Create To-do List using Vanilla JavaScript
Karan Developer
Posted on June 30, 2021
It's a simple To-do app. As a beginner, creating these features like DOM manipulations, animations and dark theme feature was challenging for me. So let's see how I created this and what I've learned from it.
Prerequisite Knowledge
Basics of HTML, CSS and JS (specially DOM Manipulations)
What I've Learned
- DOM Manipulation
- Classlist
- ChildNodes
- Forms
- Changing Themes
Let's Start
We will create this project step by step.
1. Brainstorming
First you have to plan the features of your to-do app. You can use any software to plan your project or just a pen and paper. I generally prefer to plan everything in Notion.
2. Sketching
Make a simple sketch of To-do app which contains all your decided features.
3. Prototype
Make a prototype of your app using previous sketch. You can also follow these steps to design your app.
- Make a color palette of 3 colors.
- Choose the typeface.
- Collect SVG icons
- Start designing
- Design the Dark theme
4. Setup Project Environment
In this step, setup the directories and create files for your project.
5. Create HTML structure
Open your index.html
file and create the html structure. Don't forget to link your CSS and Js file with index.html.
Refrence code is given below.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TODO :: By karan Kumar</title>
<link rel="stylesheet" href="style.css" />
<script src="script.js" defer></script>
</head>
<body>
<div class="container task_list_empty">
<header>
<div class="theme_toogle">
<button class="theme_toogle_btn"></button>
</div>
<span class="heading">My Day</span>
</header>
<section class="tasks">
<ul id="tasksList"></ul>
</section>
<footer>
<form id="new_task_form">
<input type="text" name="new_task_input" id="new_task_input" placeholder="Create New Task" value="" />
<button id="new_task_input_btn" type="submit"></button>
</form>
</footer>
</div>
</body>
</html>
6. Add CSS Styling
Open your style.css
file to style the to-do app. Follow these steps to style your to-do.
- Set root variables
- Define container layouts
- Set hover effects
- Style input placeholder using pseudo classes.
- Add Media queries
Refrence code is given below.
:root {
--primary-color: white;
--secondary-color: #1E1E1E;
--text-color: black;
--task-color: white;
--footer-color: #1E1E1E;
--theme-btn: url('assets/Dark-theme-btn.svg');
--container-bg: url('./assets/Light-empty.svg');
--complete-icon: url('assets/complete.svg');
--filter: none;
--theme-transition: 0s;
}
* {
font-family: "Times New Roman";
outline: none;
}
body {
display: flex;
min-height: 100vh;
justify-content: center;
align-items: center;
overflow: hidden;
}
.container {
position: relative;
border: 4px var(--footer-color) solid;
padding: 30px;
display: flex;
flex-direction: column;
width: 300px;
height: 80vh;
border-radius: 20px;
overflow: hidden;
background: var(--primary-color);
transition: var(--theme-transition);
}
header {
display: flex;
flex-direction: column;
}
.heading {
font-weight: 900;
color: var(--text-color);
}
.theme_toogle {
text-align: right;
margin-right: -15px;
}
.theme_toogle_btn {
min-width: 30px;
min-height: 30px;
background-color: transparent;
border: none;
outline: none;
background-image: var(--theme-btn);
background-repeat: no-repeat;
background-size: 80%;
background-position: center;
padding: 20px;
cursor: pointer;
}
.theme_toogle_btn:hover {
background-size: 85%;
transition: 0.5s;
transform: rotate(90deg);
}
.heading {
font-size: 30px;
}
.tasks {
margin: 20px 0px;
overflow: hidden;
padding-right: 15p;
}
#tasksList {
padding: 0px;
}
.task_list_empty {
transition: 0s;
background-position: center;
background-size: 50%;
background-repeat: no-repeat;
background-image: var(--container-bg);
}
.task_item {
list-style-type: none;
border: 1px var(--secondary-color) solid;
padding: 10px;
display: flex;
flex-direction: row;
align-items: center;
border-radius: 7px;
margin-bottom: 20px;
background-color: var(--task-color);
color: var(--text-color);
}
.task_item:hover {
transition: 0.5s;
/* border: 1px rgba(148, 148, 148, 0.63) solid; */
cursor: pointer;
background-color:rgba(226, 226, 226, 0.192);
}
.task_check_btn {
width: 10px;
height: 10px;
margin-right: 16px;
padding: 3px;
border: 2px var(--secondary-color) solid;
/* color: var(--primary-color); */
background-position: center;
background-size: contain;
border-radius: 50%;
border: 2px grey solid;
cursor: pointer;
}
.task_check_btn:hover {
background-image: url('assets/complete.svg');
/* opacity: 0.5; */
filter: var(--filter);
}
.task_bio {
font-size: 18px;
}
.task-completed {
transition: 0.5s;
transform: scale(90%);
text-decoration: line-through;
color: rgb(150, 150, 150);
opacity: 0;
}
footer {
position: absolute;
bottom: 0px;
padding: 15px 10px;
min-width: 100%;
background-color: var(--footer-color);
left: 0px;
border: 5px var(--footer-color) solid;
}
footer form {
display: flex;
flex-direction: row;
align-content: center;
}
#new_task_input {
min-width: 250px;
margin-right: 40px;
font-size: 20px;
color: white;
background-color: transparent;
border: none;
border-bottom: 1px rgba(255, 255, 255, 0.267) solid;
}
#new_task_input::placeholder {
color: rgba(255, 255, 255, 0.589);
font-size: 20px;
font-family: "Times New Roman";
}
#new_task_input_btn {
width: 30px;
height: 30px;
background-color: transparent;
border: none;
background-image: url('./assets/new.svg');
background-repeat: no-repeat;
background-size: 80%;
cursor: pointer;
}
.taskCompleted {
visibility: hidden;
}
@media screen and (max-width : 600px) {
body {
margin: 0px;
padding: 0px;
align-items: flex-start;
height: 100vh;
background-color: var(--bg-color);
}
.theme_toogle {
margin-top: 30px;
}
.container {
border: none;
border-radius: 0px;
width: 100%;
height: 93vh;
padding: 0px 20px;
}
#new_task_input {
margin-right: 20px;
}
}
7. Add JavaScript Functionality
Before starting any JS code, first you have to plan the working of your To-do App
Plan the working of to-do app
When user enter a new task in input and submit the form the task input value will go to a function , which creates a task element with checkbox using task input value. then add another function, which remove the task item when checkbox get checked.
Open your script.js
file and style the to-do app. Follow these steps to add JS Functionality.
Refrence code is given below.
// Variables
var root = document.querySelector(':root')
var container = document.querySelector('.container');
var newTaskInput = document.getElementById('new_task_input')
var taskform = document.getElementById('new_task_form');
var tasksList = document.getElementById('tasksList');
var taskBtns = document.querySelectorAll('.task_check_btn');
var themeBtn = document.querySelector('.theme_toogle_btn');
// Do this when we submit the form
taskform.addEventListener('submit', function (e) {
e.preventDefault();
var newtaskInputValue = taskform.elements.new_task_input;
addTask(newtaskInputValue.value)
// Reset input value to empty
newtaskInputValue.value = '';
container.classList.remove('task_list_empty')
})
// To add task in List
function addTask(newTask) {
// Create li element and set its class
const newTaskItem = document.createElement('li');
newTaskItem.setAttribute('class', 'task_item');
// Create checkbox element and set its type and class
const newCheckBtn = document.createElement('div');
newCheckBtn.setAttribute('class', 'task_check_btn')
// Create span element and set its class and add new task input
const newTaskBio = document.createElement('span');
newTaskBio.setAttribute('class', 'task_bio')
// Put value of input in it
newTaskBio.innerText = newTask; // putting value of input in the li
// append (insert) li tag in Ul
tasksList.appendChild(newTaskItem)
// append (insert) checkbox in li
newTaskItem.appendChild(newCheckBtn)
// append (insert) newtask in li
newTaskItem.appendChild(newTaskBio)
// Run this function when task is completed or checkbox is checked
onTaskComplete(newCheckBtn)
}
// To remove the completed task
function onTaskComplete(btns) {
btns.addEventListener('click', function (e) {
var parent = e.toElement.parentElement;
parent.classList.add('task-completed'); // To slide out the task to the right
// Now we delete that tast which we have slided out
setTimeout(() => {
// Removing Parent Element of checkobx which is Li in 0.5 s
parent.remove();
}, 400);
if (tasksList.childNodes.length == 1) {
setTimeout(() => {
container.classList.add('task_list_empty')
}, 800);
}
})
}
// Dark mode
themeBtn.addEventListener('click', function () {
var darkTheme = themeBtn.classList.toggle('dark')
if (darkTheme) {
root.style.setProperty('--theme-transition', '1s')
root.style.setProperty('--primary-color', '#1E1E1E')
root.style.setProperty('--secondary-color', '#3B3B3B')
root.style.setProperty('--text-color', '#EAEAEA')
root.style.setProperty('--task-color', '#3B3B3B')
root.style.setProperty('--footer-color', '#1E1E1E')
root.style.setProperty('--theme-btn', `url('assets/Light-theme-btn.svg')`)
root.style.setProperty('--container-bg', `url('./assets/Dark-empty.svg')`)
root.style.setProperty('--filter', 'invert()')
} else {
root.style.setProperty('transition', '1s')
root.style.setProperty('--primary-color', 'white')
root.style.setProperty('--secondary-color', '#1E1E1E')
root.style.setProperty('--text-color', 'black')
root.style.setProperty('--task-color', 'white')
root.style.setProperty('--footer-color', '#1E1E1E')
root.style.setProperty('--theme-btn', `url('assets/Dark-theme-btn.svg')`)
root.style.setProperty('--container-bg', `url('./assets/Light-empty.svg')`)
}
})
View Demo
Source Code
thekarandeveloper / To-Do-List
A Todo List built using HTML , CSS and Vanilla JS
Find Me on Instagram
Posted on June 30, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
March 26, 2023