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

checkBoxEventHandler

Question

In Chalkley's JS course, "Interactive Web Pages w/ JS," he has included a parameter called "checkBoxEventHandler" in a function called "bindTaskEvents."

I'm not sure I understand how this works. My code works as I've followed him, it's just that my understanding of this leaves room for improvement.

Pardon my repeating it, but I have included it here for your ease.

Would someone please explain it in more detail for me?

Thank you.

Supporting info

Initial definition:

var 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;
}

Sample recalling of said function:

var taskIncomplete = function () {
    console.log("Task incomplete...");
    //Append the task list item to the #incomplete-tasks
    var listItem = this.parentNode;
    incompleteTasksHolder.appendChild(listItem);
    bindTaskEvents(listItem, taskCompleted);
}
Jonathan Grieve
Jonathan Grieve
Treehouse Moderator 91,254 Points

How far are you in the course?

I'm just going through it for a second time ans I've decided simply not to worry about them until the time comes they're referenced again in the course.

It's probably just there for the programmers sake to keep it as a references for when it;s needed. I agree that could probably have been clarified though. :-)

Hi, Jonathan.

i've gone all the way to the end. i get everything else but that.

at this point, i'll assume that it's something to understand better as i progress through JS. the code work, and i get 90% of it.

Thanks for the suggestion.

Jonathan Grieve
Jonathan Grieve
Treehouse Moderator 91,254 Points

Thinking more about it then, I wonder if it's just a variable, passed into the function as a parameter than when returned simply holds and event handler for interaction with the checkbox,

Remember you're making new checkboxes, removing them from the application, which probably needs to be held as a function argument to work. I don't know enough yet to understand why that would be the case but I think it;ll be something like that.

Jonathan Grieve That sounds like a good explanation. Thanks!

3 Answers

Jonathan is right. The function name and parameter names could be anything. Obviously it is best practice to give them names that help the reader understand what the code is doing, but they are not predefined.

Somewhere else in the code (maybe later in the course) I image that this function will be called. When that function is called, it will take two arguments in between the parenthesis.

I haven't taken this course, but you should see somewhere in the code that the function is being called like so:

bindTaskEvents(param1, param2);

Where param1 and param2 will be the names of variables or values that you will pass to the bindTaskEvents function.

Hi everyone,

I'm went through this course and the answer is actually pretty simple. I'll walk you through some of the code step-by-step to make the explanation a bit easier to understand.

We know that the taskCompleted function is used to mark a task as completed. Say we check the checkbox for an item that is in the "Incomplete" list. It calls the taskCompleted function because we want to move that item to the "Completed" list. Let's look at the code in the taskCompleted function and break it down step by step (I numbered them for reference, obviously the numbers aren't in the code).

  1. var listItem = this.parentNode;
  2. completedTasksHolder.appendChild(listItem);
  3. bindTaskEvents(listItem, taskIncomplete);

One: "this" is a reference to the list item we want to mark as "Completed", so this.parentNode is a reference to the li holding that item. So we created the variable listItem which is a reference to the li holding the label, input field, edit button, delete button, etc. We want to move this entire li to the "Completed" list.

Two: We append this li to completedTasksHolder which we know is a reference to the ul holding all the items in the "Completed" list. We know completedTasksHolder is a reference to the ul holding the "Completed" tasks list because at the top of the page we have this code:

completedTasksHolder = document.getElementById("completed-tasks");

So we just moved the task from the "Incomplete" list ul to the "Completed" list ul. Pretty straightforward so far I think.

Three: Now here's where it gets a little tricky and could have been explained a bit better. We call the bindTaskEvents function using listItem and taskIncomplete as arguments. The declaration of that function looks like this:

var bindTaskEvents = function(taskListItem, checkBoxEventHandler) {...}

And we called the function like this:

bindTaskEvents(listItem, taskIncomplete);

So now the taskListItem parameter is a reference to the list item we just moved, and the checkBoxEventHandler parameter is now a reference to taskIncomplete, which itself is a reference to a function (the taskIncomplete function of course). In other words, the following code

checkBox.onchange = checkBoxEventHandler;

is actually equal to this:

checkBox.onchange = taskIncomplete;

We have made it so that when we check the checkbox of the item we have just moved to the "Completed" list, the taskIncomplete function will be called to move that item back to the "Incomplete" list.

I'll take it a little further just in case you don't quite understand yet. Now that we have moved the list item into the "Completed" list, if we were to hit the checkbox for that item again, it's going to call the taskIncomplete function that we just associated with that checkbox. The taskIncomplete function has 3 steps like above. It will get the parent li of the task, then move it to the incompleteTasksHolder ul. In other words, move that task back to the "Incomplete" list. Then bindTaskEvents is called again, this time passing listItem and taskCompleted as the arguments. Now the checkBoxEventHandler parameter is a reference to the taskCompleted function.. That task item has been moved back to the "Incomplete" list, and the code:

checkBox.onchange = checkBoxEventHandler;

is equal to:

checkBox.onchange = taskComplete;

Now clicking on the checkbox a 3rd time will call the taskComplete function again and move this item from the "Incomplete" list back to the "Complete" list a second time.

In case you're still a little confused....

The bindTaskEvents function is assigning a function to each event, i.e. pressing the delete button, pressing the edit button, or checking a checkbox. Pressing the delete button will always do the same thing, it will call the function to delete the item. Pressing the edit button will always do the same thing, it will call the edit function. However, since a checkbox appears next to an item whether it's in the "Complete" list or the "Incomplete" list, we can't always call the same function when it is checked because there are two possible functions it can all, either taskComplete or taskIncomplete. The checkBoxEventHandler parameter is used to assign either the taskComplete function or the taskIncomplete function as the function to be called when the checkbox is checked, depending on whether the task is in the "Incomplete" or the "Complete" list.

Wow, that got long. I hope everyone understands a little better now.

Your efforts at explaining this were not in vain. It is clearer and helping me to unscramble the eggs. It's a bit of a chess game looking several moves deep. I've printed off your explanation and attached it to my copy of the code which I will continue to study until it is perfectly clear. Thanks again.

I was having trouble here too because I couldn't find where checkBoxEventHandler was getting its value. What helped me: do a search in your code for bindTaskEvents so that you can see where that function is called.

What you'll find is that when the page loads your script loops through each list item in the complete and incomplete task lists and runs the functions you defined for taskCompleted and taskIncomplete depending on which list it is you're clicking.

It's a bit confusing in the video because Andrew has a way of kind of jumping back and forth in the code and calling functions before he defines them.

Hope that helps a bit.