Please pardon my writing skills,i just started out recently.
Note: You can also build this app or create it's functionality using Angular or any other framework/library.
App Description: A simple browser based note app which allows you to create and store your notes probably for later purpose.
App Idea: FreeCodeCamp
**App Repo: ** Link
Before we move on lets just list out it features.
The user can create a note
The user can edit a note
The user can delete a note.
How is this going to work ?
After a User creates a note or edits a note, when closing the browser window the notes are stored and when the User returns the notes gets retrieved.
So a User:
Adds or creates a note by clicking on a button.
Edits a note by clicking or focus on a note.
Saves note by clicking outside of that note.
Deletes note by clicking on a delete button.
More like performing crud operation but this time lets see how we can use the browsers' storage to perform this operation,lets get started.
HTML
First what are the things we need on the web page
An area or card which will serve as the note.
Few Buttons like add and delete.
<div class="container">
<div class="notes">
<div class="note">
<div class="note-header">
<div class="header-content">Tue Jun 25 2019</div>
<div class="header-content">
<i class="fa fa-edit"></i>
<i class="fa fa-trash"></i>
</div>
</div>
<div class="note-body">
<div class="note-area"></div>
</div>
</div>
</div>
<div class="add-note">
<i class="fa fa-plus fa-1x"></i>
</div>
</div>
Lets talk about the code above.
So we created a markup of the app by adding some few html codes
we have the .container
class which will serve as a wrapper to other page content alongside that we have the .notes
class which will serve as a parent container to the notes. The .note
class will be generated dynamically by JavaScript depending on the number of notes created by a user, so we are gonna move that to our JavaScript code in a moment.
Next we have the .add-note
class which is the add button.
Before we jump into styling the app lets just work on the JavaScript part first.
JavaScript
Before i drop down codes lets list out some few things we are going to do with JavaScript.
First thing we want to do is to be able to add notes
Display Notes.
Update notes and save notes
Delete notes
Be able to retrieve notes if notes exists when a user returns to the browser.
With this in mind i think we ready to drop some codes. But first since we going to be making use of the browsers storage won't it be nice we first check if it available for us to use.
https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API
const storageAvailable = (type) => {
let storage;
try {
storage = window[type];
const x = '__storage_test__';
storage.setItem(x,x);
storage.removeItem(x);
return true;
} catch (e) {
return e instanceof DOMException && (
// everything except Firefox
e.code === 22 ||
// Firefox
e.code === 1014 ||
// test name field too, because code might not be present
// everything except Firefox
e.name === 'QuotaExceededError' ||
// Firefox
e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
// acknowledge QuotaExceededError only if there's something already stored
(storage && storage.length !== 0);
}
}
The function above will help us check if storage is both supported and available for us to use . if we have storage available it return true
else an Exception
. notice we can use this function to check for any storage type available for us to use e.g we can use it to check for sessionStorage
, localStorage
.
Here we are making use of the localStorage so we check like this
if (storageAvailable('localStorage')) {
// we place our code here if we have storage available to us
}
else {
// here you can pass a message
}
Finally.
Adding Notes
if (storageAvailable('localStorage')) {
// added an event listener to the add note button
document.querySelector('.add-note').addEventListener('click',()=>{
// get notes content
const notesItem = localStorage.getItem('notes'),newNotes = {};
let notes = [];
newNotes.createdOn = Date.now();
newNotes.text = ' ';
///check if notes not null and not empty
if (notesItem !== null && notesItem !=='' ) {
/// if not null and not empty run this
notes = JSON.parse(notesItem);
}
//
notes.push(newNotes);
localStorage.setItem('notes',JSON.stringify(notes));
});
Lets break the code above down
First checked if storage is available and supported,if it is we use it.
Next we placed an event listener to the
add-note
button onclick
Next we declared some few variables and assigned values to them
const notesContent =
This stores the item we get fromlocalStorage
.The reason we did this is to be able to check if the user has already created or have other notes stored and we don't get to overide them instead we add to them.const newNotes =
declares or create an object, this is because we intend to store this items as key/value pair in localStorage.let notes =
an empty array which will help store our objects.Notice we using thelet
key word here? The reason is because we are going to change it values later on our code.
We created our Object key and value pair
newNotes.createdOn
\=Date.now()
which gets your current timestamp andnewNotes.text=
empty string.Next we checked if notes has already been initially created before by checking if it not
null
and empty,iftrue
we assign the items to thenotes
variable.Next we push or append the newNotes Object into the empty array using
notes.push(newNotes)
Note*
if we tend to store our data just by having the localStorage.setItem()
set just the array or object like this localStorage.setItem('notes',notes)
what we will have stored for us will be this [object object]
string which we can't use when we retrieve it.Note* you can store integers,strings,booleans in localStorage
with no problems.
with that in mind how do we store our object or array and retrieve them?.
To store the object or array we first convert it to a string which can easily be done with JSON.stringify()
e.g JSON.stringify(notes)
.With this we can retrieve our objects nicely and be able to use them by constructing the object described or stored as a string like this JSON.parse(notesItem);
Display Notes.
Now we want to create the elements we need and have them inserted into the div.notes
in our HTML code. So we are going to have to edit or add some codes in the click event listener which will create those needed elements and have them displayed to the user after clicking the add-note
button.
document.querySelector('.add-note').addEventListener('click',()=>{
const notesItem = localStorage.getItem('notes'),newNotes = {};
let notes = [];
newNotes.createdOn = Date.now();
newNotes.text = ' ';
if (notesItem !== null && notesItem !=='') {
notes = JSON.parse(notesItem);
}
notes.push(newNotes);
localStorage.setItem('notes',JSON.stringify(notes));
const childDiv = document.createElement('div');
childDiv.setAttribute('class','note note-'+newNotes.createdOn);
const parentDiv = document.querySelector('.notes')
parentDiv.insertBefore(childDiv,parentDiv.childNodes[0]);
const noteBody = document.getElementsByClassName('note');
noteBody[0].innerHTML = noteContentArea(newNotes);
document.getElementsByClassName('note-area')[0].contentEditable = true;
});
lets talk about it
First created the
childDiv
set theclass
attribute andvalue
Got the
parentDiv
and usedinsertBefore()
method to insert thechildDiv
we created before every other child element of theparentDiv
Next we made the
noteBody
by getting the note byclass
name having itinnerHTML
to be thenoteContentArea
which is a function created in other for us to reuse it or repeat ourselves.
Here is the function
const noteContentArea= (note) => {
const dateTime = new Date(note.createdOn);
let content = '<div class="note-header"><div class="header-content">'+ dateTime.toDateString() +'</div>';
content +='<div class="header-content"><i class="fa fa-edit icon-'+note.createdOn+'"></i><i class="fa fa-trash" onclick="deleteNote('+note.createdOn+')"></i>';
content +='</div></div> <div class="note-body"> <div class="note-area" onblur="update(this)" id="'+note.createdOn+'">'+note.text+'</div></div>';
return content;
}
All we did was to have the other relevant elements in a function noteContentArea
passed some contents from the note
parameter and also some other attributes onclick
which will handle the deletion of the notes whenever the trash icon is clicked and onblur
which will save the note or update the note when the user clicks outside the note area.
- After all that we made the
note-area
editable using contentEditable property Learn More
** Update And Save Note**
const update = (div) => {
const text = div.innerHTML;
const getNotes = JSON.parse(localStorage.getItem('notes'));
const updatedNotes = [];
getNotes.forEach(note =>{
if (note.createdOn == div.id) {
note.text = text;
updatedNotes.push(note);
} else {
updatedNotes.push(note);
}
});
localStorage.setItem('notes',JSON.stringify(updatedNotes));
const icon =document.querySelector('.icon-'+div.id);
setTimeout(()=>{
icon.setAttribute('class','fa fa-edit icon-'+div.id);
icon.style.color = '#000';
},3000);
icon.setAttribute('class','fa fa-check icon-'+div.id);
icon.style.color = '#00C851';
}
We created a variable to help us hold the content of the HTML element which we made editable
const text
Get the previously stored notes
const getNotes
Created an empty array which will store the updated note
Next we looped through the getNotes array to get the specific note which is been updated using the control statement
Using the control statement what we did was to check if the note item key
createdOn
which we are using as a primary key in the getNotes array is same with the current note been edited.So if it is same we assign the new value of the HTML element been edited which we have stored intext
variable tonote.text
and we push to the empty arrayupdatedNotes.push(note)
and else it is not same we just push the item into the empty array.Next we save the newly edited item in the browser's storage
localStorage.setItem('notes',JSON.stringify(updatedNotes));
and wrote some codes to help switch the icons .
** Delete Notes **
const deleteNote = (timestamp) => {
const getNoteItems = JSON.parse(localStorage.getItem('notes'));
notesArr = [];
getNoteItems.forEach(note =>{
if (note.createdOn !== timestamp) {
notesArr.push(note);
}
});
localStorage.setItem('notes',JSON.stringify(notesArr));
let node = document.getElementsByClassName('note-'+timestamp);
if (node[0].parentNode) {
node[0].parentNode.removeChild(node[0]);
}
}
So what we did in the delete note function is similar only this time after getting and looping through the items we check if the note key
createdOn
not same with the current one been deleted,if it is not we have the items stored in thenoteArr
and also have it stored on the browser's storagelocalStorage.setItem('notes',JSON.stringify(notesArr))
,that way we don't have the already deleted items saved in the browsers storage and also retrieved when the user returns .Next we removed it from the DOM by invoking the removeChild method on the parentNode of the element been gotten by class name
node
.node[0].parentNode.removeChild(node[0]);
Retrieve Notes
notes = JSON.parse(localStorage.getItem('notes'));
if( notes !== null ) {
notes.reverse();
let i = 0;
notes.forEach(note => {
const cards = document.createElement('div');
cards.setAttribute('class','note note-'+note.createdOn);
document.querySelector('.notes').appendChild(notes);
const card = document.getElementsByClassName('note');
card[i].innerHTML = cardContent(note);
document.getElementsByClassName('note-area')[i].contentEditable = true;
i++;
});
}
Similar to what we did on Display Note but this time after getting the note from our browsers storage we first check if it not null or not empty.
if it meets our conditions we loop through each items and create the elements on the DOM based on the items we have in the
notes
array.
Note : You can place the above code in the window.onload
function to display to the user when or after the user returns to the browser or reloads the browser.
So i guess that will be it. Oh as for the CSS you can get the source code on the link below or actually just apply your own styling to the element following the Demo design pattern or just create yours.
**Source Code : ** here
Possible Features You Might Want To implement
Have Users make or write note in markdown format
Have the notes stored somewhere other than the browser's storage.
Finally friends we done.