TODO

Attention

This exercise should be done in groups and submitted as a group.

Include all group members and make sure that everyone knows how your solution works. Only one group member needs to submit the exercise on behalf of the whole group.

In this exercise, you build a simple TODO list application.

Download the template

todo.zip

Instructions

../../_images/w05ex2a.gif ../../_images/w05ex2b.gif

The images above illustrates the goal we are trying to achieve. The first image shows how the application behaves when you are adding items in the list. And the second image shows what happens when you click individual items in the list. New items are appended to the end of the list after you submit the form. At the same time, when a new item is added to the list, the input field is reset back to empty. Clicking an item marks it done and adds a CSS class “done” that causes the style of that item to be modified accordingly. If the same item is clicked twice, it will be removed from the list.

NOTE: The stages below are not all required and the end result is what counts. For more experienced JavaScript coders some of the stages may seem unnecessary but for others they should prove helpful when there are a few checkpoints included in between and some functions are built incrementally.

1. First start by downloading the template files. The HTML template takes care of loading the JavaScript file and you don’t have to change anything else but the todo.js file. All your code goes inside the todo.js file and this is the only file you submit in this exercise.

2. Again there are three important elements in the HTML file: the form input which has id “type-input”, the target list ul-element which has an id “todo” and the form itself which has an id “form”. Your first task is to get a hold of all these elements inside your code. Again you can use document.getElementById() or document.querySelector().

3. Next you should implement the addListItem(text) function. It is responsible for creating new list items (li-elements) and then adding them to the list. As you can see it gets text as its argument. This is the text that the user typed in the input field. This function should first create a new li-element and then put the text inside that element. Finally the function appends the li-element to the end of the list. Useful functions here are document.createElement() and Element.append() and also the property textContent that you have already used in the previous exercise. See: Modifying the document

4. Next you should implement the submitHandler(e) function. You already know that this function is responsible for interrupting the form submit event and cancelling it. But this function is also responsible for reading value of the the input field just like in the previous exercise. And again this function checks whether the value is empty or contains only spaces and in that case it should do nothing else. On the other hand if the input value is not empty this function should call the addListItem(text) function and pass the input value in as an argument. You could of course simply create and add the list item inside submitHandler(e) but it is usually a better idea to separate the concerns of each function so that your code is easier to understand and maintain in the future if you need to change it. For the same reason we have named the functions with long and descriptive names so that anyone reading the code can immediately understand what each functions is responsible for. Finally your submitHandler(e) should reset the input field value back to empty string.

5. Attach the submitHandler(e) function to the form submit event. You should already know how this is done based on the previous exercise.

6. Reload your page to make sure that your changes to the JavaScript file are loaded and test your application. Try submitting text and see if the the text is appended correctly at the end of the TODO list and the input field is reset to empty. Try this a few times. If everything works you can move on to the next phase otherwise you should see some error messages in the browser console. Depending on the message you should try to locate the source of the error and fix it. At this point the most likely source of errors is the addListItem(text) function but it is also possible to have mistakes inside the submitHandler(e). In any case the error message should include the line number of the error. See: Debugging in Chrome

7. Next you should implement the function listClickHandler(e) which is the event handler that is responsible for handling all those clicks to each individual list items and then giving them the class “done” and on the second click removing the list item from the document. This time you don’t have to cancel any default event since clicking a list item (li-element) does not have a default action to cancel but it does not do any harm if you cancel it anyways. This time the e argument refers to the click event and you need to get to the actual li-element that was clicked. Fortunately the event knows that and offers it in its target property. This means that the list item that is clicked can be accessed as e.target. In our case this should always be a list item but there is a chance that somehow the user has clicked another element and it is usually a good idea to check that you are actually dealing with the element you think you are. Therefore the very next thing is to ask the element itself whether it is li-element or not. This can be done with Element.tagName property or in our case e.target.tagName and it should have a value “LI”. If the element is not a list item you should do nothing since we do not want to change anything else in the document. Now lets first just remove the item from the list. Removing an element can be done with node.remove(). See: Node removal

8. Attach the listClickHandler(e) function to the TODO list ul-element’s click event. You should already know how to do this. NOTE: Here we attach this listener on the ul-element and not on each individual li-element. This is possible because of event bubbling. See: Bubbling and capturing and Event delegation

9. Reload your page and test your application. First add a few items to the list. This should work just fine since you already completed that stage. Then try to click one of the list items and see it hopefully disappear. If that happens click all the other elements too and see if you can make the list empty again. If something went wrong you can see the errors in the console as usual. This time all the errors should be in the listClickHandler(e) function. Fix errors and try again.

10. Now it is time to add the check for the class “done” and adding the class if it is missing. You can access all the classes an element has with its classList property. You can add a new class to the element, remove an existing class and also toggle a class to either add or remove a class depending on whether it existed on the element or not. In this case you can add the class to the element with e.target.classList.add("done") and you can ask if the element already has that class with e.target.classList.contains("done"). Remember that if the li-element does not have the class “done” you should add it and not remove the element from the list. And only when the element already has the class “done” you should remove the element. See: How To Modify CSS Classes in JavaScript

11. Reload your page and test your application. First add a few items to the list. This should work just fine since you already completed that stage. Then try to click one of the list items. If the item changes its appearance try clicking another element to see it change too. NOTE! Here you must also have the stylesheet or the class “done” does not change anything and you don’t see any change. If everything worked so far go ahead and click one of the items second time and see it hopefully disappear. If that happens click all the other elements too and see if you can make the list empty again. If something went wrong you can see the errors in the console as usual. This time all the errors should be in the listClickHandler(e). Fix errors and try again.

12. Before submitting this exercise do one final check so that everything is in place and then go ahead and submit. Congratulations!

A+ presents the exercise submission form here.