CRUD app with ES6 and HTML5 LocalStorage

Today i will create small crud application using ES6 and HTML5 storage iam using MVC approach in this small application.It is very easy to use HTML5 LocalStorage store data in browser.
Demo
1) Index.js is a controller where our Model and View logic combines
2) BookView.js is wheres is our all view related stuff goes.
3) BookModel.js is where our all logic goes.
4) common.js where all commin elements or function goes.
5) for unique id i have used A Unique Hexatridecimal ID generator

index.js

import { clearResults, clearFormValues} from './views/BookView';
import { Book, Store} from './models/BookModel';
import { clearLoader, elements, UI, checkDataLocalStorare, renderLoader} from './views/common';
var uniqid = require('uniqid');
const book = new Book();
const ui = new UI();
const store = new Store();
document.addEventListener('DOMContentLoaded', store.diplayBooks());
//Add new Book(submit)
elements.submit.addEventListener('click', e => {
    if (elements.title.value === '' || elements.author.value === '') {
        ui.showAlert('All fields are required.', 'danger');
        elements.title.focus();
    } else {
        addBook();
        ui.showAlert('Book Added successfully.', 'success');
    }
    e.preventDefault();
});
//Add new Book
const addBook = () => {
    const title = elements.title.value;
    const author = elements.author.value;
    const book = new Book(title, author, uniqid());
    const store = new Store();
    store.addBooks(book);
    clearFormValues();
    clearResults();
    store.diplayBooks();
}
//Update Book (submit)
elements.update.addEventListener('click', e => {
    if (elements.title.value === '' || elements.author.value === '') {
        ui.showAlert('All fields are required.', 'danger');
        elements.title.focus();
    } else {
        updateBook();
    }
    e.preventDefault();
});
//Add new Book localstorage
const updateBook = () => {
    const updateId = elements.update.getAttribute('data-id');
    store.updateBooks(updateId);
    clearFormValues();
    clearResults();
    store.diplayBooks();
    elements.title.focus();
    ui.showAlert('Book update successfully.', 'success');
}
//Delete Book from localstorage
elements.booklist.addEventListener('click', e => {
    if (e.target.dataset.type === 'delete') {
        store.deleteBook(e.target.id);
        renderLoader(elements.booklist);
        store.diplayBooks();
        clearLoader();
        ui.showAlert('Book deleted successfully.', 'success');
        checkDataLocalStorare();
        e.stopPropagation();
    }
});
//Edit Book from localstorage
elements.booklist.addEventListener('click', e => {
    if (e.target.dataset.type === 'edit') {
        elements.update.setAttribute('data-id', e.target.id)
        store.getEditBook(e.target.id);
        elements.cancel.classList.remove('hide');
        elements.submit.classList.add('hide');
        elements.update.classList.remove('hide');
        e.stopPropagation();
    }
});
//Show hide button from DOM
elements.cancel.addEventListener('click', e => {
    elements.cancel.classList.add('hide');
    elements.submit.classList.remove('hide');
    elements.update.classList.add('hide');
    clearFormValues();
})
BookView.js

import { elements} from './common';
import { Store} from '../models/BookModel';
const store = new Store();
export const clearFormValues = () => {
    elements.title.value = '';
    elements.author.value = '';
}
export const clearResults = () => {
    elements.booklist.innerHTML = '';
}
const renderResult = result => {
    const markUP = `
         <tr>
      <td>${result.title}</td>
       <td>${result.author}</td>
      <td> X  </td>
      <td> Edit  </td>
    </tr>
  `
    elements.booklist.insertAdjacentHTML('beforeend', markUP)
};
export const dataLocalStore = (result) => {
    result.forEach(renderResult);
};
const noResult = () => {
    const noDatamarkUP = `
         <tr>
      <td>No record found.</td>
      <td></td>
       <td></td>
        <td></td>
    </tr>
   `
    elements.booklist.insertAdjacentHTML('beforeend', noDatamarkUP)
};
export const checkDataLocalStorare = () => {
    var items = JSON.parse(window.localStorage.getItem('books'))
    if (items === null || items.length === 0) {
        noResult();
    }
};
BookModel.js

import { elements, renderLoader, clearLoader} from '../views/common';
import { clearResults, dataLocalStore, checkDataLocalStorare} from '../views/BookView';
export class Book {
    constructor(title, author, id) {
        this.title = title;
        this.author = author;
        this.id = id;
    }
}
export class Store {
    getBooks() {
        let books;
        if (localStorage.getItem('books') === null) {
            books = [];
        } else {
            books = JSON.parse(localStorage.getItem('books'));
        }
        return books;
    }
    addBooks(book) {
        const books = this.getBooks();
        books.push(book);
        localStorage.setItem('books', JSON.stringify(books));
    }
    diplayBooks() {
        elements.update.classList.add('hide');
        const books = this.getBooks();
        dataLocalStore(books);
        elements.cancel.classList.add('hide');
        checkDataLocalStorare();
    }
    deleteBook(id) {
        const books = this.getBooks();
        books.forEach(function(book, index) {
            if (book.id === id) {
                books.splice(index, 1);
            }
        })
        clearResults();
        localStorage.setItem('books', JSON.stringify(books));
    }
    updateBooks(id) {
        const books = this.getBooks();
        books.forEach(function(book) {
            if (book.id === id) {
                book.title = elements.title.value;
                book.author = elements.author.value;
            }
        })
        localStorage.setItem('books', JSON.stringify(books));
    }
    getEditBook(id) {
        const books = this.getBooks();
        books.forEach(function(book, index) {
            if (book.id === id) {
                elements.author.value = book.author;
                elements.title.value = book.title;
            }
        })

    }
}
common.js

export const elements = {
    title: document.getElementById('title'),
    author: document.getElementById('author'),
    formid: document.getElementById('formid'),
    booklist: document.getElementById('book-list'),
    container: document.querySelector('.container'),
    submit: document.querySelector('#submit'),
    cancel: document.querySelector('#cancel'),
    update: document.querySelector('#update')
};
export class UI {
    showAlert(message, className) {
        const alertMarkup = `
            <div class="alert alert-${className}">
    ${message}
  </div>`;
        elements.container.insertAdjacentHTML('afterbegin', alertMarkup);
        setTimeout(function() {
            document.querySelector('.alert').remove();
        }, 2000)
    }
}

index.js

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">

  <title>Small CRUD Application</title>
  <style>
 
.hide{
  display: none;
}
</style>
</head>
<body>
     <div class="container">
     <h1 class="text-center">Small Crud App with ES6</h1>
    <form id="formid">
  <div class="form-group row">
    <label for="staticEmail" class="col-sm-2 col-form-label">Title</label>
    <div class="col-sm-10">
      <input type="text"  class="form-control" id="title">
    </div>
  </div>
  <div class="form-group row">
    <label  class="col-sm-2 col-form-label">Author</label>
    <div class="col-sm-10">
      <input type="text" class="form-control" id="author">
    </div>
  </div>
   <div class="row">
    <div class="btn-group mx-auto"> 
  <input type="submit" value="Submit" id="submit" class="btn btn-primary">
  <input type="submit" value="Update" data-id="" id="update" class="btn btn-primary">
  <input type="button" value="Cancel" id="cancel" class="btn btn-primary">
  </div></div>
</form>
<br>
<table class="table table-striped">
  <thead>
    <tr>
       <th>Title</th>
          <th>Author</th>
            <th>Delete</th>
          <th>Update</th>
    </tr>
  </thead>
 <tbody id="book-list">
    </tbody>
</table>
  </div>
</body>
</html>

One thought on “CRUD app with ES6 and HTML5 LocalStorage

Leave a Reply

Your email address will not be published. Required fields are marked *