I'm currently making a Library project, and I made it so that each book entered is stored in an array (in this case, the array is myLibrary). Then I made it so that each book in the array creates a new div with the class of "card." I've implemented a "Remove Button" for each card, but I'm not sure as to how I can make the button delete the book from the array. Any help would be appreciated, thank you.
I've tried
const remBtn = document.createElement("button");
card.appendChild(remBtn);
remBtn.textContent = "Remove";
remBtn.onclick = remBook;
// Remove book function
function remBook() {
const findBook = myLibrary.findIndex((element) => element === book);
const delBook = myLibrary.slice(findBook, 1);
}
Here are my codes:
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>Library</title>
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<div >Library</div>
<form id="submitInput" action="">
<label for="title">Title:</label>
<input type="text" id="formTitle" name="title" required />
<label for="author">Author:</label>
<input type="text" id="formAuthor" name="author" required />
<label for="page">Page:</label>
<input type="text" id="formPage" name="page" required />
<div >
<label for="read">Read</label>
<input type="checkbox" id="formRead" name="read" value="" />
</div>
<input type="submit" id="submitBtn" value="Add Book" />
</form>
<div ></div>
</body>
<script src="./script.js"></script>
</html>
JS:
// Data inputs
let myLibrary = [
{
title: "test",
author: "test",
page: "123",
read: true,
},
];
// Object constructor
function book(title, author, page, read) {
this.title = title;
this.author = author;
this.page = page;
this.read = read;
}
// Add new books to library
function addBookToLibrary() {
let a = document.getElementById("formTitle").value;
let b = document.getElementById("formAuthor").value;
let c = document.getElementById("formPage").value;
let d = document.getElementById("formRead").checked;
if (a !== "" && b !== "" && c !== "") {
myLibrary.push(new book(a, b, c, d));
}
}
const submit = document.getElementById("submitInput");
submit.addEventListener("submit", () => {
event.preventDefault();
addBookToLibrary();
submit.reset();
displayBooks();
});
// Display each book as cards
function displayBooks() {
const currentDisplay = document.querySelector(".currentDisplay");
currentDisplay.textContent = "";
myLibrary.forEach((myLibrary) => {
let card = document.createElement("div");
card.classList.add("card");
currentDisplay.appendChild(card);
for (let key in myLibrary) {
const text = document.createElement("p");
text.textContent = `${key}: ${myLibrary[key]}`;
card.appendChild(text);
}
const readBtn = document.createElement("button");
card.appendChild(readBtn);
if (myLibrary.read === true) {
readBtn.textContent = "Read";
}
if (myLibrary.read === false) {
readBtn.textContent = "Not Read";
}
readBtn.addEventListener("click", () => {
if (readBtn.textContent === "Read") {
readBtn.textContent = "Not Read";
myLibrary.read = false;
} else if (readBtn.textContent === "Not Read") {
readBtn.textContent = "Read";
myLibrary.read = true;
}
});
const remBtn = document.createElement("button");
card.appendChild(remBtn);
remBtn.textContent = "Remove";
remBtn.onclick = remBook;
});
}
// Remove book function
function remBook() {
const findBook = myLibrary.findIndex((element) => element === book);
const delBook = myLibrary.slice(findBook, 1);
}
displayBooks();
CodePudding user response:
First let's give each Book object a unique property.
// Object constructor
function Book(title, author, page, read) {
this.bookId = `book${ Book.id}`;
this.title = title;
this.author = author;
this.page = page;
this.read = read;
}
//static property
Book.id = 0;
While rendering a book we use the bookId property as class name for the div. This will be used for deleting the element.
card.classList.add(`${myLibrary.bookId}`);
Inside remove book function, we find the book using bookId property. we use the splice method to remove an element from array. Then we call the remove method on div element to delete the div.
// Remove book function
function remBook() {
const bookId = this.parentElement.classList[1];
const findBook = myLibrary.findIndex(
(element) => element.bookId === bookId
);
const delBook = myLibrary.splice(findBook, 1);
this.parentElement.remove();
}
// Data inputs
let myLibrary = [{
title: 'test',
author: 'test',
page: '123',
read: true,
}, ];
// Object constructor
function Book(title, author, page, read) {
this.bookId = `book${ Book.id}`;
this.title = title;
this.author = author;
this.page = page;
this.read = read;
}
//static property
Book.id = 0;
// Add new books to library
function addBookToLibrary() {
let a = document.getElementById('formTitle').value;
let b = document.getElementById('formAuthor').value;
let c = document.getElementById('formPage').value;
let d = document.getElementById('formRead').checked;
if (a !== '' && b !== '' && c !== '') {
myLibrary.push(new Book(a, b, c, d));
}
}
const submit = document.getElementById('submitInput');
submit.addEventListener('submit', () => {
event.preventDefault();
addBookToLibrary();
submit.reset();
displayBooks();
});
// Display each book as cards
function displayBooks() {
const currentDisplay = document.querySelector('.currentDisplay');
currentDisplay.textContent = '';
myLibrary.forEach((myLibrary) => {
let card = document.createElement('div');
card.classList.add('card');
card.classList.add(`${myLibrary.bookId}`);
currentDisplay.appendChild(card);
for (let key in myLibrary) {
const text = document.createElement('p');
text.textContent = `${key}: ${myLibrary[key]}`;
card.appendChild(text);
}
const readBtn = document.createElement('button');
card.appendChild(readBtn);
if (myLibrary.read === true) {
readBtn.textContent = 'Read';
}
if (myLibrary.read === false) {
readBtn.textContent = 'Not Read';
}
readBtn.addEventListener('click', () => {
if (readBtn.textContent === 'Read') {
readBtn.textContent = 'Not Read';
myLibrary.read = false;
} else if (readBtn.textContent === 'Not Read') {
readBtn.textContent = 'Read';
myLibrary.read = true;
}
});
const remBtn = document.createElement('button');
card.appendChild(remBtn);
remBtn.textContent = 'Remove';
remBtn.onclick = remBook;
});
}
// Remove book function
function remBook() {
const bookId = this.parentElement.classList[1];
const findBook = myLibrary.findIndex(
(element) => element.bookId === bookId
);
const delBook = myLibrary.splice(findBook, 1);
this.parentElement.remove();
}
displayBooks();
<div >Library</div>
<form id="submitInput" action="">
<label for="title">Title:</label>
<input type="text" id="formTitle" name="title" required />
<label for="author">Author:</label>
<input type="text" id="formAuthor" name="author" required />
<label for="page">Page:</label>
<input type="text" id="formPage" name="page" required />
<div >
<label for="read">Read</label>
<input type="checkbox" id="formRead" name="read" value="" />
</div>
<input type="submit" id="submitBtn" value="Add Book" />
</form>
<div ></div>
CodePudding user response:
I think you can add specific ids whenever you add a new card. And call the card classes using querySelectorAll. That will return you a nodelist. Loop that nodelist and check if the specific id that you are click right now match with the looped element's id. If true, you can do your stuffs in that loop cuz whatever you're doing will only apply to the button that you're clicking.
I made a sample here. By the way, I used JSON to check the condition in string state.
function remBook(obj) {
let card = document.querySelectorAll(".card");
for(let x=0; x<card.length; x ) {
if(JSON.stringfy(card[y].id) === JSON.stringfy(obj.id) {
/* You can do your stuff here using index */
}
}
}