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: Modifying Elements

Nicolas Brier
Nicolas Brier
20,442 Points

Checkbox, Edit and Delete buttons not functional on newly created items

Hi

Once new items are created, a click on checkbox, Edit or Delete does nothing. I can't find the reason. Any idea?

Thanks

// TODO
// Problem: Add, Delete and checkbox doesn't work on newly created items

var taskInput = document.getElementById("new-task"); // #new-task
var addButton = document.getElementsByTagName("button")[0]; // first button in the DOM
var incompleteTasksHolder = document.getElementById("incomplete-tasks");// #incomplete-tasks
var completedTasksHolder = document.getElementById("completed-tasks"); // #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 element needs modifying

    checkBox.type = "checkbox";
    editInput.type = "text";

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

    label.innerText = taskString;

    // Each element needs appending 
    listItem.appendChild(checkBox); 
    listItem.appendChild(label);    
    listItem.appendChild(editInput);    
    listItem.appendChild(editButton);   
    listItem.appendChild(deleteButton);     


    return listItem;
}

// Add a new task - similar to function addTask();
var addTask = function() {
    console.log("Add task...");

  // create a new list item with the text from #new-task
    var listItem = createNewTaskElement(taskInput.value);

    // Append listItem to incompleteTasksHolder
    incompleteTasksHolder.appendChild(listItem);
    bindTaskEvents = (listItem, taskCompleted);

    taskInput.value = "";
}

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

    var listItem = this.parentNode;

    var editInput = listItem.querySelector("input[type=text]"); //return the first one selector (querySelectorAll needs an index sinon)
    var label = listItem.querySelector("label");

    var containsClass = listItem.classList.contains("editMode");
        // if the class of the parent is .editMode
        if(containsClass) {
            // switch from editMode
            // make the label text become the input's value
            label.innerText = editInput.value;
        } else {
            // switch to editMode
            // input value becomes the label text
            editInput.value = label.innerText;
        }

        //Toggle .editMode on the parent on the list Item
        listItem.classList.toggle("editMode");

}

// Delete an existing task
var deleteTask = function() {
    console.log("Delete task...");
        // remove the parent list item form the ul
        var listItem = this.parentNode;
        var ul = listItem.parentNode;

        // remove the li (parent of button) from the ul (grandparent)
        ul.removeChild(listItem);

}

// mark a task as complete
var taskCompleted = function() {
    console.log("Completed...");
        // 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("Incomplete...");
        // Append the task list item to the #incomplete-tasks
        var listItem = this.parentNode;
        incompleteTasksHolder.appendChild(listItem);
        bindTaskEvents(listItem, taskCompleted);
}       

var bindTaskEvents = function(taskListItem, checkBoxEventHandler) {
        console.log( "bind list item event..." );
        // 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 taskCompleted to the checkbox
        checkBox.onchange = checkBoxEventHandler;
}


// Set the click handler to the Add task function
addButton.onclick = addTask; // no the call of the function (missing () but just a reference )

// loop over the incompleteTaskHolder ul list items
for (var i = 0; i < incompleteTasksHolder.children.length; i++) {
    // bind taskCompleted to the checkbox
    bindTaskEvents( incompleteTasksHolder.children[i], taskCompleted );
}


// loop over the completedTaskHolder ul list items
for (var i = 0; i < completedTasksHolder.children.length; i++) {
    // bind taskIncomplete to the checkbox
    bindTaskEvents( completedTasksHolder.children[i], taskIncomplete );
}   

3 Answers

Hi Nico, look inside your addTask function definition. You'll see a syntax error that is preventing your bindTaskEvents call from running as expected.

Nicolas Brier
Nicolas Brier
20,442 Points

Thank you bob! I found that I had a "bindTaskEvents = (listItem, taskCompleted);" instead of "bindTaskEvents(listItem, taskCompleted);" Working great now :)

Karl Taylor
Karl Taylor
4,043 Points

Had the exact same problem and could find it for ages! Thank you for this! It's quite a confusing one this but a massive lightbulb goes once it all links up!