How can I save notes with JSON and localstorage? Javascript

I created a page where I can create a note with a title, description and the background color. I can also delete the note. The next and final step that I want to do is that when I return to the page that the notes have been saved and are still visible from the last time. I want to do this with JSON and localstorage . I have already tried a number of things as you can see in the comments from my Javascript but I don’t succeed. I have to admit that I’m a beginner in localstorage. I’ve been stuck with this for almost a week. I hope someone can help me and have a solution. Thanks in advance!

index.html

<!DOCTYPE html>
<html>
    <head>
        <title>Notities</title>
        <link href="style.css" media="screen,projection" rel="stylesheet" type="text/css"/>
        <meta content="width=device-width, initial-scale=1.0" name="viewport"/>
    </head>
    <body>
    <h1 class="center-align">Notities</h1>
    <div class="container">
        <div class="row">
    <form>
        <div>
        <select class="inputfield col s12 m6" id="notitiekleur">
        <option value="" disabled selected>Selecteer uw kleur</option>
        <option value="rood">Rood</option>
        <option value="groen">Groen</option>
        <option value="blauw">Blauw</option>
        <option value="geel">Geel</option>
        </select>
            <label>Selecteer een kleur, vul een titel en een beschrijving in</label>
        </div>
        <input class="col col s12 m6" id="notitietitel" placeholder="Vul hier de titel in">

        <input class="col col s12 m12" id="notitiebeschrijving" placeholder="Vul hier de beschrijving in">
        <button class="btn-floating btn-large waves-effect waves-light red" id="addnotities"><i class="material-icons">add</i></button>
    </form>

    <div id="notities"></div>
        </div>
    </div>
        <script src="bundle.js"></script>
        <script src="main.js"></script>
    </body>
</html>

main.js

var form = {}
form.titel = document.querySelector('#notitietitel');
form.beschrijving = document.querySelector('#notitiebeschrijving');
form.addnotitie = document.querySelector('#addnotities');
form.kleur = document.querySelector('#notitiekleur');

var notities = document.querySelector('#notities');

form.titel.focus();


function addNotitie() {
    var titel = form.titel.value;
    titel.split(/((?:\w+ ){5})/g).filter(Boolean).join("\n");
    var beschrijving = form.beschrijving.value;
    beschrijving.split(/((?:\w+ ){5})/g).filter(Boolean).join("\n");
    var notitie = document.createElement('div');
    var deleteButton = document.createElement('span');

    notitie.classList.add('notitie');
    notitie.classList.add(form.kleur.value);
    notitie.innerHTML = `<div class='notitie-titel'>${titel}
    <p class="notitie-beschrijving">${beschrijving}</p></div>`;
    deleteButton.classList.add('notitie-delete');
    deleteButton.innerHTML = '&times;';

    notitie.appendChild(deleteButton);
    notities.appendChild(notitie);

    form.titel.value = '';
    form.titel.focus();
    form.beschrijving.value = '';
    form.beschrijving.focus();

    addDeleteButton(deleteButton);
}

function addDeleteButton(deleteButton) {
    deleteButton.addEventListener('click', function (e) {
        e.stopPropagation();
        deleteNotitie(e);
    });
}

function deleteNotitie(e) {
    let eventNotitie = e.target.parentNode;
    eventNotitie.parentNode.removeChild(eventNotitie);
}


form.addnotitie.addEventListener('click', function (e) {
    e.preventDefault();
    if (form.titel.value && form.beschrijving.value != '') {
        addNotitie();
    }
});

// let itemsArray = [];
//
// localStorage.setItem('items', JSON.stringify(itemsArray));
// const data = JSON.parse(localStorage.getItem('items'));
//
// e.preventDefault();
//
// notesArray.push(form.titel.value, form.beschrijving.value, form.kleur.value);
// localStorage.setItem('items', JSON.stringify(itemsArray));
//
// data.forEach(item => {
//     addNotitie(item)
// });
//
// let notes;
//
// if (localStorage.getItem('items')) {
//     items = JSON.parse(localStorage.getItem('ítems'))
// }else {
//     items = []
// }
//
// let itemsArray = localStorage.getItem('items') ? JSON.parse(localStorage.getItem('items')) : [];
//
//

_opmaak.scss

html {
  font-size: 62.5%;
}

textarea {
  display: block;
  border-radius: 0.4rem;
}

form select,
form button {
  display: inline-block;
  height: 6rem;
}

#notities {
  display: flex;
  flex-wrap: wrap;
  padding-top: 2rem;
}

.notitie {
  width: 24rem;
  height: 20rem;
  font-size: 1.4rem;
  background: #fff;
  border-radius: 0.4rem;
  padding: 1.2rem 1.6rem;
  margin: 2.4rem 2.4rem 0 0;
  box-shadow: 0 0.9rem 1.2rem rgba(0,0,0, 0.1);
  position: relative;
}

.notitie-titel {
  height: 100%;
  font-size: 25px;
  overflow-y: auto;
}

.notitie-beschrijving {
  font-size: 15px;
  overflow-y: auto;
}

.notitie::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 0.8rem;
  border-radius: 0 0 0.4rem 0.4rem;
}

.notitie.rood {
  background-color: #ff0b00;
}

.notitie.blauw {
  background-color: #0061c8;
}
.notitie.groen {
  background-color: #89e25d;
}
.notitie.geel {
  background-color: #f0df2a;
}

.notitie span {
  position: absolute;
  width: 2rem;
  height: 2rem;
  top: 0.2rem;
  right: 0.2rem;
  border-radius: 0.4rem;
  color: #f4ffff;
  text-align: center;
}

.notitie span:hover {
  color: #ff0b00;
  background: #f4ffff;
  cursor: pointer;
}
1 Like

So it’s a challenging task you’re setting for yourself. First thing I might suggest, move your localStorage access into their own functions. It will provide you with an easier interface, and will also allow you to later (if you feel daring) use the same code in a whole new way.

For example, with the code the way you have it now, if you decide to create a back-end of some sort (firebase, or node, or whatever), you will have to ‘touch’ the entire codebase to make those changes work.

If, instead, when the user is first loading the page, the script calls loadNotes(), then it doesn’t matter where the data comes from - so long as loadNotes() returns a JSON object that looks like what you expect, you can use it with localStorage, firebase, or any other API you want to try.

By the same token, when adding a note, you simply update the JSON object (typically, simply push something onto an array), and then call saveNotes(). The implementation of saveNotes and loadNotes is hidden from the rest of the code, and easy to change.

So, with that said, here are a few suggestions:

  1. create a standard JSON object format that you will use throughout. What exactly will go into each note? Do you want a timestamp? Do you have a means of retrieving an individual note later? Is there anything else that will get saved into that JSON object?
  2. separate your concerns. addNotitie() gathers the data from the form, which works great, but then maybe have it call a function called displayNotitie(), which simply does the DOM addition. Once that’s done, call something like saveNotitie() to update the JSON object. See how that works, though? the DOM stuff is totally separate from the storage stuff, as it should be.
  3. the other reason to separate your concerns is, that displayNotitie() function? You can use that same function to display notities coming in from localStorage, just as easily as you can from the user form. But you don’t want that route to re-save the notitie each time.

All that said, if you like, I have a repl that starts from your code and handles saving and deleting notes. I am willing to give you the link to it, if you like, but I’d like to know that my notes above make sense to you first. The spoiler below contains the link to the working todo note thing.

See it on repl.it

1 Like

Thank you very much! I appreciate your help. This makes it a lot clearer and easier for me!

1 Like

Now, you’re by no means done. I did add a function to the page to allow you to create custom ID’s for the notes, so you can add more functionality! Next bit missing… can you figure how to make them editable?

1 Like

I have used your code but now I have another problem… When I want to add a note I get a error in the console that says: ‘Uncaught TypeError: Cannot read property ‘length’ of undefined at main.js:50’. It is from this line: ‘if(notitiesCollection.todos.length > 0){’. So I can’t add a new note. I’m using the framework Materialize for the design etc. When I work without the framework your code is working. Do you know how I can use your code with the framework? EDIT: Never mind haha, I had to build it first with a command in the terminal. Thanks again for your help! You explain it very well, I am very grateful for that!

Thank you for adding a new function!

I haven’t figured out yet how to change the notes.

1 Like