Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

JavaScript

Carole Nissen
Carole Nissen
5,655 Points

Cannot set property 'onclick' of null

As a newbie to the forum, I'm hoping someone can help me?! I'm working through Interactive Web Pages with JavaScript, and am trying to get the 'add task' function to clear the box after adding the task. As soon as I try to test it I get the error message in the console "uncaught TypeError: Cannot set property 'onclick' of null" with the ref "app.js:131"

I've followed everything Andrew says (I think!) and searched the forum for others with this problem, but none of the answers seem to apply to my code. Can anyone help - I'm totally stuck and frustratingly it's the last video in the section! Thank you in advance and here's my code...

//Problem: User interactivity 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 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"); //checkbox
    //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
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");
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...");
        //Remove the parent list item from the ul
    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...");
        //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 incompleted...");
        //Append the task list item to the #incompleted-tasks
    var listItem = this.parentNode;
    incompleteTasksholder.appendChild(listItem);
    bindTaskEvents(listItem, taskCompleted);
}

var bindTaskEvents = function(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 the editTask to edit button
    editButton.onclick = editTask;

        //bind the 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;

//var ajaxRequest = function() {
    //console.log("AJAX request");
//}
//addButton.onclick = ajaxRequest;

//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);
}



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

2 Answers

Hi Carole,

Are you still working on this? There is a typo on line 33; the class name for the delete button never gets set because there is a dash instead of an equals sign. Line 33 should look like this:

deleteButton.className = "delete";

That should get rid of the error message and allow the input box to clear.

Carole Nissen
Carole Nissen
5,655 Points

OMG Thank you Erika!!!! That's not the first time I've made that typo, but I didn't catch that one and it was driving me crazy!! I've finished the course but had just left that bit of code not working so it's brilliant to finally be able to see how it does actually work! Thank you again for taking the time...

You're welcome! I also have typos that drive me crazy. They make me think I don't understand my code, then finally...oh there's a comma in the wrong place.

Carole Nissen
Carole Nissen
5,655 Points

I knowwwww!!! Glad it's not just me - and great to hear from another female coder! :-)