Thursday, November 30, 2023
HomeVideo EditingEasy methods to Construct a CRUD Net Utility with Vanilla JavaScript

Easy methods to Construct a CRUD Net Utility with Vanilla JavaScript


On this tutorial, we’ll be constructing a CRUD utility within the type of a observe taking app. We’ll additionally discover how you can use native storage to avoid wasting notes in our browser.

What’s CRUD?

Chances are you’ll already be questioning: “what does CRUD imply?!” A CRUD utility is the commonest type of any software program utility. CRUD stands for Create, Learn, Replace and Delete and it applies to any software program that’s able to letting customers create and examine information on its interface, in addition to make modifications to, and delete current information.

CRUD purposes can vary from a easy to-do checklist utility to a extra advanced social media platform. It’s additionally frequent for builders to construct CRUD purposes to show their grasp of a selected framework or language.

1. Creating the Markup

For our markup, we’ll have two foremost parts: the new-note container that comprises the enter and textual content space subject for coming into the content material for our notes, and the notes-wrapper container that’ll include the created notes. We even have a form-error div for displaying error messages and a button that calls the addNote() perform we’ll outline later.

1
<foremost>
2
  <div class="new-note">
3
    <enter kind="textual content" identify="title" id="title" placeholder="Title">
4
    <textarea identify="content material" id="content material" placeholder="Begin writing"></textarea>
5
    <div id="form-error"></div>
6
  </div>
7
  <div class="button-container">
8
    <button class="add-btn" onclick="addNote()">Add observe</button>
9
  </div>
10
  <div id="notes-wrapper"></div>
11
</foremost>

2. Styling the Structure

That is the CSS for our preliminary format:

1
.new-note {
2
  margin-bottom: 32px;
3
  background-color: white;
4
  border: 1px strong #dadada;
5
  border-radius: 6px;
6
  padding: 16px;
7
  place: relative;
8
}
9
10
.new-note enter {
11
  width: 100%;
12
  background: clear;
13
  border: none;
14
  define: none;
15
  font-size: 1.5rem;
16
  font-weight: 700;
17
  padding: 0 0 12px;
18
}
19
20
.new-note textarea {
21
  show: block;
22
  width: 100%;
23
  min-height: 100px;
24
  border: none;
25
  resize: none;
26
  background: clear;
27
  define: none;
28
  padding: 0;
29
}
30
31
#form-error {
32
  colour: #b33030;
33
  place: absolute;
34
  backside: -32px;
35
  left: 0;
36
}
37
38
.button-container {
39
  show: flex;
40
  justify-content: middle;
41
  margin-bottom: 32px;
42
}
43
44
.add-btn {
45
  border: 1px strong rgb(95, 95, 95);
46
  background-color: clear;
47
  transition: background-color 250ms, colour 250ms;
48
  border-radius: 16px;
49
  cursor: pointer;
50
  padding: 8px 12px;
51
}
52
53
.add-btn:hover {
54
  background-color: rgb(95, 95, 95);
55
  colour: white;
56
}
57
58
#notes-wrapper {
59
  show: flex;
60
  flex-direction: column;
61
  hole: 32px;
62
}
63
64
.observe {
65
  place: relative;
66
  overflow: hidden;
67
  background: white;
68
  border: 1px strong #dadada;
69
  border-radius: 6px;
70
  padding: 16px;
71
}
72
73
.note-title {
74
  font-size: 1.5em;
75
  font-weight: 700;
76
  margin-bottom: 12px;
77
  width: 100%;
78
  show: inline-block;
79
  overflow-wrap: break-word;
80
  white-space: pre-wrap;
81
}
82
83
.note-title:last-child {
84
  margin-bottom: 0;
85
}
86
87
.note-text {
88
  margin-bottom: 16px;
89
  background-color: white;
90
  width: 100%;
91
  overflow-wrap: break-word;
92
  white-space: pre-wrap;
93
  background-color: white;
94
  overflow: hidden;
95
  width: 100%;
96
}
97
98
.note-date {
99
  font-size: 0.75em;
100
  text-align: proper;
101
  border-top: 1px strong #dadada;
102
  padding-top: 16px;
103
  width: 100%;
104
  margin-top: auto;
105
}
106
107
.note-controls {
108
  place: absolute;
109
  proper: 0;
110
  prime: 0;
111
  background-color: white;
112
  font-size: 0.75rem;
113
  column-gap: 8px;
114
  padding: 8px;
115
  show: flex;
116
  opacity: 0;
117
  transition: opacity 350ms;
118
}
119
120
.observe:hover .note-controls,
121
.note-controls:focus-within {
122
  opacity: 1;
123
}
124
125
.note-controls button {
126
  padding: 0;
127
  border: none;
128
  background-color: clear;
129
  cursor: pointer;
130
  padding: 0.5rem;
131
}
132
133
.note-controls button:hover {
134
  filter: brightness(0.85)
135
}
136
137
.note-delete {
138
  colour: #bb0000;
139
}
140
141
.note-edit {
142
  colour: #00bb00;
143
}
144
145
.note-save {
146
  colour: #0000bb;
147
}
148
149
.note-save[disabled="true"] {
150
  colour: #dfdfdf;
151
  pointer-events: none;
152
  user-select: none;
153
  cursor: not-allowed;
154
}

On this demo, we’ve eliminated the define styling on our enter and textarea fields to keep away from interfering with the styling. Nevertheless, if you want, you possibly can depart the define styling for accessibility functions.

That is what our format seems to be like at the moment:

our note taking app demoour note taking app demoour note taking app demo

3. Creating and Studying Information

Now we are able to begin engaged on the logic of our utility!

International Parts

First, let’s get all the worldwide parts we’ll want.

1
const notesWrapper = doc.getElementById("notes-wrapper");
2
const title = doc.getElementById("title");
3
const content material = doc.getElementById("content material");
4
const error = doc.getElementById("form-error");

Then we’ll outline a worldwide variable to retailer our notes information.

Creating and Storing Information

As a way to create the info, we’ll outline an addNote() perform to be known as when the button is clicked. That is what’s going to deal with taking the info from the enter subject and placing them into a brand new observe component in a readable format.

To start with, we’ll embody a situation to verify if there’s any content material to be added in a brand new observe. If each the title and content material subject are empty, we’ll show an error message.

1
const addNote = () => {
2
  if (title.worth.trim().size == 0 && content material.worth.trim().size == 0) {
3
    error.innerText = "Observe can't be empty";
4
    return;
5
  }
6
};

Subsequent, we create an object to include the date for a brand new observe. On this tutorial, we’ll be producing a novel id (uid) worth for every observe utilizing the date.getTime() methodology. This returns the precise millisecond the observe was created and is used to ensure that no two notes have the identical id.

We’ll even be together with the date worth of when the observe was created utilizing the date.toLocaleDateString() methodology. That is what our up to date perform seems to be like:

1
const noteObj = {
2
    uid: new Date().getTime().toString(),
3
    title: title.worth,
4
    textual content: content material.worth,
5
    date: new Date().toLocaleDateString()
6
};

Now that now we have the observe object, we are able to retailer that information within the notesData array and in addition within the browser localStorage

1
notesData.push(noteObj);
2
localStorage.setItem("notes", JSON.stringify(notesData));

localStorage solely helps information in string format so we use the JSON.stringify() methodology to transform our array into an acceptable format.

Displaying Information

Let’s outline a perform createNote() to deal with appending the brand new observe to the notesWrapper container. The observe component will show the title, content material and date based mostly on consumer enter. It should even have an edit, save and delete button for finishing up the corresponding capabilities based mostly on the observe distinctive id.

1
const createNote = (uid, title, textual content, date) => {
2
  const observe = doc.createElement("div");
3
  observe.className = "observe";
4
  observe.id = uid;
5
  observe.innerHTML = `
6
    <div class="note-title">${title}</div>
7
    <div class="note-controls">
8
      <button class="note-edit" onclick="editNote(${uid})">
9
        Edit
10
      </button>
11
      <button class="note-save" fashion="show:none" onclick="saveNote(${uid})">
12
        Save
13
      </button>
14
      <button class="note-delete" onclick="deleteNote(${uid})">
15
        Delete
16
      </button>
17
    </div>
18
    <div class="note-text">${textual content}</div>
19
    <div class="note-date">${date}</div>
20
  `;
21
22
  notesWrapper.insertBefore(observe, notesWrapper.firstChild);
23
};

On this perform, we use the .insertBefore() methodology to ensure that the latest observe in positioned on the prime of the notesWrapper container.

Reset the Title and Content material for Subsequent Observe

Lastly, we are able to replace our addNote() perform to create a brand new observe and in addition reset the title, content material and error parts when the button is clicked.

1
const addNote = () => {
2
  if (title.worth.trim().size == 0 && content material.worth.trim().size == 0) {
3
    error.innerText = "Observe can't be empty";
4
    return;
5
  }
6
7
  const noteObj = {
8
    uid: new Date().getTime().toString(),
9
    title: title.worth,
10
    textual content: content material.worth,
11
    date: new Date().toLocaleDateString()
12
  };
13
  
14
  createNote(noteObj.uid, noteObj.title, noteObj.textual content, noteObj.date);
15
16
  error.innerText = "";
17
  content material.worth = "";
18
  title.worth = "";
19
};

Test for Present Information

Since we’re utilizing localStorage, we are able to additionally embody a situation to verify if there’s already current information for our notes in localStorage and show that on the web page as soon as the web page masses. The JSON.parse() methodology is used to transform our stringified information again to its authentic format.

1
window.addEventListener("load", () => {
2
  notesData = localStorage.getItem("notes")
3
    ? JSON.parse(localStorage.getItem("notes"))
4
    : [];
5
    
6
  notesData.forEach((observe) => {
7
    createNote(observe.uid, observe.title, observe.textual content, observe.date);
8
  });
9
});

4. Updating Information

At this level, we’ve dealt with the “C” and “R” elements of CRUD, having managed to efficiently create notes based mostly on consumer enter, and show current notes. Now let’s flip our consideration to “U” by defining a perform that lets us edit and save (replace) an current observe.

Modifying..

Once we outlined out createNote() perform, we included two button parts to deal with modifying and saving a observe based mostly on a novel id so now we are able to create the editNote() and saveNote() capabilities. When the edit button is clicked, we’ll cover the edit button and show the save button:

1
const editNote = (uid) => {
2
  const observe = doc.getElementById(uid);
3
4
  const noteTitle = observe.querySelector(".note-title");
5
  const noteText = observe.querySelector(".note-text");
6
  const noteSave = observe.querySelector(".note-save");
7
  const noteEdit = observe.querySelector(".note-edit");
8
9
  noteTitle.contentEditable = "true";
10
  noteText.contentEditable = "true";
11
  noteEdit.fashion.show = "none";
12
  noteSave.fashion.show = "block";
13
  noteText.focus();
14
};

On this perform, we use the uid to search out the observe component within the DOM. Then we goal the title and textual content parts contained in the goal observe and use the contentEditable methodology to permit us make modifications to the content material. contentEditable is an inbuilt browser attribute that enables a consumer change the content material of any component if set to true.

We are able to replace our CSS to incorporate styling on the observe component when modifying.

1
.observe > *[contenteditable="true"] {
2
  colour: #5f5f5f;
3
  width: 100%;
4
  define: none;
5
}

..and Resaving

For our saveNote() perform, we’ll have to replace our notesData worth and localStorage information. We are able to do that utilizing the .forEach() methodology to search out the observe that has the corresponding uid and replace the content material. Then we’ll push our up to date array into localStorage to interchange the previous worth.

1
  notesData.forEach((observe) => {
2
    if (observe.uid == uid) {
3
      observe.title = noteTitle.innerText;
4
      observe.textual content = noteText.innerText;
5
    }
6
  });
7
8
  localStorage.setItem("notes", JSON.stringify(notesData));

Then we’ll use the identical logic because the editNote() perform, solely this time we’ll be setting the contentEditable attributes to false and hiding the save button whereas displaying the edit button. We’ll additionally use the identical situation we utilized in our addNote() perform to ensure customers can’t save a clean observe.

1
const saveNote = (uid) => {
2
  const observe = doc.getElementById(uid);
3
4
  const noteTitle = observe.querySelector(".note-title");
5
  const noteText = observe.querySelector(".note-text");
6
  const noteSave = observe.querySelector(".note-save");
7
  const noteEdit = observe.querySelector(".note-edit");
8
9
  if (
10
    noteTitle.innerText.trim().size == 0 &&
11
    noteText.worth.trim().size == 0
12
  ) {
13
    error.innerHTML = "Observe can't be empty";
14
    return;
15
  }
16
17
  notesData.forEach((observe) => {
18
    if (observe.uid == uid) {
19
      observe.title = noteTitle.innerText;
20
      observe.textual content = noteText.innerText;
21
    }
22
  });
23
24
  localStorage.setItem("notes", JSON.stringify(notesData));
25
26
  noteTitle.contentEditable = "false";
27
  noteText.contentEditable = "false";
28
  noteEdit.fashion.show = "block";
29
  noteSave.fashion.show = "none";
30
  error.innerText = "";
31
};

5. Deleting Information

And lastly, the “D” a part of CRUD.

For the ultimate implementation of our utility, we’ll be dealing with deleting information. For this perform, we’ll take away the observe component from the DOM and in addition delete the observe object from our notesData array. We are able to deal with eradicating the article from the array by utilizing the .filter() methodology.

1
const deleteNote = (uid) => {
2
  let confirmDelete = affirm("Are you positive you need to delete this observe?");
3
  if (!confirmDelete) {
4
    return;
5
  }
6
7
  const observe = doc.getElementById(uid);
8
  observe.parentNode.removeChild(observe);
9
  
10
  notesData = notesData.filter((observe) => {
11
    return observe.uid != uid;
12
  });
13
  localStorage.setItem("notes", JSON.stringify(notesData));
14
};

One of many advantages of constructing an online utility is that we are able to benefit from current browser options. This perform makes use of the affirm() methodology to show an inbuilt modal that may deal with confirming consumer enter, with out the necessity to constructed a customized modal and detect a response ourselves.

Conclusion

And that’s that! What we’ve simply coded was advanced sufficient to be difficult, but easy sufficient to grasp, and the proper demonstration of CRUD. We’ve carried out the fundamental operations of a software program utility utilizing vanilla JavaScript (properly carried out).

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments