├── img ├── tab-bar-icon.png ├── no-data-found.png ├── search-not-found.png └── site-demo-image.png ├── README.md ├── style └── style.css ├── Untitled Diagram.drawio ├── index.html └── script └── script.js /img/tab-bar-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samarthdadhaniya/CRUD-Operation-in-LocalStorage/HEAD/img/tab-bar-icon.png -------------------------------------------------------------------------------- /img/no-data-found.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samarthdadhaniya/CRUD-Operation-in-LocalStorage/HEAD/img/no-data-found.png -------------------------------------------------------------------------------- /img/search-not-found.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samarthdadhaniya/CRUD-Operation-in-LocalStorage/HEAD/img/search-not-found.png -------------------------------------------------------------------------------- /img/site-demo-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samarthdadhaniya/CRUD-Operation-in-LocalStorage/HEAD/img/site-demo-image.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # LocalStorage CRUD Operation 3 | 4 | 5 | - CRUD operation in LocalStorage with search and sort functionality. 6 | - It is a JavaScript program that allows users to create, read, update, and delete items from a productList stored in LocalStorage. 7 | - It also includes search and sort functionality to easily find and organize products. 8 | - Users can add, edit, and delete product details, including name, price, description,and image. 9 | - The program generates an HTML code for each product card and displays them on the webpage. 10 | - This program provides an efficient way to manage and manipulate data in LocalStorage. 11 |
12 | 13 | ## :camera_flash: Screenshots 14 | 15 | ![App Screenshot](https://github.com/samarthdadhaniya/CRUD-Operation-in-LocalStorage/blob/features/img/site-demo-image.png) 16 | 17 |
18 | 19 | ## :computer: Tech Stack 20 | 21 | [![My Skills](https://skillicons.dev/icons?i=html,css,js,bootstrap,vscode,git,github,figma)](https://skillicons.dev)

22 | 23 | 24 | ## :rocket: Deployment Link 25 | 26 | - [CRUD-Operation](https://samarthdadhaniya.github.io/CRUD-Operation-in-LocalStorage/) 27 |

28 | 29 | ## :technologist: Authors 30 | 31 | - [@Samarth Dadhaniya](https://github.com/samarthdadhaniya) 32 | 33 | -------------------------------------------------------------------------------- /style/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #e2e2e2 3 | } 4 | 5 | .nav-bar 6 | { 7 | background-color: rgb(255, 255, 255); 8 | box-shadow: 1px 2px 6px 1px rgb(141, 141, 141); 9 | 10 | } 11 | 12 | .card { 13 | background-color: #fff; 14 | border: none; 15 | width: 17rem; 16 | border-radius: 5px; 17 | justify-content: space-evenly; 18 | } 19 | 20 | @media(max-width:1024px) 21 | { 22 | .card-container{ 23 | justify-content: center; 24 | } 25 | .card{ 26 | width: 16rem; 27 | } 28 | } 29 | @media(max-width:734px) 30 | { 31 | .search-bar{ 32 | width: 24rem !important; 33 | } 34 | .btn-add { 35 | width: 7rem; 36 | } 37 | .btn-del { 38 | width: 7rem; 39 | } 40 | } 41 | @media(max-width:450px) 42 | { 43 | .search-bar{ 44 | width: 22.5rem !important; 45 | } 46 | .btn-add { 47 | width: 12rem; 48 | } 49 | .btn-del { 50 | width: 9rem; 51 | } 52 | } 53 | @media(max-width:377px) 54 | { 55 | .search-bar{ 56 | width: 19rem !important; 57 | } 58 | .btn-add { 59 | width: 8.5rem; 60 | } 61 | .btn-del { 62 | width: 9rem; 63 | } 64 | } 65 | 66 | @media(max-width:322px) 67 | { 68 | .search-bar{ 69 | width: 15.8rem !important; 70 | } 71 | .btn-add { 72 | width: 7rem; 73 | } 74 | .btn-del { 75 | width: 7rem; 76 | } 77 | } 78 | 79 | .search-bar 80 | { 81 | border-radius: 4px; 82 | width: auto; 83 | border: 1px solid rgb(194, 194, 194); 84 | } 85 | 86 | .form-control { 87 | margin-top: 10px; 88 | height: 40px; 89 | border: 1px solid rgb(221, 221, 221); 90 | border-radius: 4px 91 | } 92 | 93 | .form-control-discription{ 94 | margin-top: 10px; 95 | width: 100%; 96 | text-align: top; 97 | height: 7rem; 98 | border: 2px solid #eee; 99 | border-radius: 5px 100 | } 101 | 102 | .form-control:focus { 103 | box-shadow: none; 104 | border: 1.5px solid #039BE5 105 | } 106 | 107 | .confirm-button { 108 | height: 40px; 109 | width: 100%; 110 | border-radius: 2px 111 | } 112 | 113 | .btn-danger, .btn-primary, .btn-success, .btn-secondary 114 | { 115 | justify-content: center; 116 | border-radius: 3px; 117 | } 118 | 119 | .submitButton 120 | { 121 | background-color: rgb(73, 73, 255); 122 | color: white; 123 | border-radius: 4px; 124 | } 125 | 126 | .submitButton:hover 127 | { 128 | background-color: rgb(0, 0, 207); 129 | color: white; 130 | } 131 | 132 | .img-fluid{ 133 | width: 30rem; 134 | margin-left: auto; 135 | margin-right: auto; 136 | } 137 | -------------------------------------------------------------------------------- /Untitled Diagram.drawio: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CRUD Operation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |

CRUD OPERATIONS IN LOCALSTORAGE

17 | 39 |
40 |
41 |
42 |
43 |
44 | 45 | 46 | 47 | 84 | 85 | 86 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /script/script.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @projectName - CRUD Operation in LocalStorage 3 | * 4 | * @description - CRUD operation in LocalStorage with search and sort functionality is a JavaScript program 5 | * that allows users to create, read, update, and delete items from a productList stored in 6 | * LocalStorage. It also includes search and sort functionality to easily find and organize 7 | * products. Users can add, edit, and delete product details, including name, price, description, 8 | * and image. The program generates an HTML code for each product card and displays them on the 9 | * webpage. This program provides an efficient way to manage and manipulate data in LocalStorage. 10 | * 11 | * @devloper - samarth dadhaniya 12 | * 13 | * @github - https://github.com/samarthdadhaniya/CRUD-Operation-in-LocalStorage 14 | */ 15 | 16 | /** 17 | * @function validateForm 18 | * 19 | * @description Function validates form input for name, price, description, 20 | * and image attachment, returning true if valid and false 21 | * with error message if not. 22 | * 23 | * @param none 24 | */ 25 | function validateForm() { 26 | // Get references to the form elements 27 | let nameInput = document.getElementById("name"); 28 | let priceInput = document.getElementById("price"); 29 | let descriptionInput = document.getElementById("description"); 30 | let image = document.getElementById("inputGroupFile01"); 31 | 32 | // Get the values from the input fields and remove extra white spaces. 33 | let name = nameInput.value.trim(); 34 | let price = priceInput.value.trim(); 35 | 36 | // Validate name input 37 | if (name === "") { 38 | document.getElementById("name-error-msg").innerHTML = " Please enter your name"; 39 | return false; 40 | } else { 41 | document.getElementById("name-error-msg").innerHTML = ""; 42 | } 43 | 44 | // Validate price input 45 | if (price === "") { 46 | document.getElementById("price-error-msg").innerHTML = " Please enter the price"; 47 | return false; 48 | } else { 49 | document.getElementById("price-error-msg").innerHTML = ""; 50 | } 51 | 52 | if (isNaN(price) || price.startsWith("0")) { 53 | document.getElementById("price-error-msg").innerHTML = " Please enter a valid price number that not start with zero"; 54 | return false; 55 | } 56 | else { 57 | document.getElementById("price-error-msg").innerHTML = ""; 58 | } 59 | 60 | 61 | // Validate description input 62 | if (descriptionInput.value.length > 50) { 63 | document.getElementById("disc-error-msg").innerHTML = " Description can be maximum 50 characters"; 64 | return false; 65 | } else if (descriptionInput.value == "") { 66 | document.getElementById("disc-error-msg").innerHTML = " Please enter the Discription"; 67 | return false; 68 | } else { 69 | document.getElementById("disc-error-msg").innerHTML = ""; 70 | } 71 | 72 | // Validate image input 73 | if (image.files.length === 0) { 74 | document.getElementById("image-error-msg").innerHTML = " Please attach an image"; 75 | return false; 76 | } else { 77 | document.getElementById("image-error-msg").innerHTML = "" 78 | } 79 | 80 | // regular expression for image format 81 | let allowedExtensions = /(\.jpg|\.jpeg|\.png|\.gif)$/i; 82 | if (!allowedExtensions.exec(image.files[0].name)) { 83 | document.getElementById("image-error-msg").innerHTML = " Please attach a valid image file (jpg, jpeg, png, or gif)"; 84 | image.value = ""; 85 | return false; 86 | } else { 87 | document.getElementById("image-error-msg").innerHTML = "" 88 | } 89 | 90 | // Check the file size of the uploaded image 91 | let fileSize = image.files[0].size / 1024; // in KB 92 | if (fileSize > 750) { 93 | document.getElementById("image-error-msg").innerHTML = " Please attach an image that is smaller than 750KB"; 94 | image.value = ""; 95 | return false; 96 | } 97 | else { 98 | document.getElementById("image-error-msg").innerHTML = ""; 99 | } 100 | return true; 101 | } 102 | 103 | /** 104 | * @function showData 105 | * 106 | * @description The function is retrieves the productList from localStorage, 107 | * generates HTML code for each product card, and displays them 108 | * on the webpage. It also handles empty productList and provides 109 | * options to edit and delete each product. 110 | * 111 | * @param none 112 | */ 113 | function showData() { 114 | let productList; 115 | if (localStorage.getItem("productList") == null) { 116 | productList = []; 117 | } else { 118 | productList = JSON.parse(localStorage.getItem("productList")); 119 | } 120 | let html = ""; 121 | if (productList.length === 0) { 122 | // Display an image if the productList array is empty 123 | html += `
124 |
125 |
126 |
127 | No Products 128 |
129 |
130 |
131 |
`; 132 | } else { 133 | productList.forEach(function (element, index) { 134 | html += 135 | `
136 |
137 |
138 |
139 |
140 |
141 |
Item No.- ${element.id}
142 | Image 143 |
144 |
    145 |
  • Product - ${element.name}
  • 146 |
  • Description - ${element.description}
  • 147 |
  • Price - $${element.price}
  • 148 |
149 |
150 | 151 | 152 | 153 | 154 |
155 |
156 |
157 |
158 |
159 |
`; 160 | }); 161 | } 162 | document.querySelector("#curd-table").innerHTML = html; 163 | } 164 | 165 | // Load all data when document or page load 166 | showData(); 167 | 168 | /** 169 | * @function AddData 170 | * 171 | * @description The function is adds a new product to the localStorage using 172 | * form data, generates a new ID, and reloads the page to display 173 | * the updated data. It also clears the form and displays an alert message. 174 | * 175 | * @param none 176 | */ 177 | function AddData() { 178 | if (validateForm() == true) { 179 | let name = document.getElementById("name").value; 180 | let price = document.getElementById("price").value; 181 | let description = document.getElementById("description").value; 182 | let image = document.getElementById("inputGroupFile01"); 183 | let reader = new FileReader(); 184 | 185 | let productList; 186 | if (localStorage.getItem("productList") == null) { 187 | productList = []; 188 | } else { 189 | productList = JSON.parse(localStorage.getItem("productList")); 190 | } 191 | 192 | // generate new ID by incrementing the highest existing ID 193 | let id = 1; 194 | if (productList.length > 0) { 195 | let ids = productList.map((product) => product.id); 196 | id = Math.max(...ids) + 1; 197 | } 198 | 199 | /** 200 | * @function anonymous-Function (Arrow Function) 201 | * 202 | * @description The function reads the data URL of an image file, and 203 | * adds product details to the productList and stores it 204 | * in localStorage. 205 | * 206 | * @param none 207 | */ 208 | reader.readAsDataURL(image.files[0]); 209 | reader.addEventListener("load", () => { 210 | productList.push({ 211 | id: id, 212 | name: name, 213 | description: description, 214 | price: price, 215 | image: reader.result, 216 | }); 217 | localStorage.setItem("productList", JSON.stringify(productList)); 218 | location.reload(); 219 | showData(); 220 | }); 221 | 222 | document.getElementById("name").value = ""; 223 | document.getElementById("price").value = ""; 224 | document.getElementById("description").value = ""; 225 | document.getElementById("inputGroupFile01").value = ""; 226 | document.getElementById("close-btn").click(); 227 | alert("Data Added Successfully"); 228 | } 229 | } 230 | 231 | /** 232 | * @function deleteData 233 | * 234 | * @description This function deletes an item from an array called 'productList' 235 | * and updates local storage. It also displays a confirmation message 236 | * to the user before deleting the item. 237 | * 238 | * @param index 239 | */ 240 | function deleteData(index) { 241 | let productList; 242 | if (localStorage.getItem("productList") == null) { 243 | productList = []; 244 | } else { 245 | productList = JSON.parse(localStorage.getItem("productList")); 246 | } 247 | 248 | // Display a confirmation message to the user 249 | if (confirm("Are you sure you want to delete this item?")) { 250 | productList.splice(index, 1); 251 | localStorage.setItem("productList", JSON.stringify(productList)); 252 | showData(); 253 | location.reload(); // Reload the current page 254 | } 255 | } 256 | 257 | /** 258 | * @function editData 259 | * 260 | * @description -This function edits the details of a product at a specific index. It 261 | * reads the data from local storage and updates the HTML elements with 262 | * the corresponding values. It also adds event handlers for an image and 263 | * a button to update the data. 264 | * 265 | * @param index 266 | */ 267 | function editData(index) { 268 | let productList; 269 | if (localStorage.getItem("productList") == null) { 270 | productList = []; 271 | } else { 272 | productList = JSON.parse(localStorage.getItem("productList")); 273 | } 274 | 275 | document.getElementById("id-edit").value = productList[index].id; 276 | document.getElementById("name-edit").value = productList[index].name; 277 | document.getElementById("price-edit").value = productList[index].price; 278 | document.getElementById("description-edit").value = 279 | productList[index].description; 280 | 281 | let imagePreview = document.getElementById("image-div"); 282 | imagePreview.src = productList[index].image; 283 | document.getElementById("image-div").innerHTML = 284 | ""; 285 | 286 | /** 287 | * @function anonymous-Function (Arrow Function) 288 | * 289 | * @description this function is used When the user selects an image file using the file dialog 290 | * input element, the function reads the contents of the selected file and updates 291 | * the image property of a iten object at a specific index in an array called productList. 292 | * 293 | * @param event 294 | */ 295 | let imageEdit = document.getElementById("image-edit"); 296 | imageEdit.onchange = function (event) { 297 | let file = event.target.files[0]; 298 | let reader = new FileReader(); 299 | reader.onload = function () { 300 | productList[index].image = reader.result; 301 | imagePreview.src = reader.result; 302 | }; 303 | reader.readAsDataURL(file); 304 | }; 305 | 306 | /** 307 | * @function anonymous-Function (Arrow Function) 308 | * 309 | * @description The code defines an event handler function for the onclick event of an 310 | * HTML element with an id of "update". When the user clicks on this element, 311 | * the function performs a series of actions related to updating a item's details, 312 | * and store updated details into localstorage. 313 | * 314 | * @param none 315 | */ 316 | document.querySelector("#update").onclick = function () { 317 | productList[index].id = document.getElementById("id-edit").value; 318 | productList[index].name = document.getElementById("name-edit").value; 319 | productList[index].price = document.getElementById("price-edit").value; 320 | productList[index].description = document.getElementById("description-edit").value; 321 | // this line is used to convert the array to a JSON string before it is saved to local storage. 322 | localStorage.setItem("productList", JSON.stringify(productList)); 323 | // The is method, which refreshes the page with the updated data. 324 | location.reload(); 325 | 326 | showData(); 327 | document.getElementById("id-edit").value = ""; 328 | document.getElementById("name-edit").value = ""; 329 | document.getElementById("price-edit").value = ""; 330 | document.getElementById("description-edit").value = ""; 331 | document.getElementById("close-btn").click(); 332 | alert("Data Updated Successfully"); 333 | }; 334 | } 335 | 336 | /** 337 | * @function searchBar 338 | * 339 | * @description This function is designed to search for products in a Arraylist 340 | * based on user input. It first gets the search value from an input 341 | * field with an id of "searchProductText". It then give an array of 342 | * item from the local storage using the key "productList". 343 | * 344 | * @param none 345 | */ 346 | function searchBar() { 347 | let searchvalue = document.querySelector("#serachProductText").value; 348 | console.log(searchvalue); 349 | let sortedItem = []; 350 | let sortedProduct = JSON.parse(localStorage.getItem("productList")) ?? []; 351 | let regex = new RegExp(searchvalue, "i"); 352 | for (let element of sortedProduct) { 353 | let item = element; 354 | if (regex.test(item.name)) { 355 | sortedItem.push(element); 356 | } 357 | } 358 | console.log(sortedItem); 359 | searchProduct(sortedItem); 360 | } 361 | 362 | /** 363 | * @function searchProduct 364 | * 365 | * @description This function is generates HTML code to display search 366 | * results for items. If there are no results, it displays an 367 | * image and a error message. Otherwise, it generates a card 368 | * for each product that matches the search query, 369 | * 370 | * @param sortedItem (a array format) 371 | */ 372 | function searchProduct(sortedItem) { 373 | let html = ""; 374 | console.log("searchProduct", sortedItem); 375 | if (sortedItem.length === 0) { 376 | // Display an image if the productList array is empty 377 | html += `
378 |
379 |
380 |
381 | No Products 382 |

No Similar Items Found..!

383 |
384 |
385 |
386 |
`; 387 | } else { 388 | sortedItem.forEach(function (element, index) { 389 | html += 390 | `
391 |
392 |
393 |
394 |
395 |
396 |
Item No.- ${element.id}
397 | Image 398 |
399 |
    400 |
  • Product - ${element.name}
  • 401 |
  • Description - ${element.description}
  • 402 |
  • Price - $${element.price}
  • 403 |
404 |
405 | 406 | 407 |
408 |
409 |
410 |
411 |
412 |
`; 413 | }); 414 | } 415 | document.querySelector("#curd-table").classList.add("d-none"); 416 | document.querySelector("#sort-table").innerHTML = html; 417 | } 418 | 419 | /** 420 | * @function anonymous-Function (Arrow Function) 421 | * 422 | * @description When the user selects an option from the dropdown menu of 423 | * sorting, the value of the selected option is stored in the sortBy variable. 424 | * Then, the filterProduct function is called with sortBy as its 425 | * argument to perform the sorting action based on the selected value. 426 | * 427 | * @param change (it take any event as a parameter) 428 | */ 429 | let selectElem = document.querySelector("#sort-select"); 430 | selectElem.addEventListener("change", (event) => { 431 | let sortBy = event.target.value; 432 | filterProduct(sortBy); // perform the sorting action based on the selected value 433 | if (sortBy == "refresh-btn") { 434 | location.reload(); // refresh the page 435 | } 436 | }); 437 | 438 | /** 439 | * @function filterProduct 440 | * 441 | * @description Overall, this function seems to be designed to sort an array of 442 | * products based on different criteria like (with name, id, price) 443 | * and return the sorted data. 444 | * 445 | * @param sortvalue 446 | */ 447 | function filterProduct(sortvalue) { 448 | let sortedProduct = JSON.parse(localStorage.getItem("sortedProduct")) ?? []; 449 | let productList = JSON.parse(localStorage.getItem("productList")) ?? []; 450 | sortedProduct = productList; 451 | localStorage.setItem("sortedProduct", JSON.stringify(sortedProduct)); 452 | 453 | /** 454 | * @description This code block is a conditional statement that checks 455 | * the value of the sortvalue parameter to determine the 456 | * sorting criteria to be used for the product list. 457 | */ 458 | if (sortvalue == "desc") { 459 | let desc = true; 460 | sortedProduct = sortedProduct.sort((a, b) => 461 | desc ? b.id - a.id : a.id - b.id 462 | ); 463 | desc = !desc; 464 | console.log("descending", sortedProduct); 465 | return filteredData(sortedProduct); 466 | } 467 | else if (sortvalue == "asc") { 468 | let desc = false; 469 | sortedProduct = sortedProduct.sort((a, b) => 470 | desc ? b.id - a.id : a.id - b.id 471 | ); 472 | console.log("Asc", sortedProduct); 473 | return filteredData(sortedProduct); 474 | } else if (sortvalue == "name") { 475 | sortedProduct = sortedProduct = sortedProduct.sort((a, b) => 476 | a.name.localeCompare(b.name) 477 | ); 478 | console.log("name", sortedProduct); 479 | return filteredData(sortedProduct); 480 | } else if (sortvalue == "price") { 481 | sortedProduct = sortedProduct.sort((a, b) => b.price - a.price); 482 | console.log("Price", sortedProduct); 483 | return filteredData(sortedProduct); 484 | } else { 485 | return false; 486 | } 487 | } 488 | 489 | /** 490 | * @function filteredData 491 | * 492 | * @description This is a function is takes array as a parameter. The function 493 | * generates HTML code to display the sorted products in a card format. 494 | * 495 | * @param sortedProduct (as a Array format) 496 | */ 497 | function filteredData(sortedProduct) { 498 | let html = ""; 499 | console.log("filterData", sortedProduct); 500 | if (sortedProduct.length === 0) { 501 | // This Below HTML Code Display when product list's array is Empty. 502 | html += `
503 |
504 |
505 |
506 | No Products 507 |

No products to display

508 |
509 |
510 |
511 |
`; 512 | } else { 513 | sortedProduct.forEach(function (element, index) { 514 | // This Below HTML code is generate Card For Sorted Items. 515 | html += `
516 |
517 |
518 |
519 |
520 |
521 |
Item No.- ${element.id}
522 | Image 523 |
524 |
    525 |
  • Product - ${element.name}
  • 526 |
  • Description - ${element.description}
  • 527 |
  • Price - $${element.price}
  • 528 |
529 |
530 | 531 | 532 |
533 |
534 |
535 |
536 |
537 |
`; 538 | }); 539 | } 540 | document.querySelector("#curd-table").classList.add("d-none"); 541 | document.querySelector("#sort-table").innerHTML = html; 542 | } --------------------------------------------------------------------------------