DEV Community

Hikari
Hikari

Posted on

How to Create a To Do List by vanilla JavaScript

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😁

  1. Add HTML
  2. Add CSS
  3. 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>

Enter fullscreen mode Exit fullscreen mode

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;
}

Enter fullscreen mode Exit fullscreen mode

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");

Enter fullscreen mode Exit fullscreen mode

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";  
Enter fullscreen mode Exit fullscreen mode

document.createElement()
: creates the HTML element specified by tagName

const newDiv = document.createElement("div");
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

Element.setAttribute()
: Sets the value of an attribute on the specified element.

setAttribute(name, value)
Enter fullscreen mode Exit fullscreen mode

Event.target
: Returns the element that triggered the event.

alert(event.target);
Enter fullscreen mode Exit fullscreen mode

Element appendChild()
: Appends a node (element) as the last child of an element.

document.getElementById("myList1").appendChild(node);
Enter fullscreen mode Exit fullscreen mode

removeChild()
: Remove the first element from a list

list.removeChild(list.firstElementChild);
Enter fullscreen mode Exit fullscreen mode

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);
  }
});

Enter fullscreen mode Exit fullscreen mode

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>`
Enter fullscreen mode Exit fullscreen mode

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 = "";
Enter fullscreen mode Exit fullscreen mode

How to add the editing part

  1. 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.

Enter fullscreen mode Exit fullscreen mode

The console result will be like below which means you have an object called DOMTokenList and has the class.

Image description

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.

  1. 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 the textContent
  • 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)

Collapse
 
yuridevat profile image
Julia πŸ‘©πŸ»β€πŸ’» GDE

Great article on DOM manipulation with a perfect example every developer can relate to.

Collapse
 
hikari7 profile image
Hikari

Thank you for your comment, Julia :))