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 Flood
3,920 PointsTasks no longer shift from complete to incomplete and delete only works for tasks that were pre-created.
Basically, when new tasks are created they are appended and look alright. Tasks are no longer able to move from completed to incomplete or vice versa, they have become static but only after this lesson. Here is my code.. any help would be appreciated.
var taskInput= document.getElementById('new-task'); //#newtask
var addButton = document.getElementsByTagName('button')[0];//first button
var incompleteTaskHolder = document.getElementById('incomplete-tasks'); //incomplete-tasks
var completedTasksHolder= document.getElementById('completed-tasks'); //completed-tasks
//new task lisk item
var createNewTaskElement = function(taskString){
var listItem = document.createElement("li");
var checkBox = document.createElement("input"); //checkbox type
var label = document.createElement("label");
var editInput = document.createElement("input"); //edit label
var editButton = document.createElement("button");
var deleteButton = document.createElement("button");
//each element needs to be modified
checkBox.type = "checkbox";
editInput.type = "text";
editButton.innerText = "Edit";
editButton.className = "edit";
deleteButton.innerText = "Delete";
deleteButton.className = "delete";
label.innerText = taskString;
listItem.appendChild(checkBox);
listItem.appendChild(label);
listItem.appendChild(editInput);
listItem.appendChild(editButton);
listItem.appendChild(deleteButton);
return listItem;
}
var addTask = function(){
console.log("added task");
var listItem = createNewTaskElement(taskInput.value);
//append listItem to incompleteTaskHolder
incompleteTaskHolder.appendChild(listItem);
bindTaskEvents(listItem, taskCompleted);
}
var editTask = function(){
console.log("edited task");
var listItem = this.parentNode;
var editInput = listItem.querySelector("input[type=text]");
var label = listItem.querySelector("label");
var containsClass = listItem.classList.contains("editMode");
if(containsClass){
label.innerText = editInput.value;
}else{
editInput.value = label.innerText;
};
//toggle edit mode on <li>
listItem.classList.toggle("editMode");
}
var deleteTask = function(){
console.log("deleted task");
//remove parent list item from <ul>
var listItem = this.parentNode;
//the <ul> from the <li> already selected in listeItem
var ul = listItem.parentNode;
//we want to remove the <li> from <ul>
ul.removeChild(listItem);
}
var taskCompleted = function(){
//append to #completed-tasks
var listItem = this.parentNode;//this is the <li> element b/c we are on the checkbox itself
completedTasksHolder.appendChild(listItem);//appending to under <li>
bindTaskEvents(listItem, taskIncomplete);
console.log("completed task");
}
var taskIncomplete = function(){
var listItem = this.parentNode;
incompleteTaskHolder.appendChild(listItem);
bindTaskEvents(listItem, taskCompleted);
console.log("incomplete task");
}
//STAY DRY
//cycle over list items in ul
//select list items' children
//bind editTask to edit button
//bind deleteTask to delete button
//bind completed or incomplete to task box
var bindTaskEvents = function(taskListItem, checkBoxEventHandler){
console.log('bind item events');
var checkBox = taskListItem.querySelector('input [type="checkbox"]');
var editButton = taskListItem.querySelector("button.edit");
var deleteButton = taskListItem.querySelector("button.delete");
editButton.onclick = editTask;
deleteButton.onclick = deleteTask;
checkBox.onchange = checkBoxEventHandler;
}
//set click handler to addTask function - does not autocall but links them
addButton.onclick = addTask;
//cycle over the completed holder ul list items
//bind events to task items children (taskCompleted)
for(var i =0; i < incompleteTaskHolder.children.length; i++){
bindTaskEvents(incompleteTaskHolder.children[i], taskCompleted);
}
//cycle over the completed holder ul list items
//bind events to task items children (taskIncomplete)
for(var i =0; i < incompleteTaskHolder.children.length; i++){
bindTaskEvents(completedTasksHolder.children[i], taskIncomplete);
}
2 Answers
M Fen
9,858 PointsInside of the addTask function, use
bindTaskEvents(listItem, taskCompleted);
this makes sure you checkbox and buttons are not binding with the event handlers.
it should look like this:
//add new task
var addTask = function() {
//when button is pressed
//create a new list item with text from new task
var listItem = createNewTaskElement(taskInput.value);
//append listItem to incompleteTasksHolder
incompleteTasksHolder.appendChild(listItem);
bindTaskEvents(listItem, taskCompleted);
}
Andrei Punei
14,051 PointsThank you I had the same problem and I stood a bit just to figure it out, I much appreciate the solution you've given.
Rick Klaras
20,183 PointsRick Klaras
20,183 PointsThanks for that!