Creating a "to-do list" app is the one of essential ways to deepen your DOM manipulation knowledge. I made it once before, however, it was a pretty redundant code so wasn't satisfied with my work at the time.
However, I learned DOM essence again and how to use them effectively recently. So I'd like to share what I learned and hope it would be some ideas to create your own "to-do list" by vanilla JavaScript.
Basic Steps
These are basic steps to create apps by vanilla JS which you already might knowπ
- Add HTML
- Add CSS
- Add JavaScript!
The Sample
And here's the sample of the "to-do list"!
HTML
<!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>Note Manager</title>
<script
src="https://kit.fontawesome.com/d4e1c36ab6.js"
crossorigin="anonymous"
></script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="wrapper">
<header>
<h2 id="heading">To Do List</h2>
</header>
<div class="note-list">
<ul id="list"></ul>
</div>
<div class="add-note">
<form id="add">
<input type="text" placeholder="Add note..." id="add-input" />
<button type="submit" id="add-btn">Add Note</button>
</form>
</div>
</div>
<script src="exercise.js"></script>
</body>
</html>
I haven't added <li>
and <p>
inside of the <div class="note-list">
which is the basic area of the note yet because they'll be implemented by DOM later on!
So, the blueprint is important since it makes orgnaized to think which part will be added by JavaScript.
Also, when it comes to adding <form>
, I recommend making sure to think whether to mark it up with type="submit"
!
Because using an <input type=submit>
in the form, which is what gets the automatic Enter Key behaviour so can be a good user-friendly experience.
CSS
Enjoy to write your codes for whatever your preferable designπ¨
* {
margin: 0;
padding: 0;
}
body {
font-family: "Concert One", cursive;
color: #333;
}
.wrapper {
width: 90%;
max-width: 760px;
margin: 20px auto;
border-radius: 3px;
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.2);
box-sizing: border-box;
padding: 0 0 20px;
border: 1px solid lightgray;
}
.changeBg {
background-color: yellow;
}
.changeFt {
font-style: italic;
font-size: 40px;
}
input {
color: #777;
outline: none;
border: 1px solid #777;
}
header {
text-align: center;
background: #ffd1d1;
}
header h2 {
padding: 40px 0 20px 0;
color: #555;
}
header #search-note input {
padding: 5px 2px;
width: 200px;
border-radius: 2px;
margin: 10px 0 40px 0;
}
.note-list ul {
list-style: none;
padding: 40px;
}
.note-list ul li {
padding: 5px;
margin-bottom: 10px;
border-bottom: 0.1px solid #ccc;
border-left: 5px solid #ffd1d1;
}
.note-list ul li p:nth-child(2) {
text-align: right;
}
.note-list ul li p i {
cursor: pointer;
margin-left: 5px;
}
//the icon which is from font awesome
.note-list ul li p i.fa-pencil-square-o {
color: #228b22;
}
//the icon which is from font awesome
.note-list ul li p i.fa-times {
color: #dc143c;
}
.note-list ul li input {
display: none;
padding: 5px 0;
width: 70%;
margin: 5px auto 0 auto;
}
#add-notes {
padding: 60px 0;
}
form#add {
margin-top: 10px;
text-align: center;
}
form#add input {
border-radius: 2px;
}
form#add input[type="text"] {
padding: 6px;
width: 250px;
}
#add-btn {
padding: 4px;
border-radius: 2px;
}
The edit icon and delete icon appear once the user inputs the note. So these are already supposed to be added in CSS and hidden and displayed by JS.
JavaScript
All right, let's start writing JavaScript then!
Let's see the very basic flow of implementing DOM first.
Basically, when you implement the DOM function, we will follow the below flow for the elements.
1. Select
To manipulate an element inside the DOM, you need to select it and store a reference to it inside a variable at first.
// Get the first <p> element:
document.querySelector("p");
//Get the first element with class="example":
document.querySelector(".example");
2. Manipulate
We can start to manipulate the elements using the properties and methods available.
I'll introduce some are used in the "to-do list" below.
style
: returns the values of an element's style attribute.
element.style.backgroundColor = "red";
document.createElement()
: creates the HTML element specified by tagName
const newDiv = document.createElement("div");
Element.className
: gets and sets the value of the class attribute of the specified element.
secondIcon.className = "fa fa-times";
//(It was also used to add font awesome in this work)
Element.setAttribute()
: Sets the value of an attribute on the specified element.
setAttribute(name, value)
Event.target
: Returns the element that triggered the event.
alert(event.target);
Element appendChild()
: Appends a node (element) as the last child of an element.
document.getElementById("myList1").appendChild(node);
removeChild()
: Remove the first element from a list
list.removeChild(list.firstElementChild);
3. Events
Responding to user inputs and actions!
Such as The addEventListener()
method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target.
//1. Select
const ul = document.querySelector("#list");
//3. Events
document.getElementById("add-btn").addEventListener("click", function (e) {
e.preventDefault();
const addInput = document.getElementById("add-input");
if (addInput.value !== "") {
//2. Manipulate
//create note elements
const li = document.createElement("li"),
firstP = document.createElement("p"),
secondP = document.createElement("p"),
firstIcon = document.createElement("i"),
secondIcon = document.createElement("i"),
input = document.createElement("input");
//create attributes
firstIcon.className = "fa fa-pencil-square-o";
secondIcon.className = "fa fa-times";
input.className = "edit-note";
input.setAttribute("type", "text");
//add text to first paragraph
firstP.textContent = addInput.value;
//appending stage
secondP.appendChild(firstIcon);
secondP.appendChild(secondIcon);
li.appendChild(firstP);
li.appendChild(secondP);
li.appendChild(input);
ul.appendChild(li);
addInput.value = "";
}
});
// Editing and deconsting
ul.addEventListener("click", function (e) {
// console.log(this);
// console.log(e.target.classList);
if (e.target.classList[1] === "fa-pencil-square-o") {
//<li>: the parent of the icon <p>
const parentP = e.target.parentNode;
parentP.style.display = "none";
//note
const note = parentP.previousElementSibling;
//<input>: the previousElementSibling of <li>
const input = parentP.nextElementSibling;
//show the block section
input.style.display = "block";
input.value = note.textContent;
input.addEventListener("keypress", function (e) {
//e.keyCode === 13 represents "Enter"
if (e.keyCode === 13) {
if (input.value !== "") {
//add the text which was input
note.textContent = input.value;
parentP.style.display = "block";
input.style.display = "none";
}
}
});
}
if (e.target.classList[1] === "fa-times") {
const list = e.target.parentNode.parentNode;
list.parentNode.removeChild(list);
}
});
Tips for creating a "to-do list by DOM"
Lastly, I'd like to share some parts which I think it would be nice tips for creating a "to-do list".
Programatic approach
Instead of the DOM, you can also wrtie the note section by InnerHTML like this:
`<li>${addInput.value}</li>`
Even if it's a redundant code, I guess basically creating elements through the DOM is easier to manipulate them eventually b because I also put the edit and delete functions smoothly for each element.
How to reset the value
Once the user add the note, how can we reset the value?
It's easy to solove this, just you can put an empty string.
addInput.value = "";
How to add the editing part
- Select the edit icon
ul.addEventListener("click", function(e){
console.log(this)
console.log(e.target.classList)
}
//"event.target" returns the value of where the user is clicking on.
The console result will be like below which means you have an object called DOMTokenList and has the class.
So, you can access the index[1]
through the e.target
to choose the edit icon (the pencil icon) and set the condition to check if the user clicks that. And then put them inside of the addEventLisetener
.
- Manipulate inside of the
addEventLisetener
Let's manipulate the inside of the function which the user clicked the edit button then!
The flow is like these:
- Create the note section with invoking CSS
- Set the
input.value
with thetextContent
- Add the event contents to show what the user keypressed
I also added some comments on the above codes so please refer to them as well!
Conclusion
DOM manipulations are very important essense to understand JavaScript. I hope it will be helpful to understand the JavaScript libraries in the futureπ€
Thank you so much for reading and happy coding!
Top comments (2)
Great article on DOM manipulation with a perfect example every developer can relate to.
Thank you for your comment, Julia :))