You are on page 1of 2

To make Medium work, we log user data.

By using Medium, you agree to our Privacy Policy,


including cookie policy.
Surya Shakti 30 Followers About Follow Sign in Get started

You have 2 free member-only stories left this month. Sign up for Medium and get an extra one

Building To-Do List App Using


Vanilla JavaScript For Absolute
Beginners
Surya Shakti Jul 31, 2020 · 5 min read

Preview of our To-Do app

The best way to learn something is by doing. In this tutorial, we will be


building a To-Do List app using pure JavaScript. If you are a beginner and
tired of studying from boring theoretical tutorials then you are in a right
place because here we will practically build this To-Do app from scratch.
Don’t worry I have explained each and every step to develop our To-do
app.

In this app, we will be able to add new tasks to be done, delete tasks,
mark tasks after completion, we will have a drop-down menu to filter our
tasks on basis of completed or incomplete tasks.

So without any further delay let’s get started with the coding.

We have to create a folder and we have to create three files there:

1. index.html

2. styles.css

3. main.js

HTML file for our app

1 <html lang="en">
2 <head>
3 <meta charset="UTF-8">
4 <meta name="viewport" content="width=device-width, initial-scale=1.0">
5 <link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
6 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/
7 integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PT
8 crossorigin="anonymous" />
9 <link rel="stylesheet" href="./styles.css">
10 <title>To-Do List App</title>
11 </head>
12 <body>
13 <!-- TITLE -->
14 <header>
15 <h1>WORKS TO BE DONE</h1>
16 </header>
17 <!-- INPUT FIELD TO ENTER TASK AND DROPDOWN FILTER -->
18 <form>
19 <input type="text" placeholder="Enter The Work" class="todo_input" />
20 <button class="todo_button" type="submit">
21 <i class="fas fa-plus-square"></i>
22 </button>
23 <div class="select">
24 <select name="todos" class="filter_todo">
25 <option value="all">All</option>
26 <option value="completed">Completed</option>
27 <option value="uncompleted">Uncompleted</option>
28 </select>
29 </div>
30 </form>
31 <!-- CONTAINER FOR DISPLAYING TO-DO LIST BY ADDING TASKS DYNAMICALLY USING JAVASCRIPT -->
32 <div class="todo_container">
33 <ul class="todo_list"></ul>
34 </div>
35 <!-- ADDING JAVA SCRIPT -->
36 <script src="./main.js"></script>
37 </body>
38 </html>

index.html hosted with ❤ by GitHub view raw

HTML File

As this tutorial mainly focuses on teaching JavaScript concepts, I assume


that you must be familiar with the HTML syntax and easily understand
above code but still we will discuss briefly about what’s happening in this
html file.

In body tag of our file we have three main section: 1. Heading 2. Form
3.Task Container and at last we are just linking our JavaScript file.

Heading section as you already guessed contains title of our app.

In form section, we have an input element to enter a new task, a button


to display that task below, a dropdown which filters our tasks on basis of
completed or incomplete tasks.

In task container section we have all our tasks which are added to our
page dynamically when user adds a task through JavaScript.

CSS file for styling

1 /* REMOVING THE DEFAULT STYLINGS FROM THE PAGE */


2 *{
3 margin: 0;
4 padding: 0;
5 box-sizing: border-box;
6 }
7 /* ADDING BACKGROUND COLOR, FONT FAMILY, FOREGROUND COLOR AND MINIMUN HEIGHT TO OUR PAGE */
8 body{
9 background-image: linear-gradient(120deg, #5f57d1, #c065c0);
10 font-family: 'Poppins', sans-serif;
11 color: white;
12 min-height: 100vh;
13 }
14
15 /* STYLYING INPUT ELEMENT AND TH EBUTTON */
16 header,form{
17 display: flex;
18 min-height: 15vh;
19 justify-content: center;
20 align-items: center;
21 }
22 form input, form button{
23 padding: 0.4rem;
24 border: none;
25 font-size: 1.6rem;
26 background: white;
27 }
28 form button{
29 color: #c065c0;
30 background: white;
31 cursor: pointer;
32 transition: all 0.3s ease;
33 }
34 form button:hover{
35 background: #c065c0;
36 color: white;
37 }
38 /* STYLING DROPDOWN */
39 select{
40 -webkit-appearance: none;
41 -moz-appearance: none;
42 appearance: none;
43 outline: none;
44 border: none;
45 }
46 .select{
47 margin: 1rem;
48 position: relative;
49 overflow: hidden;
50 }
51 select{
52 color: #c065c0;
53 width: 8rem;
54 cursor: pointer;
55 padding: 0.7rem;
56 }
57 .select::after{
58 content: "\25bc";
59 position: absolute;
60 color: #c065c0;
61 top: 7px;
62 right: 6px;
63 pointer-events: none;
64 }
65 .select:hover::after{
66 color: #583429;
67 }
68
69 /* STYLING CONTAINER WHERE THE TASKS ARE SHOWN */
70 .todo_container{
71 display: flex;
72 justify-content: center;
73 align-items: center;
74 }
75 .todo_list{
76 min-width: 40%;
77 list-style: none;
78 }
79
80 .todo{
81 margin: 5px auto;
82 background: white;
83 color: #000000;
84 display: flex;
85 font-size: 1.2rem;
86 padding: 0.3rem;
87 justify-content: space-between;
88 align-items: center;
89 transition: all 0.5s ease;
90 }
91
92 .todo li {
93 flex: 1;
94 }
95
96 /* STYLING THE BUTTONS ON THE TASKS */
97 .complete_btn,
98 .delete_btn{
99 padding: 0.5rem;
100 background: #ff3700;
101 color: white;
102 border: none;
103 margin-left: 0.2rem;
104 cursor: pointer;
105 font-size: 1rem;
106 }
107
108 .complete_btn{
109 background: rgb(67, 179, 67);
110 }
111 .complete_btn:active{
112 background: green;
113 }
114
115 .delete_btn:active{
116 background: #b65337;
117 }
118
119 .fa-trash,
120 .fa-check{
121 pointer-events: none;
122 }
123
124 /* STYLING TASK THAT IS COMPLETED */
125 .completedItem{
126 text-decoration: line-through;
127 opacity: 0.5;
128 transform: scale(0.96);
129 }
130 /* DELETING THE TASKS */
131 .fall{
132 transform: translateY(4rem) scale(0.4) rotateZ(20deg);
133 opacity: 0;
134 }

styles.css hosted with ❤ by GitHub view raw

CSS File

This is my styling for our To-Do List app which you can easily understand
by just reading once as I have also added comments specifying the role of
the code. You can also come up with your own styling. And please send
the link of your styling in comment section. I would love to see all of your
creative styling.

JavaScript file for functionality

1 //selectors
2 const todoInput = document.querySelector('.todo_input');
3 const todoButton = document.querySelector('.todo_button');
4 const todoList = document.querySelector('.todo_list');
5 const filterOption = document.querySelector('.filter_todo');
6 //event listeners
7 todoButton.addEventListener("click", addTodo)
8 todoList.addEventListener("click", deleteCheck)
9 filterOption.addEventListener("click", filterTodo)
10 //functions
11
12 function addTodo(event) {
13 event.preventDefault();
14 //todo DIV
15 const todoDiv = document.createElement('div');
16 todoDiv.classList.add('todo');
17 //todo LI
18 const newTodo = document.createElement('li');
19 newTodo.innerText = todoInput.value;
20 newTodo.classList.add('todo_item');
21 todoDiv.appendChild(newTodo);
22 if(todoInput.value === ""){
23 return null
24 }
25 //check mark BUTTON
26 const completedButton = document.createElement('button');
27 completedButton.innerHTML = '<i class="fas fa-check"></i>';
28 completedButton.classList.add('complete_btn')
29 todoDiv.appendChild(completedButton);
30 //delete BUTTON
31 const deleteButton = document.createElement('button');
32 deleteButton.innerHTML = '<i class="fas fa-trash"></i>';
33 deleteButton.classList.add('delete_btn')
34 todoDiv.appendChild(deleteButton);
35 //Append to Actual LIST
36 todoList.appendChild(todoDiv);
37 //Clear todo input VALUE
38 todoInput.value = ""
39 }
40
41 //DELETE & CHECK
42 function deleteCheck(e) {
43 const item = e.target;
44 //DELETE ITEM
45 if (item.classList[0] === "delete_btn") {
46 const todo = item.parentElement;
47 //ANIMATION TRANSITION
48 todo.classList.add("fall")
49 todo.addEventListener('transitionend', function () {
50 todo.remove()
51 })
52 }
53 //COMPLETE ITEM
54 if (item.classList[0] === "complete_btn") {
55 const todo = item.parentElement;
56 todo.classList.toggle("completedItem")
57 }
58 }
59 //FILTERING THE TASKS ACCORDING THE OPTION
60 function filterTodo(e) {
61 const todos = todoList.childNodes;
62 for(let i = 1; i<todos.length; i++ ){
63 switch (e.target.value) {
64 case "all":
65 todos[i].style.display = "flex";
66 break;
67 case "completed":
68 if (todos[i].classList.contains('completedItem')) {
69 todos[i].style.display = "flex";
70 } else {
71 todos[i].style.display = "none";
72 }
73 break;
74 case "uncompleted":
75 if (!todos[i].classList.contains('completedItem')) {
76 todos[i].style.display = "flex";
77 } else {
78 todos[i].style.display = "none";
79 }
80 break;
81 }
82 }
83 }
84

main.js hosted with ❤ by GitHub view raw

JavaScript File

Here comes the exciting part for which you guys are reading this. The
JavaScript file is responsible for all the functionality of our app.

1. Storing Elements in constants


First let’s store html elements which we will use in different
functionalities.

//selectors

const todoInput = document.querySelector('.todo_input');

const todoButton = document.querySelector('.todo_button');

const todoList = document.querySelector('.todo_list');

const filterOption = document.querySelector('.filter_todo');

Here, with the help of document.querySelector() method we are


storing html elements with specific class to their respective constants.
Now constants todoInput, todoButton, todoList, filterOption
contains html elements.

2. Adding Event Listeners to elements


Now we will add click event listeners to our Buttons and Dropdown
Filter.

//event listeners

todoButton.addEventListener("click", addTodo)

todoList.addEventListener("click", deleteCheck)

filterOption.addEventListener("click", filterTodo)

The addEventListener() method attaches an event handler to the


specified element. Now when we will click ‘+’ button element in our
input then addTodo function will execute. When we will click any task
which is added in task container of our app then deleteCheck function
will execute. When we will click select element (dropdown) in our app
then filterTodo function will execute

3. Adding a Task with check button and delete button

function addTodo(event) {

event.preventDefault();

//todo DIV

const todoDiv = document.createElement('div');

todoDiv.classList.add('todo');

//todo LI

const newTodo = document.createElement('li');

newTodo.innerText = todoInput.value;

newTodo.classList.add('todo_item');

todoDiv.appendChild(newTodo);

if(todoInput.value === ""){

return null;

//check mark BUTTON

const completedButton = document.createElement('button');

completedButton.innerHTML = '<i class="fas fa-check"></i>';

completedButton.classList.add('complete_btn')

todoDiv.appendChild(completedButton);

//delete BUTTON

const deleteButton = document.createElement('button');

deleteButton.innerHTML = '<i class="fas fa-trash"></i>';

deleteButton.classList.add('delete_btn')

todoDiv.appendChild(deleteButton);

//Append to Actual LIST

todoList.appendChild(todoDiv);

//Clear todo input VALUE

todoInput.value = ""

This addTodo function will execute when the add button on input will be
clicked. This function is responsible for adding a task, adding check
button and adding delete button.

Firstly, we are calling event.preventDefault() method which cancels the


event if it is cancelable. In our case as our add button is of submit type,
when we click on this our page gets submitted and get refreshed and
that’s something we don’t want in our application that is where
event.preventDefault() method comes into play method prevent it from
submitting the form.

Then with the help of document.createElement() method we are


creating a html <div> element which will contain the task, check and
delete button. Next we are creating html <li> which is our actual task
which we are getting from todoInput.value which just takes whatever
user types in input field and stores it in this <li> element. In the similar
way we are creating both check and delete buttons. At last we are
checking if our input field is not empty which means there is some task
written there and if so, we are append our <li> (list) and both buttons
in the <div> element we just created.

4. Deleting and checking the task accordingly

//DELETE & CHECK

function deleteCheck(e) {

const item = e.target;

//DELETE ITEM

if (item.classList[0] === "delete_btn") {

const todo = item.parentElement;

//ANIMATION TRANSITION

todo.classList.add("fall")

todo.addEventListener('transitionend', function () {

todo.remove()

})

//COMPLETE ITEM

if (item.classList[0] === "complete_btn") {

const todo = item.parentElement;

todo.classList.toggle("completedItem")

As we have added an event listener on our todoList <div>, whenever we


will click on check or delete button this function will execute. However
on clicking the task itself in the <div> also execute this function but as
we are handling the situation when either of any button is clicked so
clicking the task will not do anything.

In this function we are getting the target element using e.target. Then
we are checking if the target element is delete button or check button. If
it is delete button(delete_btn) then we are simply getting its parent
element with .parentElement property and deleting it with the help of
.remove() method after the transition is completed which is added by
adding ‘fall’ class to the whole <div>. If we clcik on check button
(complete_btn) then we are just toggling a class to the parent element
that is <div> itself which will apply some styling to the task to confirm
that this task is completed.

5. Filtering the tasks according to the selected option

//FILTERING THE TASKS ACCORDING THE OPTION

function filterTodo(e) {

const todos = todoList.childNodes;

for(let i = 1; i<todos.length; i++ ){

switch (e.target.value) {

case "all":

todos[i].style.display = "flex";

break;

case "completed":

if (todos[i].classList.contains('completedItem')) {

todos[i].style.display = "flex";

} else {

todos[i].style.display = "none";

break;

case "uncompleted":

if (!todos[i].classList.contains('completedItem')) {

todos[i].style.display = "flex";

} else {

todos[i].style.display = "none";

break;

When we click one of the options of dropdown then this filterTodo


function will execute. This function is responsible for filtering the tasks
on the basis of all tasks, completed and uncompleted tasks. In constant
todos we are storing all the todo tasks. Then using for loop we are
iterating over them . In the loop we are checking which option is clicked
from the dropdown and just filtering the elements by implementing the
display style to the todos.

For example:- If you clicked completed option of the dropdown then it


will check which todos have class of completed_item and add a style of
flex to it otherwise it will add style of display none to it.

todos[i].style.display = "flex";

} else {

todos[i].style.display = "none";

Other options filter the todos by the same method.

Now our application is working great without any problem.

That is all for today. I hope this was helpful for guys. I will be posting my
ideas on various topics and we will build many cool apps together.

Good Day, Good Coding…

257  1

JavaScript Web Development HTML CSS Javascript Tips

More from Surya Shakti Follow

Computer Science Student, Front-end developer, love photography and paintings,


now a blogger too i guess.

More From Medium

Next.js Project Structure Koop.js in Layman’s Business Data Extractor PEG away at evaluating
Yannick Wittwer
Terms with Google Places API, expressions in JavaScript
Lusi Suwandi
Next.Js, and Node Federico Kereki in Globant
Diligent Dev

The easiest way I know to Think Functionally and A comprehensive guide How to unit test your first
replace icons in a React Become Functional in to using BEM with React Vue.js component
app JavaScript Asís García in Trabe Sarah Dayan in
Tom Parandyk in Views Tools Kretawiweka Nuraga Sani in freeCodeCamp.org
The Startup

About Help Legal

You might also like