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 trialAleks Dahlberg
19,103 PointsProblem: List item elements not being created when a list item is created.
On the click event to add a new task, the elements (inputs, label and buttons) are not being created. Note: my HTML and CSS is slightly modified compared to the workspace assets. My javascript is also slightly modified compared to the videos.
Javascript
//Problem: User interaction does not provide desired results.
//solution: add interactivity so the user can manage the todo list.
var taskInput = document.getElementById('todoInput');
var addButton = document.getElementById('addTaskButton');
var incompleteTaskHolder = document.getElementById('incompleteTasks');
var completedTaskHolder = document.getElementById('completedTasks');
/*This function creates the the list items.*/
var createListItem = function(taskString){
//list item will be the parent of the checkbox, label, text... etc
var listItem = document.createElement("li");
listItem.className = "p-t-2";
//create and modify child elements
var checkbox = document.createElement("input");
checkbox.type = "checkbox";
var label = document.createElement("label");
label.innerHTML = taskString;
var editInput = document.createElement("input");
editInput.type = "text";
editInput.className = "form-control task-form"; //apply classes
var deleteButton = document.createElement("button");
//check if innerText string is "undefined" (firefox)
if (typeof deleteButton.innerText === "undefined"){
deleteButton.innerContent = "Delete";
} else {
deleteButton.innerText = "Delete";
}
deleteButton.className = "btn btn-secondary delete"; //apply classes
var editButton = document.createElement("button");
//check if innerText string is "undefined" (firefox)
if (typeof editButton.innerText === "undefined"){
editButton.innerContent = "edit"
} else {
editButton.innerText = "edit"
}
editButton.className = "btn btn-secondary edit"; //apply classes
//append child elements to listItem parent.
checkbox.appendChild(listItem);
label.appendChild(listItem);
editInput.appendChild(listItem);
deleteButton.appendChild(listItem);
editButton.appendChild(listItem);
console.log("Task created"); //console message
return listItem; //return the listItem
}
/*This function adds the created list items from createListItem function
to the unordered list html & incompleteTaskHolder on the click event of
addButton */
var addTask = function () {
//create variable listItem and store the returned created item from createListItem
var listItem = createListItem(taskInput.value); //use the value of taskInput as the taskString
//append listItem to incompleteTaskHolder
incompleteTaskHolder.appendChild(listItem);
bindTaskEvents(listItem, taskCompleted);
console.log("Task added!"); //console message
}
//edit existing tasks
var editTask = function (){
console.log("Task in edit-mode");
}
//delete tasks
var deleteTask = function () {
//traversing:
//create a variable to store the li from the listItem's parent
var listItem = this.parentNode;
//create a variable to store the ul as listItem's parent
var ul = listItem.parentNode;
//remove the child
ul.removeChild(listItem);
console.log("task deleted!"); // console message
}
//mark tasks completed
var taskCompleted = function (){
//append the list item to completedTasks
var listItem = this.parentNode;
//add listItem to parent node (completedTaskHolder)
completedTaskHolder.appendChild(listItem);
//bind task events to the new list item.
bindTaskEvents(listItem, taskIncomplete);
console.log("task completed!"); //console message
}
//mark tasks incomplete
var taskIncomplete = function () {
//
var listItem = this.parentNode;
//add listItem to parent node (incompleteTaskHolder)
incompleteTaskHolder.appendChild(listItem);
//bind task events to the new list item.
bindTaskEvents(listItem, taskCompleted);
console.log("task incomplete!"); //console message
}
/*This function binds the list item event elements (checkboxes and buttons) to the
appropriate event handers*/
var bindTaskEvents = function (listItem, checkboxEventHandler) {
//create variables to store each element (get element by type)
var checkbox = listItem.querySelector("input[type=checkbox]");
var editButton = listItem.querySelector("button.edit");
var deleteButton = listItem.querySelector("button.delete");
//set event handlers
editButton.onclick = editTask;
deleteButton.onclick = deleteTask;
checkbox.onchange = checkboxEventHandler;
console.log("List item events bound"); //console message
}
//while i is less than then number of items in incompleteTaskHolder (ul) children (li) bind the events to the (ul) children (li) using the bindTaskEvents function
for(var i = 0; i < incompleteTaskHolder.children.length; i++){
bindTaskEvents(incompleteTaskHolder.children[i], taskCompleted);
console.log("Tasked added to incompleteTaskHolder"); //console message
}
//while i is less than then number of items in completedTaskHolder (ul) children (li) bind the events to the (ul) children (li) using the bindTaskEvents function
for(var i = 0; i < completedTaskHolder.children.length; i++){
bindTaskEvents(completedTaskHolder.children[i], taskIncomplete);
console.log("task added to completedTaskHolder"); //console message
}
//wiring
addButton.onclick = addTask; //onclick run addTask function
HTML
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.rawgit.com/twbs/bootstrap/v4-dev/dist/css/bootstrap.css">
<link rel="stylesheet" href="css/master.css" media="screen" title="no title" charset="utf-8">
</head>
<body>
<div class="container p-t-3 p-b-3">
<div class="row">
<h4 id='title3'>To do list</h4>
<!--NEW TASK HTML-->
<div class="p-t-2">
<label class="label-heading">ADD ITEM</label>
<ul>
<li class="add-task-li">
<input class="form-control task-form" id="todoInput">
<button class="btn btn-secondary" type="button" name="button" id="addTaskButton">ADD</button>
</li>
</ul>
</div>
<!--INCOMPLETE TASK HTML-->
<div class="p-t-2">
<label class="label-heading">INCOMEPLETE TASKS</label>
<ul id="incompleteTasks">
<!--not edit mode-->
<li class="p-t-1">
<input type="checkbox" class="checkbox-style"/>
<label>Test item not edit mode</label>
<input type="text"/>
<button class="btn btn-secondary edit" type="button" name="button" id="editButton">Edit</button>
<button class="btn btn-secondary delete" type="button" name="button" id="deleteButton">Delete</button>
</li>
<!--edit mode-->
<li class="edit-mode p-t-1">
<input type="checkbox" class="checkbox-style"/>
<label>Test item edit mode</label>
<input type="text" class="form-control task-form" value="Test item edit mode"/>
<button class="btn btn-secondary edit" type="button" name="button" id="editButton">Edit</button>
<button class="btn btn-secondary delete" type="button" name="button" id="deleteButton">Delete</button>
</li>
</ul>
</div>
<!--COMPLETED TASK HTML-->
<div class="p-t-2">
<label class="label-heading">COMPLETED TASKS</label>
<ul id="completedTasks">
</ul>
</div>
</div>
</div>
<script src="https://cdn.rawgit.com/twbs/bootstrap/v4-dev/dist/js/bootstrap.js"></script>
<script src="js/todoapp.js" charset="utf-8"></script>
</body>
</html>
2 Answers
Shane Oliver
19,977 PointsYou have your appendchild set the wrong way around in the createlistitem function
you are saying : checkbox.appendChild(listItem); where it should be : listItem.appendChild(checkbox)