How to Create a To Do List by vanilla JavaScript
Published: 2022-10-03 19:28:56

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"!

{% codepen https://codepen.io/hikari7-the-scripter/pen/jOxzare %}


##HTML

```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🎨 

```css
* {
  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. 

```javascript

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

```javascript
element.style.backgroundColor = "red";  
```

**_document.createElement()_**
: creates the HTML element specified by `tagName`
```javascript
const newDiv = document.createElement("div");
```

**_Element.className_**
: gets and sets the value of the class attribute of the specified element.

```javascript
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.

```javascript
setAttribute(name, value)
```


**_Event.target_**
: Returns the element that triggered the event.

```javascript
alert(event.target);
```

**_Element appendChild()_**
: Appends a node (element) as the last child of an element.

```javascript
document.getElementById("myList1").appendChild(node);
```

_**removeChild()**_
: Remove the first element from a list

```javascript
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.


```javascript

//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:

```javascript
 `<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.

```javascript
 addInput.value = "";
```


_**How to add the editing part**_

1. Select the edit icon

```javascript 

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.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uliertb531swf7l1wvzq.png)



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


2. 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!