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 Perfect

Jonas Troyer
Jonas Troyer
10,912 Points

Adding 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

Hey 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
Placid Rodrigues
12,630 Points

DRY it :)

Declare and assign the editButton variable before the if/else clause once and then use it in if and else clause.

Washed and dried! :P