A Pen by Brad Traversy on CodePen.
Created
February 3, 2020 06:25
-
-
Save ahmed-issa-mohd/613665ad2c1463ac1eb14586efd0906b to your computer and use it in GitHub Desktop.
JavaScript BookList App
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="container mt-4"> | |
<h1 class="display-4 text-center"> | |
<i class="fas fa-book-open text-primary"></i> My<span class="text-primary">Book</span>List</h1> | |
<form id="book-form"> | |
<div class="form-group"> | |
<label for="title">Title</label> | |
<input type="text" id="title" class="form-control"> | |
</div> | |
<div class="form-group"> | |
<label for="author">Author</label> | |
<input type="text" id="author" class="form-control"> | |
</div> | |
<div class="form-group"> | |
<label for="isbn">ISBN#</label> | |
<input type="text" id="isbn" class="form-control"> | |
</div> | |
<input type="submit" value="Add Book" class="btn btn-primary btn-block"> | |
</form> | |
<table class="table table-striped mt-5"> | |
<thead> | |
<tr> | |
<th>Title</th> | |
<th>Author</th> | |
<th>ISBN#</th> | |
<th></th> | |
</tr> | |
</thead> | |
<tbody id="book-list"></tbody> | |
</table> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Book Class: Represents a Book | |
class Book { | |
constructor(title, author, isbn) { | |
this.title = title; | |
this.author = author; | |
this.isbn = isbn; | |
} | |
} | |
// UI Class: Handle UI Tasks | |
class UI { | |
static displayBooks() { | |
const books = Store.getBooks(); | |
books.forEach((book) => UI.addBookToList(book)); | |
} | |
static addBookToList(book) { | |
const list = document.querySelector('#book-list'); | |
const row = document.createElement('tr'); | |
row.innerHTML = ` | |
<td>${book.title}</td> | |
<td>${book.author}</td> | |
<td>${book.isbn}</td> | |
<td><a href="#" class="btn btn-danger btn-sm delete">X</a></td> | |
`; | |
list.appendChild(row); | |
} | |
static deleteBook(el) { | |
if(el.classList.contains('delete')) { | |
el.parentElement.parentElement.remove(); | |
} | |
} | |
static showAlert(message, className) { | |
const div = document.createElement('div'); | |
div.className = `alert alert-${className}`; | |
div.appendChild(document.createTextNode(message)); | |
const container = document.querySelector('.container'); | |
const form = document.querySelector('#book-form'); | |
container.insertBefore(div, form); | |
// Vanish in 3 seconds | |
setTimeout(() => document.querySelector('.alert').remove(), 3000); | |
} | |
static clearFields() { | |
document.querySelector('#title').value = ''; | |
document.querySelector('#author').value = ''; | |
document.querySelector('#isbn').value = ''; | |
} | |
} | |
// Store Class: Handles Storage | |
class Store { | |
static getBooks() { | |
let books; | |
if(localStorage.getItem('books') === null) { | |
books = []; | |
} else { | |
books = JSON.parse(localStorage.getItem('books')); | |
} | |
return books; | |
} | |
static addBook(book) { | |
const books = Store.getBooks(); | |
books.push(book); | |
localStorage.setItem('books', JSON.stringify(books)); | |
} | |
static removeBook(isbn) { | |
const books = Store.getBooks(); | |
books.forEach((book, index) => { | |
if(book.isbn === isbn) { | |
books.splice(index, 1); | |
} | |
}); | |
localStorage.setItem('books', JSON.stringify(books)); | |
} | |
} | |
// Event: Display Books | |
document.addEventListener('DOMContentLoaded', UI.displayBooks); | |
// Event: Add a Book | |
document.querySelector('#book-form').addEventListener('submit', (e) => { | |
// Prevent actual submit | |
e.preventDefault(); | |
// Get form values | |
const title = document.querySelector('#title').value; | |
const author = document.querySelector('#author').value; | |
const isbn = document.querySelector('#isbn').value; | |
// Validate | |
if(title === '' || author === '' || isbn === '') { | |
UI.showAlert('Please fill in all fields', 'danger'); | |
} else { | |
// Instatiate book | |
const book = new Book(title, author, isbn); | |
// Add Book to UI | |
UI.addBookToList(book); | |
// Add book to store | |
Store.addBook(book); | |
// Show success message | |
UI.showAlert('Book Added', 'success'); | |
// Clear fields | |
UI.clearFields(); | |
} | |
}); | |
// Event: Remove a Book | |
document.querySelector('#book-list').addEventListener('click', (e) => { | |
// Remove book from UI | |
UI.deleteBook(e.target); | |
// Remove book from store | |
Store.removeBook(e.target.parentElement.previousElementSibling.textContent); | |
// Show success message | |
UI.showAlert('Book Removed', 'success'); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<link href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" rel="stylesheet" /> | |
<link href="https://bootswatch.com/4/yeti/bootstrap.min.css" rel="stylesheet" /> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment