Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript Interactive Web Pages with JavaScript Traversing and Manipulating the DOM with JavaScript Perform: Traversing Elements with children

Gabriel Ward
Gabriel Ward
20,222 Points

bindTaskEvents

There's one thing i'm not quite grasping in this video, and that's some of the code in the curly braces of the 'for' loops.

{bindTaskEvents(incompleteTasksHolder.children[i], taskCompleted);}

{bindTaskEvents(completedTasksHolder.children[i], taskIncomplete);}

Where do the arguments, or parameters, I'm not quite sure come from?

Because the code for bindTasksEvents is

var bindTaskEvents = function(taskListItem, checkBoxEventHandler).

I'm not quite making the connection between

(taskListItem, checkBoxEventHandler). and

(completedTasksHolder.children[i], taskIncomplete);

It seems a little arbitrary, I'm generally following along with everything, but can't quite explain this step clearly to myself.

Thanks to anyone in advance!

5 Answers

Hey Gabriel!

I think the easiest way to think of 'bindTaskEvents' is as a function that allows us to target an element we pass in to parameter 1 (taskListItem) with a function in parameter2 (checkBoxEventHandler) that applies a certain action.

Here's an example from the video I parsed out for you...

//*incompleteTasksHolder* is the variable we use to store the unordered list with the ID #incomplete-tasks
var incompleteTasksHolder = document.getElementById("incomplete-tasks");

//*taskCompleted* is the function we use to mark a task as completed and move it over to the unordered list with the ID #completed-tasks
var taskCompleted = function() {
    console.log("Task completed...");
};

//*bindTaskEvents* is the function that allows us to attach *taskCompleted* to the children of *incompleteTasksHolder*
//On a high-level, we are giving the user the ability to take an item from his or her "To Do List" and mark it as "Completed".
var bindTaskEvents = function(incompleteTasksHolder.children[i], taskCompleted) {
    console.log("Bind list item events...");
};

I hope this helps a little!

-Chris

Gabriel Ward
Gabriel Ward
20,222 Points

Wow thanks Chris,

I've posted a reply in a comment at the bottom of the page, that outlines my interpretation of how I'm understanding this now.

I really appreciate your help. This stuff is such a step up from the beginner/foundation stuff. But I feel like I'm slowly getting my head around it. Did you find it tough at first to understand?

Best,

Gabe

Chris,

the explanation was was simple and easy to understand. I was confused why they are passing the parameters taskCompleted and taskIncompleted for the list items. Your explanation was clear and useful.

Aishu

Robert Farese
Robert Farese
7,944 Points

Hi Gabriel! I feel your pain! This one confused me the first time around as well. I had to go through the entire course a 2nd time to grasp what he was doing. I may over explain and touch on things you already know but just stick with me and I think I'll answer your question somewhere in this response...

So we have the following function:

var bindTaskEvents = function(taskListItem, checkBoxEventHandler){}

Then we are calling the function twice from inside the 2 different for loops:

bindTaskEvents(incompleteTasksHolder.children[i], taskCompleted); bindTaskEvents(completedTasksHolder.children[i], taskIncomplete);.

Remember that when you are creating a function the code inside the ( ) are the parameters and when you are calling the function the code inside the ( ) are the arguments. The arguments are replacing the parameters. So they are taking the value of the arguments and passing those values into the function. The value inside "incompleteTasksHolder.children[i]" will be inserted where ever "taskListItem" is used in the bindTaskEvents function. Similarly, the value stored inside "taskCompleted" will be inserted where ever "checkBoxEventHandler" is used in the bindTaskEvents function.

So now its just a question of what values are inside of the "incompleteTaskHolder.children[i]" and "taskCompleted" (and "completedTaskHolder.children[i]" and "taskIncomplete").

"incompleteTaskHolder.children[i]" is one of the <li> tags inside of the <ul id="incomplete-tasks"> tag. In other words, the <li> tag is a child of the <ul> tag. Remember that "incompleteTaskHolder" stored the <ul> tag inside it. If you scroll to the top of the app.js file, you'll see the variable incompleteTasksHolder is declared:

var incompleteTaskHolder = document.getElementById("incomplete-tasks");

The variable incompleteTaskHolder is getting the <ul> tag with the id="incomplete-tasks". So to grab one of the <li> tags, we use incompleteTaskHolder.children. But there are 2 <li> tags inside of the <ul id="incomplete-tasks"> tag...so how do we know which one is being passed as an argument to the bindTaskEvents function? That's what the for loop is doing. The first time it cycles through, it'll grab the 1st <li> tag, the 2nd time it cycles through it'll grab the 2nd <li> tag, but the 3rd time it won't grab anything because there are only 2 <li> tags.

Are you familiar with the different parameters inside the for loop? If you're not then I'd look that up or watch Jim's course "JavaScript Foundations" and then come back to this course.

If you follow the same kind of thinking process with the "taskCompleted" then you should be able to extrapolate the value stored inside of that argument and how it's value is being passed into the bindTaskEvents function and replacing the checkBoxEventHandler parameter.

Remember that the entire point to all of this is too connect the elements with the functions or as Andrew puts it in the video...its to creating the "wiring".

I hope that helped...?

Happy Holiday Season!

Bobby

Gabriel Ward
Gabriel Ward
20,222 Points

Thanks for your explanations Robert and Christopher!

Here's my interpretation:

In the bindTaskEvents function, taskListItem is, and can be arbitrary because we are only defining the function, we're not calling it.

ar bindTaskEvents = function(taskListItem, checkBoxEventHandler) {
    console.log('Bind list item events');
    //select taskListItem's children
    var checkBox = taskListItem.querySelector('input[type=checkBox]');
    var editButton = taskListItem.querySelector('button.edit');
    var deleteButton = taskListItem.querySelector('button.delete');
    //bind editTask to edit button
    editButton.onclick = editTask;
    //bind deleteTask to delete button
    deleteButton.onclick = deleteTask;
    //bind checkBoxEventHandler to checkbox
    checkBox.onchange = checkBoxEventHandler;
}

Then in the for loops, we're now calling the bindTaskEvents function, so taskListItem is now defined as incompleteTasksHolder.children[i], in the lines of code

for(var i = 0; i < incompleteTasksHolder.children.length; i++) {
        //bind events to list item's children (taskCompleted)
        or(var i = 0; i < incompleteTasksHolder.children.length; i++) {
        //bind events to list item's children (taskCompleted)
        bindTaskEvents(incompleteTasksHolder.children[i], taskCompleted);
}

and completedTasksHolder.children[i], in the line of code

for(var i = 0; i < completedTasksHolder.children.length; i++) {
        //bind events to list item's children (taskIncomplete)
        bindTaskEvents(completedTasksHolder.children[i], taskIncomplete);
}

Is this interpretation correct? Am I kind of getting it?

Thank you so much for your help.

Robert Farese
Robert Farese
7,944 Points

Hey Gabe, sorry about the late reply...crazy holidays!

But yes Chris is right and you've got it. With a bunch of different names flying around, it can be hard to keep track of how the different programs are tied together.

It helps me to think of functions and calling them like parking spaces and cars. When you define the function and create the parameters inside the ( ), you're creating the parking space. When call the function and pass in the arguments inside the ( ), you saying what "car" you want parked in the parking space. In other words, the parameter is an empty parking space and you can park whatever car you want to in it (so to speak...).

You can also think of the parameters as an empty variable that you need to provide a value to at a later date...whatever works best for you.

Gabe & Chris - Happy Holidays to you both!

Bobby

Gabe,

Looks like you've got it! And yes, all of this is tough to understand as far as I'm concerned - if it wasn't, everyone would be a programmer!

Don't be afraid to watch videos multiple times until themes really sink in, use complementary resources like MDN, CodeAcademy and various textbooks, and ask questions on the forum!

Most importantly, after you learn certain techniques, practice as much as possible to make them second nature.

Best of luck,

-C

Gabriel Ward
Gabriel Ward
20,222 Points

Great thanks Chris. Just one more further question, where do you practice code? On your own projects? On sites such as jsfiddle? A mix of both?

Gabe,

Mostly my own projects, and sites like JSFiddle and CodePen are great. My preferred text editor is Brackets because it's geared toward Front-End, but Sublime Text is great as well.

-C