Build a TODO app using Vanilla JavaScript
Hussain Pettiwala
Posted on July 16, 2022
Building a TODO app is a very basic but thorough way to understand concepts of a software tool.
We will build a TODO app using JavaScript
for logic and Bootstrap
for styling in this tutorial.
Try out the app here
.
We will follow the following steps:
Building the User Interface (UI)
with Bootstrap
Start with
Bootstrap's Starter Template
Create a
form
for user to enter the TODO item.Create an unordered list to
hold all todos
.Create
list element
with checkbox for a todo item.Make UI
responsive
using Bootstrap's grid system
Handling functionality
with JavaScript
- Define structure of our data - way to represent all TODOs in a
JSON (JavaScript Object Notation)
format. -
renderTodos
function to display TODOs in the UI. -
renderTodo
helper function to render an individual TODO. -
addTodo
function to add a TODO - Setup an Event Listener for
submitting
the todo from the UI. -
completeTodo
function to mark a TODO as completed
Building UI
Copy bootstrap's starter template and add custom script tags
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Bootstrap CSS -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous"
/>
<title>TODO App</title>
</head>
<body>
<!-- CONTENT -->
<div></div>
<!-- custom JS -->
<script src="./script.js"></script>
<!-- Bootstrap JS -->
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"
></script>
</body>
</html>
Create a form for user to enter the TODO item
- Give unique
id
totext field
andform
to refer them in our JavaScript later.
<form id="todo-form">
<!-- input field -->
<input
id="todo-text"
class="form-control form-control-lg"
type="text"
placeholder="Your TODO"
required
/>
<!-- submit button -->
<input type="submit" class="btn btn-primary my-3 w-100" />
</form>
Create an unordered list to hold all todos
<ul id="todo-list" class="list-unstyled"></ul>
Create list element with checkbox for a todo item
<li>
<div class="form-check">
<input class="form-check-input" type="checkbox" />
<label class="form-check-label" for="flexCheckDefault"> TODO Text </label>
</div>
</li>
Make UI responsive using Bootstrap's grid system
<div class="container">
<div class="row row-cols-1 row-cols-sm-1 row-cols-md-2">
<div class="col">
<!-- todo form goes here -->
</div>
<div class="col">
<!-- todo list goes here -->
</div>
</div>
</div>
Handle functionality using JavaScript
Lets start by creating an array of objects for our todos
.
var todos = [
{
id: 0,
text: "subscribe to KJSCE codecell",
complete: false,
},
{
id: 1,
text: "Star https://github.com/pettiboy/react-ui-scrollspy on GitHub",
complete: false,
},
];
Select all required elements from the DOM
const list = document.getElementById("todo-list");
const form = document.getElementById("todo-form");
const todoText = document.getElementById("todo-text");
Lets try to render these todos
to the DOM from our JS
/*
loops over each todo in todos and if the task is not completed yet
calls the renderTodo function to render it to the DOM
*/
function renderTodos() {
emptyTodos();
todos.forEach((todo) => {
if (todo.complete === false) {
renderTodo(todo);
}
});
}
/*
takes a todo object as input and appends the innerHTML
of the unordered list with that todo
*/
function renderTodo(todo) {
list.innerHTML += `
<li>
<div class="form-check">
<input onclick="completeTodo(${todo.id});" class="form-check-input" type="checkbox" />
<label class="form-check-label" for="flexCheckDefault">
${todo.text}
</label>
</div>
</li>
`;
}
Lets write a function that given a todo
adds it to our array of objects called todos
.
function addTodo(todo) {
todos.push({
id: todo.id,
text: todo.text,
complete: todo.complete,
});
// render that todo to the DOM
renderTodo(todo);
}
Setup an Event Listener
for submitting the todo
// listen for form to be submitted
form.addEventListener("submit", (e) => {
e.preventDefault();
addTodo({
id: todos.length + 1,
text: todoText.value,
complete: false,
});
// reset value of input field
todoText.value = "";
});
Lets write a function to mark a todo
as completed
function completeTodo(removeId) {
// Find index of specific object using findIndex method.
todoIndex = todos.findIndex((todo) => todo.id == removeId);
// Update object's name property.
todos[todoIndex].complete = true;
// Just to wait for a sec before re rendering
setTimeout(function () {
saveTodosInMemory();
renderTodos();
}, 1000);
}
Store the todos in localStorage
// on page load - the following functions will run
todos = JSON.parse(localStorage.getItem("todosInMemory")) || [];
renderTodos();
Now that we can build a TODO app using JavaScript, we will use a popular framework called React
to build this app and see how it compares and solves various problems with writing code using Vanilla JavaScript.
To watch a video version of this tutorial check out this lecture I had given at KJSCE Codecell's Month Of MERN.
You can also find the code on GitHub
.
Posted on July 16, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.