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 trialAndrey Konovalenko
9,409 PointsSolution for Interactive Web Pages with JavaScript - Perfect 1 empty task - solved; 2 Save button - added.
Hi! For solving the issue with empty task, I've used an if else statement.
var addTask = function() {
console.log("AddTask...");
//Create a new list intem with the text form #new-task:
var emptyTask = "";
if (taskInput.value !==emptyTask) {
var listItem = createNewTaskElement(taskInput.value);
//Append listItem to incompleteTasksHolder
incompleteTasksHolder.appendChild(listItem);
bindTaskEvents(listItem, taskCompleted);
taskInput.value = "";
} else {
console.log("No task was appended");
}
}
To change edit button to "Save" button I've used querySelector("button.edit") in editTask function
var editTask = function() {
console.log("editTask...");
var listItem = this.parentNode;
var editInput = listItem.querySelector("input[type=text]");
var label = listItem.querySelector("label");
var containsClass = listItem.classList.contains("editMode");
var button = listItem.querySelector("button.edit");
console.log(button.innerText);
//if the class of the perent is .edidMode
if(containsClass) {
//Switch from .editMode
//Label text become the input's value
label.innerText = editInput.value;
button.innerText = "Edit";
} else {
//else
//Switch to .editMode
//input value becomes to label's
editInput.value = label.innerText;
button.innerText = "Save";
}
//Toggle .editMode on the liet item
listItem.classList.toggle("editMode");
}
docgunthrop
12,445 Pointsone other thing is adding this line is redundant:
var emptyTask = "";
Instead, you can modify this line:
if (taskInput.value !==emptyTask)
to become:
if (taskInput.value !== "")
Gabriel E
8,916 PointsAlso, if you wanted to do the toggle between Save and Edit button like in your original post, you don't need that "button.edit" that's in your variable 'button', it works just as "button". Sorry if this was confusing, I was just a bit happy I solved this as well!
3 Answers
Andrey Konovalenko
9,409 PointsThank you. I understood what did you mean. In my case selecting button.edit in editTask was redundant because we have already did It in bindTaskEvents function. Now I realize why you suggested me to use this global object.
Here is editTask function with your suggestion I commented my variant of code and It became bit shorter and without repeating.
var editTask = function() {
console.log("editTask...");
var listItem = this.parentNode;
var editInput = listItem.querySelector("input[type=text]");
var label = listItem.querySelector("label");
var containsClass = listItem.classList.contains("editMode");
/* var button = listItem.querySelector("button.edit");
console.log(button.innerText);*/
//if the class of the parent is .edidMode
if(containsClass) {
//Switch from .editMode
//Label text become the input's value
label.innerText = editInput.value;
this.innerText = "Edit";
} else {
//else
//Switch to .editMode
//input value becomes to label's
editInput.value = label.innerText;
this.innerText = "Save";
}
//Toggle .editMode on the liet item
listItem.classList.toggle("editMode");
}
Tonye Jack
Full Stack JavaScript Techdegree Student 12,469 PointsBetter Solution to Warn the user When they try to create an Empty Task shows a warning Message in Red
<script>
//Add new task
var addTask = function(){
console.log("Add Task");
var parent = this.parentNode;
if (taskInput.value === "" ){
console.log("Empty");
var warn = document.createElement("p");
warn.innerText = "Can't create an Empty Task";
warn.style.color = "red";
parent.appendChild(warn);
}
else{
//Create a new list of the item with the text from #new-item:
var listItem = createNewTaskElement(taskInput.value);
//Append list Item to the Incomplete taskHolder
incompleteTasksHolder.appendChild(listItem);
bindTaskEvents(listItem, completedTask);
taskInput.value = "";
var check = parent.querySelector("p");
if (check){
parent.removeChild(check);
}
}
}
</script>
For Edit and Save Button to Switch Edit and Save when you finish editing
<script>
//Edit Existing task
var editTask = function(){
console.log("Edit Task");
//If the class of the parent is .editMode
var listItem = this.parentNode;
var editInput = listItem.querySelector("input[type=text]");
var label = listItem.querySelector("label");
var containsClass = listItem.classList.contains("editMode");
var editButton = listItem.querySelector("button.edit");
if (containsClass){
//Switch from .editMode
//Label text becomes the input value
label.innerText = editInput.value;
editButton.innerText = "Edit";
}
else{
//Switch to .editMode
//Input value becomes the labels text
editInput.value = label.innerText ;
editButton.innerText = "Save";
}
//toggle editmode on the list item
listItem.classList.toggle("editMode");
}
</script>
Andrey Konovalenko
9,409 PointsThanks for answer) I'm not familiar with .this statement yet. I checked your advice, it works. But I don't really understand why?
Where the connection between button.edit and this.innerText
Not only button have innerText.
How can we know that we change particular innerText in button when we use .this statement?
When i use button.innerText i have 100% confidence that i chose particular button.
Henry Morrow
19,425 PointsTo be honest I just did this lesson for the second time and for some reason it finally clicked for me. I would agree that using button.innerText probably assures for more piece of mind to know exactly what you are selecting and I understand why you would use that. I just was able to put together that the editTask function was directly tied to the editButton back in the bindTaskEvents function any code we entered would affect the Edit button tags in the html. Sorry I can't really explain it better as of yet.
Ullas Savkoor
6,028 PointsWhen the event handler for edit button is called, an object is passed implicitly to the function/eventhandler. The object passed is the HTML element upon which the triggering action occurred in this case it was the mouse click and the element was the editbutton
Now the object which was passed implicitly to the eventhandler is referenced by the 'this' variable , that is the 'this' variable points to the implicilty passed object .
Since in our case the edit button is the object passed implicitly to the editTask eventHandler, the 'this' reference variable will always point to the edit button.
Hopes this clears your doubt.
Henry Morrow
19,425 PointsHenry Morrow
19,425 PointsSince the function is also being performed on the button for edit I think you can also use
this.innerText = "Save";