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 trialJose Linares
5,062 PointsWhen the for loop runs ???
I'm having a hard time to understand this for loop. I know that when the page loads it runs, but does it run again when I click on a checkbox ???, and If it does not, how are the functions taskCompleted() and taskIncomplete() called ??? (the for loops are in the end)
var taskInput = document.getElementById('new-task'); //new task
var addButton = document.getElementsByTagName('button')[0]; //first button
var incompleteTasksHolder = document.getElementById('incomplete-tasks'); //incomplete tasks
var completedTasksHolder = document.getElementById('completed-tasks'); //completed tasks
//new task list item
function createNewTaskElement(taskString){
//create list items
var listItem = document.createElement("li");
var checkbox = document.createElement("input");
var label = document.createElement("label");
var editInput = document.createElement("input");
var editButton = document.createElement("button");
var deleteButton = document.createElement("button");
//appending list items
listItem.appendChild(checkbox);
listItem.appendChild(label);
listItem.appendChild(editInput);
listItem.appendChild(editButton);
listItem.appendChild(deleteButton);
return listItem;
}
//add a new task
function addTask(){
console.log("Add task....");
//create a new list item with the text from #new-task
var listItem = createNewTaskElement("some new task");
//append listItem to incompleteTasksHolder
incompleteTasksHolder.appendChild(listItem);
bindTaskEvents(listItem, taskCompleted);
}
//edit an existing task
function editTask(){
console.log("Edit task....");
}
//delete an existing task
function deleteTask(){
console.log("Delete task....");
}
//mark task as completed
function taskCompleted(){
console.log("Complete task....");
//append the list item to the #completed-tasks
completedTasksHolder.appendChild(this.parentNode); //this.parentNode is the listItem (this = checkbox)
bindTaskEvents(this.parentNode, taskIncomplete); //this.parentNode is the listItem (this = checkbox)
}
//mark task as incomplete
function taskIncomplete(){
console.log("Task incomplete....");
//append the list item to the #incomplete-tasks
incompleteTasksHolder.appendChild(this.parentNode); //this.parentNode is the listItem (this = checkbox)
bindTaskEvents(this.parentNode, taskCompleted); //this.parentNode is the listItem (this = checkbox)
}
function bindTaskEvents(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;
}
//set the click handler to the addTask function
addButton.onclick = addTask;
//cycle over incompleteTasksHolder ul list items
for(var i = 0; i <incompleteTasksHolder.children.length; i++){
//bind events to list item's children (taskCompleted)
bindTaskEvents(incompleteTasksHolder.children[i], taskCompleted);
console.log("incomplete running");
}
//cycle over incompleteTasksHolder ul list items
for(var i = 0; i <completedTasksHolder.children.length; i++){
//bind events to list item's children (taskIncomplete)
bindTaskEvents(completedTasksHolder.children[i], taskIncomplete);
console.log("completed running");
}
2 Answers
Samuel Webb
25,370 PointsSo this is all based on which ID a task list has (#incomplete-task or #completed-task). When the loops run, they assign either the taskCompleted
function or taskIncomplete
function to the onclick property of any list item contained in whichever task list was passed in. That's why you have 2 loops. Now that those functions have been assigned to the onclick properties, the proper one can fire off when you either check it off - taskCompleted()
or uncheck it - taskIncomplete()
. The loop doesn't actually invoke those 2 functions, it just assigns them to onclick properties. That's why the don't have parenthesis after them when you pass them into the bindTaskEvents
function.
Hopefully I didn't make that even more confusing.
Samuel Webb
25,370 PointsNo, the loops only run once.
Unless called, functions aren't run when the JS file loads. They're just stored in memory so that they can be called at another time. So when you click the button, it fires off the addTask()
function. The only section of code that runs is whatever is between { }. It doesn't run through the rest of the file again.
Jose Linares
5,062 PointsYeah but that's only if I click on the addButton, but when I clicked on a checkbox somehow it fires the functions taskIncomplete() or taskCompleted() ??? Do you see in the code why this happens ??? I know if you are not watching the video is really hard.
Jose Linares
5,062 PointsJose Linares
5,062 PointsOhhh, now that makes sense. That was perfect man. Thank you so much.
Samuel Webb
25,370 PointsSamuel Webb
25,370 PointsNo problem, glad to help.