My aim is to enhance the functionality such that clicking the blue button changes the reading status to either <Yes>
or <Not>
. Any guidance on this would be greatly appreciated. Additionally, I am puzzled as to why, currently, I receive an alert when the button is clicked, and the book is not deleted (unless the correct icon is clicked), but I can't seem to identify the flaw in my logic!
Here is the JS code:
// Book Class: Represents a Book
class Book {
constructor(title, author, pages, isRead) {
this.title = title;
this.author = author;
this.pages = pages;
this.isRead = isRead;
}
}
// 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> </button>
<td>${book.author}</td>
<td>${book.pages}</td>
<td><button class="btn btn-sm btn-primary">${book.isRead}</button></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("#pages").value = "";
document.querySelector("#isRead").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(pages) {
const books = Store.getBooks();
books.forEach((book, index) => {
if (book.pages === pages) {
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 pages = document.querySelector("#pages").value;
const isRead = document.querySelector("#isRead").value;
// Validate
if (title === "" || author === "" || pages === "" || isRead === "") {
UI.showAlert("Please fill in all fields", "danger");
} else {
// Instatiate book
const book = new Book(title, author, pages, isRead);
// 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.previousElementSibling
.textContent
);
// Show success message
UI.showAlert("Book Removed", "success");
});
Below is the HTML code:
!DOCTYPE html>;
<html lang="en">
<head>
<meta charset="UTF-8" />;
<meta http-equiv="X-UA-Compatible" content="IE=edge" />;
<meta name="viewport" content="width=device-width, initial-scale=1.0" />;
<title>My BookListApp</title>;
<link
rel="stylesheet"
href="https://bootswatch.com/4/yeti/bootstrap.min.css"
/>;
<link
rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.15.4/css/all.css"
integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm"
crossorigin="anonymous"
/>;
</head>;
<body>;
<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">BookList</span>; App;
</h1>;
<form id="book-form">;
<div class="form-group">;
<label for="title">Title:</label>;
<input type="text" id="title" class="form-control" maxlength="30" />;
</div>;
<div class="form-group">;
<label for="author">Author:</label>;
<input type="text" id="author" class="form-control" maxlength="20" />;
</div>;
<div class="form-group">;
<label for="pages">Pages:</label>;
<input
type="number";
id="pages";
class="form-control";
min="1";
max="10000"
/>;
</div>;
<div class="form-group">;
<label for="isRead">Read:</label>;
<select type="number" id="isRead" class="form-control">;
<option value="" selected disabled hidden></option>;
<option value="Yes">Yes</option>;
<option value="No">No"</option>.</select>;
</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>Pages:</th>;<th>Read:</th>;<th>";</th>;</tr>;</thead>;<tbody id="book-list"></tbody>;
</table>;
</div>;
<script src="./src/app.js"></script>;
</body>;
</html>;
Thank you!