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 trialEric Ridolfi
19,417 Pointsthis.parentNode
First what is the value of listItem in the taskIncomplete function and the taskCompleted function?
Second how does this.parentNode give it that value? I guess I don't understand how this.parentNode works.
// Problem: User interaction does not provide desired results.
// Solution: Add interactivity so the user can manage daily tasks.
var taskInput = document.getElementById("new-task");
var addButton = document.getElementById("addButton");
var incompleteTasksHolder = document.getElementById("incomplete-tasks");
var completedTasksHolder = document.getElementById("completed-tasks");
// New task list item
var createNewTaskElement = function(taskString) {
// Create list item
var listItem = document.createElement("li");
// input (checkbox)
var checkBox = document.createElement("input"); // checkbox
// label
var label = document.createElement("label");
// input (text)
var editInput = document.createElement("input"); // edit input text
// button.edit
var editButton = document.createElement("button") // button.edit
// button.delete
var deleteButton = document.createElement("button"); // button.delete
// each elements need to be modified
// each element needs appended
listItem.appendChild(checkBox);
listItem.appendChild(label);
listItem.appendChild(editInput);
listItem.appendChild(editButton);
listItem.appendChild(deleteButton);
return listItem;
}
// Add a new task
var addTask = function() {
console.log("add task");
// Create a new list item with the text from #new-task:
var listItem = createNewTaskElement("Some new task");
// Append listItem to incompleteTaskHolder
incompleteTasksHolder.appendChild(listItem);
bindTaskEvents(listItem, taskCompleted);
}
// Edit and existing task
var editTask = function() {
console.log("edit task");
// When the edit button is pressed
// if the class of the parent is .editMode
// switch from editMode
// label text become the input's value
// else
// switch to editMode
// input value becomes the label's text
// toggle .editMode on the parent
}
// Delete an existing task
var deleteTask = function() {
console.log("delete task");
// When the delete button is pressed
// remove the parent list item from the ul
}
// Mark a task as complete
var taskCompleted = function() {
console.log("task complete");
// append the task list item to the completed-tasks
var listItem = this.parentNode;
completedTasksHolder.appendChild(listItem);
bindTaskEvents(listItem, taskIncomplete);
}
// Mark a task as incomplete
var taskIncomplete = function() {
console.log("task incomplete");
// append to the incomplete-tasks
var listItem = this.parentNode;
incompleteTasksHolder.appendChild(listItem);
bindTaskEvents(listItem, taskCompleted);
}
var bindTaskEvents = function(taskListItem, checkBoxEventHandler) {
console.log("bind events");
// select it'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 the deleteButton
deleteButton.onclick = deleteTask;
// bind checkBoxEventHandler to checkbox
checkBox.onchange = checkBoxEventHandler;
}
// Set the click handler to the addTask function
addButton.onclick = addTask;
// cycle over incompleteTaskHolder 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);
}
//cycle over completeTaskHolder ul list items
for (var i = 0; i < completedTasksHolder.children.length; i++) {
// bind events to list item's children (taskCompleted)
bindTaskEvents(completedTasksHolder.children[i], taskIncomplete);
}
1 Answer
Sean T. Unwin
28,690 PointsFirst what is the value of listItem in the taskIncomplete function and the taskCompleted function?
This is a <li>
inside <ul id="incomplete-tasks">
or <ul id="completed-tasks">
of index.html
that has had it's checkbox clicked.
Second how does this.parentNode give it that value? I guess I don't understand how this.parentNode works.
When either of these functions is called it will be a checkbox that is calling it, so the current node is that checkbox. That checkbox is inside of a list item (<li>
). That list item is the parentNode.
Each tag in an HTML document is a DOM node, so the parentNode
is the parent of the current node. In other words the tag that the currently selected tag is encased in.
I hope that helps to clarify a little. :)
Eric Ridolfi
19,417 PointsEric Ridolfi
19,417 PointsDoes javascript need to know it is the checkbox calling it and if it does, where in the code are we using javascript to specify it is a checkbox calling either function?
Sean T. Unwin
28,690 PointsSean T. Unwin
28,690 PointsThis is defined in the function
bindTaskEvents
withWhere
checkBoxEventHandler
is the second argument of the function. This value will be eitherTasksCompleted
orIncompleteTasks
function.Eric Ridolfi
19,417 PointsEric Ridolfi
19,417 PointsLooking at the taskCompleted function, wouldn't the listItem variable be looking for the value before the bindTaskEvents function is executed?
Sean T. Unwin
28,690 PointsSean T. Unwin
28,690 PointstaskCompleted
is already bound to the onchange event of all the checkboxes in the<li>
's of the<ul id="incompleted-tasks">
, so JavaScript already knows that the checkbox is the selected node. As a result thelistItem
variable is defined with the parent of the checkbox, which is the<li>
that the checkbox is in.When
bindTaskEvents
is called at the end oftaskCompleted
it is re-defining the binding of the onchange event to the checkbox to point to the opposite -- fromtaskCompleted
toIncompleteTask
.The purpose of this, eventually, will be to move the
<li>
from<ul id="incompleted-tasks">
to<ul id="completed-tasks">
and when that move is made the checkbox needs to be set to enable moving the<li>
back to<ul id="incompleted-tasks">
.Eric Ridolfi
19,417 PointsEric Ridolfi
19,417 PointsSo the global variables and the two for loops are the only code that's ran when the page loads, everything else is ran based off of some kind of event?
The two for loops bind taskCompleted and taskIncompleted to the checkboxes?
Sean T. Unwin
28,690 PointsSean T. Unwin
28,690 PointsCorrect
Correct, as well as setting which function is called when each of the buttons is clicked, as defined in
bindTaskEvents
.Eric Ridolfi
19,417 PointsEric Ridolfi
19,417 PointsAh, thank you very much! This seems to make more sense now.
Thanks for taking the time to respond!