GOAL:
Create a simple To-Do List App where the user enters a task into the input field and click the “Add” button. The task gets added to an unordered list. Each task will also have a “Delete” button. When a task is completed, the user can click the “Delete” button next to the task and the task is removed from the unordered list.
Step 1: Create the HTML structure.
- Create HTML for a form with a text input field and a button.
- Create an empty unordered list where the tasks will be added on the fly.
- Add id for the text field and the unordered list so we can use Javascript to hook to these elements.
- Add headings to improve the readability of the app.
The HTML snippet
<form id="taskForm">
<input id="taskInput" type="text" autocomplete="off">
<button>Create A Task</button>
</form>
<h3>My To Do List</h3>
<ul id="taskList"></ul>
Step 2: Hook to the form’s submit event.
- Hook on to the document’s form element.
- Look out for the form element’s ‘submit’ event by using the ‘addEventListener’ method.
- Prevent the default behavior of the submit event. Instead of the submit events default behavior- sending the data to the server, we want the web browser to handle things from the javascript.
- Add a simple alert inside the ‘addEventListener’ method to test out the code.
Notes:
- The ‘addEventListener’ method takes in two parameters- The event we want to listen to and the function that you want to run when the event happens.
- Instead of using an anonymous function, we are using the arrow function as the second parameter.
- The default behavior of a submit event is to send the data to the server. In this case, we don’t want that. We want the web browser to handle things from the Javascript instead. Hence we use a method called preventDefault.
- The addEventListener passes a ton of information about the event to our function as a parameter. To access the information, we use a variable ‘e’ and call the method preventDefault to prevent the form’s default submit behavior.
The Javascript snippet
let ourForm = document.getElementById('taskForm');
ourForm.addEventListener('submit', (e)=>{
e.preventDefault();
alert('Testing the submit event');
} )
Step 3: Get the task entered in the text field
- Hook on to the form’s input text field.
- Get the value entered inside the text field.
- To test out that we are accessing the correct information, log out the value to the console.
The Javascript snippet
let ourInput = document.getElementById('taskInput');
ourForm.addEventListener('submit', (e)=>{
e.preventDefault();
console.log(ourInput.value);
} )
Step 4: Hook on to the list element where the task is to be displayed and pass it to to that.
- Hook on to the page’s unordered list where you want to display the list of tasks.
- Call a new function which will create the HTML for the new task inside the unordered list.
- Pass the user input text field value to the function.
- Inside the function, use the insertAdjacentHTML Method to add the task to the unordered list as a text.
The Javascript snippet
let ourList = document.getElementById('taskList');
ourForm.addEventListener('submit', (e)=>{
e.preventDefault();
createMyTaskList(ourInput.value);
} )
function createMyTaskList(x){
ourList.insertAdjacentHTML('beforeend', x);
}
Notes:
- The insertAdjacentHTML takes two values – The position where you want to add the new element and the text to be inserted.
- Since we want to add the new task at the end of the unordered list, we are using ‘beforeend’ as the first parameter.
- To test the code, we are adding the user input value first as simple text instead of an unordered list li item in Step 4.
Step 5: Convert the task into a list element.
- Instead of adding the input value as a simple text, lets convert it into an HTML li element, using a temperate literal.
- Also add a ‘Delete’ button to eack task item so the user can delete the task from the list when he is done.
The Javascript snippet
function createMyTaskList(x){
let newValue = `<li>${x} <button>Delete</button></li> `
ourList.insertAdjacentHTML('beforeend', newValue);
}
Notes:
- Temperate literals are enclosed between two back-ticks (“). On a MAC, you can find the back-tick key above the tab key.
- Temperate literals can have placeholders in the text with the expression or variable you want to replace. These are indicated by the dollar sign and curly braces (${expression}).
Step 6: Add improvements to the user experience.
- To improve the user experience, add auto clear to the text field, once the task is added to the unordered list below.
- Again, to improve the user experience, make sure the focus goes into the text field, once the task is added to the unordered list.
The Javascript snippet
ourInput.value = " ";
ourInput.focus();
Step 7: Hook the delete button to remove the task when the user clicks it.
- Hook the Delete button to a function using the onclick event.
- Test the code by using an alert message.
The Javascript snippet
function createMyTaskList(x){
let newValue = `<li>${x} <button onclick="deleteMyTaskList()">Delete</button></li> `
ourList.insertAdjacentHTML('beforeend', newValue);
ourInput.value = " ";
ourInput.focus();
}
function deleteMyTaskList(){
alert('Delete Requested');
}
Notes:
- Why we can’t use addEventListener for the Delete Button: Because when the page is loaded for the first time, there is NO delete button. You can’t add an Event Listener to a DOM element that doesn’t exist on page load.
Step 8: Complete the delete button functionality and test.
- Complete the function for Delete. Use the ‘this’ keyword to bind to the ‘button’ object and pass it to the ‘Delete’ function.
- Using the parentElement property, access the li element that is the parent for the selected ‘button’ object.
- Using the remove method, remove the parent element from the DOM.
The Javascript snippet
let newValue = `<li>${x} <button onclick="deleteMyTaskList(this)">Delete</button></li>`
.
.
.
function deleteMyTaskList(taskToDelete){
taskToDelete.parentElement.remove();
}
Notes:
- In HTML, every element is an object.
- this keyword binds to the object calling the function. In this case, that is the button object.
LIMITATIONS:
This is a simple app to level up your Javascript skills. There is a problem with this app in that every time the page is loaded, the app is refreshed and all the data will be lost. In the real world, you will need to store the data on the server or database. Databases do NOT work with HTML data. Instead, they require the data in a raw format like JSON. To overcome this, frameworks like React, Angular, or Vue are used in the real world.