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: Appending and Removing Elements

Michael Sims
Michael Sims
8,101 Points

Delete Button not working?

Hey there guys, everything was working up until we got up to the using the delete button task.... I've tried matching this to the video for the last half an hour, but I just don't see where mine differs, can someone give me a helping hand here?

//Problem: User interaction doesn't provide desired results.
//Solution: Add interactivity so the user can manage daily tasks.

var taskInput = document.getElementById("new-task"); //new-task
var addButton = document.getElementsByTagName("button")[0]; //first button
var incompleteTaskHolder = 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"); //text
      //button.edit
  var editButton =document.createElement("button");
      //button.delete
  var deleteButton = document.createElement("button");
      //Each elements needs modifying
      //Each item needs appending
  listItem.appendChild(checkBox);
  listItem.appendChild(label);
  listItem.appendChild(editInput);
  listItem.appendChild(editButton); 
  listItem.appendChild(deleteButton); 

  return listItem;
}
//Add a new taks
var addTask = function() {
  console.log("Add task...");
  //When the button is pressed
  //Create a new list item with the text from #new-task;
  var listItem = createNewTaskElement("Some New Task");

  //Append List item ti incompleteTasksHolder
  incompleteTaskHolder.appendChild(listItem);
}

//Edit an existing task
var editTask = function(){
  console.log("Edit task...");
  //When the Edit button is pressed
    //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...");
  var listItem = this.parentNode;
  var ul = listItem.parentNode;

  //Remove the parent list item from the ul 
  ul.removeChild(listItem); 
}
//Mark a task as complete
var taskCompleted = function() {
  console.log("Task complete...");
    //Apend the task list itme 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 the task list item to the #incomplete-tasks
  var listItem = this.parentNode;
  incompleteTaskHolder.appendChild(listItem);
  bindTaskEvents(listItem, taskCompleted);
}

var bindTaskEvents = function(taskListItem, checkBoxEventHandler) {
  console.log("Bind list item events");
      //select listItems' 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 delete button
  deleteButton.onclick = editTask;
    //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 < incompleteTaskHolder.children.length; i++){
    //bind events to list item's children (taskCompleted)
  bindTaskEvents(incompleteTaskHolder.children[i], taskCompleted);
}

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

6 Answers

Hey Michael,

In your bindTaskEvents() function, you are setting the deleteButton.onclick to be editTask instead of deleteTask.

Michael Sims
Michael Sims
8,101 Points

Smacks forehead........ Thanks Marcus, that was it!

Hahaha don't you love it when it's just something simple like that and you go "D'oh!" XD

Michael Sims
Michael Sims
8,101 Points

Love it??? not sure about that one Marcus... lololol

Hahaha :D Good luck to ya, man! I'm sure I'll see ya around on here

Michael Sims
Michael Sims
8,101 Points

Hey Marcus, can you give me your input on this one? Trying to get the add task function to work..... I think I'm somewhat just all around lost on this lesson to be honest, having a hard time even retaining a lot of this info.... any suggestions on progressive learning?

//Problem: User interaction doesn't provide desired results.
//Solution: Add interactivity so the user can manage daily tasks.

var taskInput = document.getElementById("new-task"); //new-task
var addButton = document.getElementsByTagName("button")[0]; //first button
var incompleteTaskHolder = 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"); //text
      //button.edit
  var editButton =document.createElement("button");
      //button.delete
  var deleteButton = document.createElement("button");
      //Each elements needs modifying
  checkBox.type = "checkbox";
  editInput.type = "text";

  editButton.innerHTML = "Edit";
  editButton.className = "edit";
  deleteButton.innerText="Delete";
  deleteButton.className = "delete";


  label.innerText = taskString
      //Each item needs appending
  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(taskInput.value);

  //Append List item ti incompleteTasksHolder
  incompleteTaskHolder.appendChild(listItem);
  bindTaskEvents(listItem, taskCompleted);
}

//Edit an existing task
var editTask = function(){
  console.log("Edit task...");
  //When the Edit button is pressed
    //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...");
  var listItem = this.parentNode;
  var ul = listItem.parentNode;

  //Remove the parent list item from the ul 
  ul.removeChild(listItem); 
}
//Mark a task as complete
var taskCompleted = function() {
  console.log("Task complete...");
    //Apend the task list itme 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 the task list item to the #incomplete-tasks
  var listItem = this.parentNode;
  incompleteTaskHolder.appendChild(listItem);
  bindTaskEvents(listItem, taskCompleted);
}

var bindTaskEvents = function(taskListItem, checkBoxEventHandler) {
  console.log("Bind list item events");
      //select listItems' 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 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 < incompleteTaskHolder.children.length; i++){
    //bind events to list item's children (taskCompleted)
  bindTaskEvents(incompleteTaskHolder.children[i], taskCompleted);
}

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

I copied your code and pasted it into a js file for my version of this program and the add task is working as it should so far. It's getting the right text into the spot it belongs. And the delete programming is working fine. Of course edit isn't working yet because it isn't wired up.

Personally, the best way I've found to learn is by messing around with the code and looking up every single command that I wasn't 100% sure of what it did. If you don't know exactly what a command does, look it up! The Mozilla Developer Network is a fantastic place to get information on tons of things web related especially JavaScript.

Also, I can't tell you how much time I've spent in the console area of Chrome. It has to be hundreds of hours lol. I used to use "console.log()" for everything (I still do for some debugging). You can literally log out just about anything to your console and see what it is. It's how I took that basic to-do list app and created a persistent to-do list app based on that original one: http://www.marcusparsons.com/projects/todolist

You've just got to play, play, and play some more with your code. It can be frustrating at times, but when you figure a solution out to your problem, it feels goooood!

Btw, if you can't add anything, let me see a copy of your workspace by posting a snapshot man.

Michael Sims
Michael Sims
8,101 Points

Awesome advice, thanks for that Marcus. I actually jsut finished the edit video and added that coding, and that's not working either... has to be something earlier in the coding knocking everything off... here's what's happening specifically: 1) When I "add" an item, no matter what I type, it comes up as "edit" in the list... 2) When I click "edit", nothing happens at all.....

By the way.. your list looks super cool!

Michael Sims
Michael Sims
8,101 Points

Oops here's the coding as it is right now

//Problem: User interaction doesn't provide desired results.
//Solution: Add interactivity so the user can manage daily tasks.

var taskInput = document.getElementById("new-task"); //new-task
var addButton = document.getElementsByTagName("button")[0]; //first button
var incompleteTaskHolder = 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"); //text
      //button.edit
  var editButton =document.createElement("button");
      //button.delete
  var deleteButton = document.createElement("button");
      //Each elements needs modifying
  checkBox.type = "checkbox";
  editInput.type = "text";

  editButton.innerHTML = "Edit";
  editButton.className = "edit";
  deleteButton.innerText="Delete";
  deleteButton.className = "delete";


  label.innerText = taskString
      //Each item needs appending
  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(taskInput.value);

  //Append List item ti incompleteTasksHolder
  incompleteTaskHolder.appendChild(listItem);
  bindTaskEvents(listItem, taskCompleted);
}

//Edit an existing task
var editTask = function(){
  console.log("Edit task...");

  var listItem = this.parentNode;

  var editInput = listItem.querySelector("input(type=text)");
  var label = listItem.querySelector("label");

  var containsClass = listItem.classList.contains("editMode");
  //if the class of the parent is .editMode
  if(containsClass){
    //Switch from .editMode
    //label text become the input's value
    label.innerText = editInput.value;
  } else {
    //Switch to .editMode
    //input value becomes the label's text
    editInput.value = label.innerText;
}
  //Toggle .editMode on the list item
  listItem.classList.toggle("editMode");
}
//Delete an existing task
var deleteTask = function(){
  console.log("Delete task...");
  var listItem = this.parentNode;
  var ul = listItem.parentNode;

  //Remove the parent list item from the ul 
  ul.removeChild(listItem); 
}
//Mark a task as complete
var taskCompleted = function() {
  console.log("Task complete...");
    //Apend the task list itme 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 the task list item to the #incomplete-tasks
  var listItem = this.parentNode;
  incompleteTaskHolder.appendChild(listItem);
  bindTaskEvents(listItem, taskCompleted);
}

var bindTaskEvents = function(taskListItem, checkBoxEventHandler) {
  console.log("Bind list item events");
      //select listItems' 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 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 < incompleteTaskHolder.children.length; i++){
    //bind events to list item's children (taskCompleted)
  bindTaskEvents(incompleteTaskHolder.children[i], taskCompleted);
}

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

It looks like there are a couple issues in that editTask function. Before you get to the if (containsClass) statement, you should go ahead and toggle the class "editMode" on the list item because you are then going to use that information to update the list item appropriately. And then within that if (containsClass) and else block of code, you have the roles reversed. If it has the class "editMode" that means you update the input's value to be the label's text and then in the else block, you update the label's text to be the input's value.

Here is my editTask function (it also switches between the words "Edit" and "Save" which is a little later on):

//Edit an existing task
var editTask = function() {
  var listItem = this.parentNode;
  var editInput = listItem.querySelector("input[type=text]");
  var label = listItem.querySelector('label');
  var editButton = listItem.querySelector("button.edit");
        //Toggle .editMode on the list item
  listItem.classList.toggle("editMode");
  var containsClass = listItem.classList.contains("editMode");
    //If the class of the parent is editMode
  if (containsClass) {
      //input value becomes the label's text
    editInput.value = label.textContent;
      //if we're in edit mode, change text to Save
    editButton.innerText = "Save";
  } 
  else {
    //Switch from .editMode
      //label text = input's value
    label.textContent = editInput.value;
   //If we're not in edit mode, change text to Edit
    editButton.innerText = "Edit";
  }
}
Michael Sims
Michael Sims
8,101 Points

Thanks Marcus... I'll have to go through your coding with a fresh mind in the morning and see what all I'm doing wrong... which is probably about everything lol

Sure thing man. If you have to just ignore the editButton variable and anything dealing with that for right now.