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 trialJonas Troyer
10,912 PointsAdding button that toggles in between save to save an edited item, and edit to edit a saved item.
I'm not sure how to set this up, this is what I have so far.
//Problem: User interaction doesn't provide user interaction desired.
//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-task
var completeTasksHolder = document.getElementById("completed-tasks"); //completed-tasks
//Each element needs modifying
//New Task List Item
var createNewTaskElement = function(taskString){
//Create List item
var listItem = document.createElement("li");
//input checkbox
var checkBox = document.createElement("input");
//label
var label = document.createElement("label");
//input (text)
var editInput = document.createElement("input");
//button.edit
var editButton = document.createElement("button");
//button.delete
var deleteButton = document.createElement("button");
//Each element, needs to be 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 appendeding
listItem.appendChild(checkBox);
listItem.appendChild(label);
listItem.appendChild(editInput);
listItem.appendChild(editButton);
listItem.appendChild(deleteButton);
return listItem;
}
//Add a new task
var addTask = function() {
//When button is pressed
//Create new list item with the text from the new task
//If addTask is empty string then break out of loop
if(taskInput.value === "") {
} else {
console.log("Add task...");
//Else run addTask as normal
var listItem = createNewTaskElement(taskInput.value);
//append listItem to incompleteTaskHolders
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(containsClass) {
//if the class of the parent has the class edit mode
//Switch from .editMode
//Label text become the input
label.innerText = editInput.value;
} else {
//Switch to editMode
//Input value becomes the labels text
editInput.value = label.innerText
}
//toggle .editMode on the parent
//toggle .editMode on the list item
listItem.classList.toggle("editMode");
}
var saveButton = function() {
if(editButton.innertext === "Edit" && editButton.onlick){
editButton.innerText = "Save";
editButton.className = "save";
} else {
editButton.innerText = "Edit";
editButton.className = "edit";
}
};
//Delete an existing task
var deleteTask = function () {
console.log("Delete Task...");
//When the delete button is pressed
//Remove the parent list item
var listItem = this.parentNode;
var ul = listItem.parentNode;
ul.removeChild(listItem);
}
//Mark a task as complete
var taskCompleted = function() {
console.log("Task complete");
//When the checkbox is checked
var listItem = this.parentNode;
completeTasksHolder.appendChild(listItem);
bindTaskEvents(listItem, taskIncomplete);
//append the task list item
}
//Mark a task as incomplete
var taskIncomplete = function() {
console.log("Task incomplete");
//When the checkbox is unchecked append this to imcomplete tasks
var listItem = this.parentNode;
incompleteTasksHolder.appendChild(listItem);
bindTaskEvents(listItem, taskCompleted);
}
var bindTaskEvents = function(taskListItem, checkBoxEventHandler) {
console.log("Bind Events to an Item");
//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;
}
var ajaxRequest = function() {
console.log("AJAX request");
}
//Set the click handler to the addTask function
addButton.addEventListener("click", addTask);
addButton.addEventListener("click", ajaxRequest);
editButton.addEventListener("click", saveButton);
//cycle over incompleteTaskHolder ul list items
for(var i=0; i<incompleteTasksHolder.children.length; i++) {
//for each list item
//bind events to list item's children
bindTaskEvents(incompleteTasksHolder.children[i], taskCompleted);
}
//cycle over completeTaskHolder ul list items
for(var i=0; i<completeTasksHolder.children.length; i++) {
//for each list item
//bind events to list item's children
bindTaskEvents(completeTasksHolder.children[i], taskIncomplete);
}
What I put in here specifically trying to change the value of the edit buttons text was this chunk of code.
var saveButton = function() {
if(editButton.innertext === "Edit" && editButton.onlick){
editButton.innerText = "Save";
editButton.className = "save";
} else {
editButton.innerText = "Edit";
editButton.className = "edit";
}
};
And this...
editButton.addEventListener("click", saveButton);
it's reporting that editButton is undefined.
1 Answer
Marcus Parsons
15,719 PointsHey Jonas, here's what I did to switch between "Edit" and "Save". I think you're overthinking the problem just a bit too much :P You should get rid of that function you created "saveButton" because you don't need it:
//Edit an existing task
var editTask = function() {
var listItem = this.parentNode;
var editInput = listItem.querySelector("input[type=text]");
var label = listItem.querySelector('label');
//Toggle .editMode on the list item
listItem.classList.toggle("editMode");
var containsClass = listItem.classList.contains("editMode");
var editButton = listItem.querySelector("button.edit");
//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";
}
}
Placid Rodrigues
12,630 PointsPlacid Rodrigues
12,630 PointsDRY it :)
Declare and assign the editButton variable before the if/else clause once and then use it in if and else clause.
Marcus Parsons
15,719 PointsMarcus Parsons
15,719 PointsWashed and dried! :P