Note App

With localStorage & markdown formatting.

Hello Everyone, let's build a Note app today.

Tech Stacks: HTML, CSS & JavaScript.

Features ⬇️

  1. CRUD Operations i.e. notes can be created, read, updated and deleted as well.
  2. Implementation of local storage, so save notes even after a refresh/reload
  3. Simple to build while following along

Step 1: Create an index.html file

  • We started with a standard HTML template.
  • Used a CDN link between head tag, so that we can use the icons.
  • Integrated the stylesheet(will be creating in step 2) style.css with HTML.
  • Inside body tag we have a add button only. Other things will be rendered using Js.
  • At last we have two script tags, one is for the markdown library other is for our script file.
<!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" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PTKnXrLnZ9+fkDaog==" crossorigin="anonymous" />
    <title>Note App</title>
    <link rel="stylesheet" href="style.css" />
</head>
<body>
    <button class="add" id="add">
      <i class="fas fa-plus">  Add Note</i>
    </button>
    <script src="https://cdn.jsdelivr.net/npm/marked@3.0.7/marked.min.js"></script>
    <script src="script.js"></script>
</body>
</html>

Step 2: Create an style.css file

  • We started with importing font a from Google Fonts.
  • Than we started with styling the elements by targeting their classes and names.
@import url('https://fonts.googleapis.com/css?family=Montserrat:300,600&display=swap');
* {
    box-sizing: border-box;
}

body {
    font-family: 'Montserrat', sans-serif;
    display: flex;
    flex-wrap: wrap;
    margin: 0;
    background-color: #e2d0b7;
    padding-top: 3rem;
}

.add {
    position: fixed;
    top: 1rem;
    right: 1rem;
    background-color: seagreen;
    border: none;
    border-radius: 3px;
    padding: 0.5rem 1rem;
    color: white;
}

.note {
    background-color: white;
    box-shadow: 0 0 10px 4px rgba(0, 0, 0, 0.1);
    margin: 30px 20px;
    height: 300px;
    width: 300px;
}

.note .tools {
    background-color: seagreen;
    display: flex;
    justify-content: flex-end;
    padding: 0.5rem;
}

.note .tools button {
    background-color: transparent;
    border: none;
    color: white;
    cursor: pointer;
    font-size: 1rem;
    margin-left: 0.5rem;
    font-family: inherit;
}

.note textarea {
    outline: none;
    font-family: inherit;
    font-size: 1.2rem;
    border: none;
    height: 300px;
    width: 100%;
    padding: 20px;
}

.main {
    padding: 20px;
}

.hidden {
    display: none;
}

Step 3: Create a script.js file

  • Let's start with accessing the add button in script file
  • Now using the element name, let's add a click event listener to it. That means every time we click on the add button it will invoke the function addNewNote()
const addBtn = document.getElementById('add');
addBtn.addEventListener('click', () => {
    addNewNote("Hello from @deeqakkk");
});
  • We create a function addNewNote() that takes text as a parameter.
  • Then we create a element div using createElement() method along with adding a class note to it.
  • Till now our div with class note is empty, so let's just add content to it using innerHTML() method Note: "We have kept class of last two sections dynamic so that they can be updated lateron."
  • We have a function updateLocalstorage() that we will discussed further
function addNewNote(text = 'Hello World') {
    const note = document.createElement('div');
    note.classList.add('note');

    note.innerHTML = `<div class="tools">
    <button class="edit">
    <i class="fas fa-edit"></i>
    </button>
    <button class="delete">
    <i class="fas fa-trash-alt"></i>
    </button>
    </div>
    <div class="main ${      text ? ' ' : 'hidden'    }"></div>
    <textarea class="${      text ? 'hidden' : ''    }"></textarea>`;

//Accessing all the elements using their classnames
    const editBtn = note.querySelector('.edit');
    const deleteBtn = note.querySelector('.delete');
    const main = note.querySelector('.main');
    const textArea = note.querySelector('textarea');

//Here we assigned a value to textArea 
    textArea.value = text;
//Adding content to `main` div along with `marked()` 
//method so that it can handle md formating.
    main.innerHTML = marked(text);

//Adding click event listener to `deleteBtn`, so that 
//everytime it is clicked `note` will be `removed` from 
//DOM as well as local storage.
    deleteBtn.addEventListener('click', () => {
        note.remove();
        updateLocalStorage()
    });

//Adding `click` event listener to the `editBtn` so that
// everytime is clicked it will `toggle` the class `hidden`
// in `main` div & `textarea` as well.
    editBtn.addEventListener('click', () => {
        main.classList.toggle('hidden');
        textArea.classList.toggle('hidden');
    });

//textArea have a event listener of `input` which means 
//everytime we write something, it will execute the nested lines.
    textArea.addEventListener('input', (e) => {
        const { value } = e.target;
        main.innerHTML = marked(value);
        updateLocalStorage();
    });

//Finally  here we are adding the `note` div that we 
//created to the main `body`
    document.body.appendChild(note);
};
  • Let's start with function updateLocalStorage() first, basically it is traversing through all the textarea(that we created using 'add button')
  • In the next step, we are pushing all the 'note' in an array called notes using forEach() loop.
  • Once we have all the 'note' in array, we will stringify and store it in local storage.
  • Finally, we added a condition at the top, if we have notes in the localstorage, than we will run a forEach() loop and pass it to the addNewNote() function
const notes = JSON.parse(localStorage.getItem('notes'));

if (notes) {
    notes.forEach(note => addNewNote(note));
}

function updateLocalStorage() {
    const notesText = document.querySelectorAll('textarea');
    const notes = [];
    notesText.forEach(note => {
        notes.push(note.value);
    });

    localStorage.setItem('notes', JSON.stringify(notes));
}

Final script code

const addBtn = document.getElementById('add');
const notes = JSON.parse(localStorage.getItem('notes'));
if (notes) {
    notes.forEach(note => addNewNote(note));
}
addBtn.addEventListener('click', () => {
    addNewNote("Hello from @deeqakkk");
});

function addNewNote(text = 'Hello World') {
    const note = document.createElement('div');
    note.classList.add('note');

    note.innerHTML = `<div class="tools">
    <button class="edit">
    <i class="fas fa-edit"></i>
    </button>
    <button class="delete">
    <i class="fas fa-trash-alt"></i>
    </button>
    </div>
    <div class="main ${      text ? ' ' : 'hidden'    }"></div>
    <textarea class="${      text ? 'hidden' : ''    }"></textarea>`;

    const editBtn = note.querySelector('.edit');
    const deleteBtn = note.querySelector('.delete');
    const main = note.querySelector('.main');
    const textArea = note.querySelector('textarea');

    textArea.value = text;
    main.innerHTML = marked(text);

    deleteBtn.addEventListener('click', () => {
        note.remove();
        updateLocalStorage()
    });

    editBtn.addEventListener('click', () => {
        main.classList.toggle('hidden');
        textArea.classList.toggle('hidden');
    });

    textArea.addEventListener('input', (e) => {
        const { value } = e.target;
        main.innerHTML = marked(value);
        updateLocalStorage();
    });
    document.body.appendChild(note);
};

function updateLocalStorage() {
    const notesText = document.querySelectorAll('textarea');
    const notes = [];
    notesText.forEach(note => {
        notes.push(note.value);
    });
    localStorage.setItem('notes', JSON.stringify(notes));
}

Github Repo(Codebase): Notes App
Live Link : Hosted here

New Here?
Allow me to introduce myself 👋

Hello, I'm Deepak Verma a student and a fullstack developer💻 from India. I have worked with number of startups and been a part of open-source community as well. Apart from coding, I love to play video games and read books. I write about Web Development and my journey of being a software developer.

If you have a code to discuss or want to team up at valorant, we can connect here : Github || Linkedin || Twitter

Thanks for reading, it was nice having you here.