From 2a52309def9f57aa01e304d051b90a4ccba1ef61 Mon Sep 17 00:00:00 2001 From: Martin Mwaka Date: Wed, 5 Aug 2026 09:02:07 +0100 Subject: [PATCH 1/7] script.js - fix issues - 1. page rendering 2. delete button 3. book add console 4. correct was read message --- debugging/book-library/script.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index 75ce6c1d..b4020df4 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -38,7 +38,7 @@ function submit() { return false; } else { let book = new Book(title.value, title.value, pages.value, check.checked); - library.push(book); + myLibrary.push(book); render(); } } @@ -54,7 +54,7 @@ function render() { let table = document.getElementById("display"); let rowsNumber = table.rows.length; //delete old table - for (let n = rowsNumber - 1; n > 0; n-- { + for (let n = rowsNumber - 1; n > 0; n--) { table.deleteRow(n); } //insert updated row and cells @@ -77,9 +77,9 @@ function render() { wasReadCell.appendChild(changeBut); let readStatus = ""; if (myLibrary[i].check == false) { - readStatus = "Yes"; - } else { readStatus = "No"; + } else { + readStatus = "Yes"; } changeBut.innerText = readStatus; @@ -90,11 +90,12 @@ function render() { //add delete button to every row and render again let delButton = document.createElement("button"); - delBut.id = i + 5; - deleteCell.appendChild(delBut); - delBut.className = "btn btn-warning"; - delBut.innerHTML = "Delete"; - delBut.addEventListener("clicks", function () { + delButton.id = i + 5; + deleteCell.appendChild(delButton); + delButton.className = "btn btn-warning"; + delButton.innerHTML = "Delete"; + delButton.addEventListener("click", function () { + console.log("Deleting..."); alert(`You've deleted title: ${myLibrary[i].title}`); myLibrary.splice(i, 1); render(); From 0baa0bf64a254f920eb4c3947b7cc21902f15729 Mon Sep 17 00:00:00 2001 From: Martin Mwaka Date: Wed, 5 Aug 2026 09:12:55 +0100 Subject: [PATCH 2/7] index.html - set html lang=en and remove onclick submit() from input submit as this should be done in JavaScript --- debugging/book-library/index.html | 145 ++++++++++++------------------ 1 file changed, 56 insertions(+), 89 deletions(-) diff --git a/debugging/book-library/index.html b/debugging/book-library/index.html index 23acfa71..0eb09684 100644 --- a/debugging/book-library/index.html +++ b/debugging/book-library/index.html @@ -1,96 +1,63 @@ - - - - - - - - - - + - -
-

Library

-

Add books to your virtual library

-
+ + + + + + + + + + + +
+

Library

+

Add books to your virtual library

+
- + -
-
- - - - - - - - -
+
+
+ + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + +
TitleAuthorNumber of PagesRead
- - - - - - - - - - - - - - - - - - - -
TitleAuthorNumber of PagesRead
+ + - - - + \ No newline at end of file From 2799fa73308e8383ccc8674d800a14472a3aef2d Mon Sep 17 00:00:00 2001 From: Martin Mwaka Date: Wed, 5 Aug 2026 10:25:11 +0100 Subject: [PATCH 3/7] script.js - 1. move all global variables to top of page 2. add submitButton variable and eventListener --- debugging/book-library/script.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index b4020df4..3ccdb670 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -1,3 +1,9 @@ +const title = document.getElementById("title"); +const author = document.getElementById("author"); +const pages = document.getElementById("pages"); +const check = document.getElementById("check"); +const submitButton = document.querySelector(".btn-primary"); + let myLibrary = []; window.addEventListener("load", function (e) { @@ -20,14 +26,9 @@ function populateStorage() { } } -const title = document.getElementById("title"); -const author = document.getElementById("author"); -const pages = document.getElementById("pages"); -const check = document.getElementById("check"); - //check the right input from forms and if its ok -> add the new book (object in array) //via Book function and start render function -function submit() { +submitButton.addEventListener("click", () => { if ( title.value == null || title.value == "" || @@ -41,7 +42,7 @@ function submit() { myLibrary.push(book); render(); } -} +}); function Book(title, author, pages, check) { this.title = title; From 948930a81618a790755eaaf13edf93197aae9c9b Mon Sep 17 00:00:00 2001 From: Martin Mwaka Date: Wed, 5 Aug 2026 10:25:46 +0100 Subject: [PATCH 4/7] small update --- debugging/book-library/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index 3ccdb670..0d504d6e 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -52,6 +52,7 @@ function Book(title, author, pages, check) { } function render() { + console.log(myLibrary); let table = document.getElementById("display"); let rowsNumber = table.rows.length; //delete old table @@ -96,7 +97,6 @@ function render() { delButton.className = "btn btn-warning"; delButton.innerHTML = "Delete"; delButton.addEventListener("click", function () { - console.log("Deleting..."); alert(`You've deleted title: ${myLibrary[i].title}`); myLibrary.splice(i, 1); render(); From cfbfb131bf958e0c4905bc36e9f41cfa98cc5ee4 Mon Sep 17 00:00:00 2001 From: Martin Mwaka Date: Fri, 7 Aug 2026 11:25:18 +0100 Subject: [PATCH 5/7] update index.html - correct errors and add a table template - script.js - update to accept populate table from fragment and refactor to make content easier to understand - style.css - add css for delete book message --- debugging/book-library/index.html | 93 ++++++------ debugging/book-library/script.js | 226 +++++++++++++++++++----------- debugging/book-library/style.css | 77 +++++++++- 3 files changed, 272 insertions(+), 124 deletions(-) diff --git a/debugging/book-library/index.html b/debugging/book-library/index.html index 0eb09684..d83c6da2 100644 --- a/debugging/book-library/index.html +++ b/debugging/book-library/index.html @@ -2,7 +2,7 @@ - + Book Library @@ -12,50 +12,55 @@ -
-

Library

-

Add books to your virtual library

-
- - - -
-
- - - - - - - - -
-
- - - - - - - - - - + +
+
+
+

Library

+

Add books to your virtual library

+
+ + + +
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + + +
+
+
+ +
diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index 0d504d6e..764c83ee 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -1,8 +1,20 @@ +class Book { + constructor(title, author, pages, check) { + this.title = title; + this.author = author; + this.pages = pages; + this.check = check; + } +} + +const form = document.getElementById("add-book"); +const submitBtn = document.getElementById("submit-button"); const title = document.getElementById("title"); const author = document.getElementById("author"); const pages = document.getElementById("pages"); const check = document.getElementById("check"); -const submitButton = document.querySelector(".btn-primary"); +const displayBooks = document.querySelector(".display-books"); +const demo = document.getElementById("demo"); let myLibrary = []; @@ -12,94 +24,150 @@ window.addEventListener("load", function (e) { }); function populateStorage() { - if (myLibrary.length == 0) { - let book1 = new Book("Robison Crusoe", "Daniel Defoe", "252", true); - let book2 = new Book( - "The Old Man and the Sea", - "Ernest Hemingway", - "127", - true + if (myLibrary.length === 0) { + myLibrary.push(new Book("Robison Crusoe", "Daniel Defoe", "252", true)); + myLibrary.push( + new Book("The Old Man and the Sea", "Ernest Hemingway", "127", true) ); - myLibrary.push(book1); - myLibrary.push(book2); render(); } } -//check the right input from forms and if its ok -> add the new book (object in array) -//via Book function and start render function -submitButton.addEventListener("click", () => { - if ( - title.value == null || - title.value == "" || - pages.value == null || - pages.value == "" - ) { - alert("Please fill all fields!"); - return false; - } else { - let book = new Book(title.value, title.value, pages.value, check.checked); +// form submission event listeners - add new books +form.addEventListener("submit", (event) => { + event.preventDefault(); + processEntries(); +}); + +// book field validations +const fields = { + title: { + input: title, + error: document.querySelector(".error-title"), + message: "Title is required", + }, + author: { + input: author, + error: document.querySelector(".error-author"), + message: "Author is required", + }, + pages: { + input: pages, + error: document.querySelector(".error-pages"), + message: "Enter page numbers (whole numbers only)", + }, +}; + +Object.values(fields).forEach(({ input, error }) => { + input.addEventListener("input", () => { + if (input.value.trim() !== "") { + error.textContent = ""; + } + }); +}); + +// check book entry is valid before adding to library +function processEntries() { + let isValid = true; + + Object.entries(fields).forEach(([key, field]) => { + const value = field.input.value.trim(); + + if (value === "") { + field.error.textContent = field.message; + isValid = false; + } else { + field.error.textContent = ""; + } + }); + + if (isValid) { + let book = new Book(title.value, author.value, pages.value, check.checked); myLibrary.push(book); + demo.classList.remove("show"); render(); + form.reset(); } -}); +} + +const createBookRow = (book, index) => { + const { title, author, pages, check: hasBeenRead } = book; + const row = document.createElement("tr"); + + const titleCell = document.createElement("td"); + const authorCell = document.createElement("td"); + const pagesCell = document.createElement("td"); + const readCell = document.createElement("td"); + const deleteCell = document.createElement("td"); + + titleCell.textContent = title; + authorCell.textContent = author; + pagesCell.textContent = pages; + + const readButton = document.createElement("button"); + readButton.className = `btn btn-sm ${hasBeenRead ? "btn-success" : "btn-secondary"}`; + readButton.textContent = hasBeenRead ? "Yes" : "No"; + readButton.style.color = "black"; + readCell.appendChild(readButton); -function Book(title, author, pages, check) { - this.title = title; - this.author = author; - this.pages = pages; - this.check = check; + const deleteButton = document.createElement("button"); + deleteButton.className = "btn btn-sm btn-warning"; + deleteButton.textContent = "Delete"; + deleteCell.appendChild(deleteButton); + + readButton.addEventListener("click", () => toggleReadStatus(index)); + + deleteButton.addEventListener("click", () => deleteBook(index)); + + row.append(titleCell, authorCell, pagesCell, readCell, deleteCell); + return row; +}; + +function toggleReadStatus(index) { + myLibrary[index].check = !myLibrary[index].check; + render(); +} + +function deleteBook(index) { + bookDeleteMessage(`You've deleted title: ${myLibrary[index].title}`); + myLibrary.splice(index, 1); + render(); +} + +function bookDeleteMessage(message, duration = 3000) { + const existingMessage = document.querySelector(".book-delete-message"); + if (existingMessage) existingMessage.remove(); + + const messageBox = document.createElement("div"); + messageBox.className = "book-delete-message"; + messageBox.textContent = message; + document.body.appendChild(messageBox); + + setTimeout(() => { + messageBox.remove(); + }, duration); } function render() { - console.log(myLibrary); - let table = document.getElementById("display"); - let rowsNumber = table.rows.length; - //delete old table - for (let n = rowsNumber - 1; n > 0; n--) { - table.deleteRow(n); - } - //insert updated row and cells - let length = myLibrary.length; - for (let i = 0; i < length; i++) { - let row = table.insertRow(1); - let titleCell = row.insertCell(0); - let authorCell = row.insertCell(1); - let pagesCell = row.insertCell(2); - let wasReadCell = row.insertCell(3); - let deleteCell = row.insertCell(4); - titleCell.innerHTML = myLibrary[i].title; - authorCell.innerHTML = myLibrary[i].author; - pagesCell.innerHTML = myLibrary[i].pages; - - //add and wait for action for read/unread button - let changeBut = document.createElement("button"); - changeBut.id = i; - changeBut.className = "btn btn-success"; - wasReadCell.appendChild(changeBut); - let readStatus = ""; - if (myLibrary[i].check == false) { - readStatus = "No"; - } else { - readStatus = "Yes"; - } - changeBut.innerText = readStatus; - - changeBut.addEventListener("click", function () { - myLibrary[i].check = !myLibrary[i].check; - render(); - }); - - //add delete button to every row and render again - let delButton = document.createElement("button"); - delButton.id = i + 5; - deleteCell.appendChild(delButton); - delButton.className = "btn btn-warning"; - delButton.innerHTML = "Delete"; - delButton.addEventListener("click", function () { - alert(`You've deleted title: ${myLibrary[i].title}`); - myLibrary.splice(i, 1); - render(); - }); - } + displayBooks.innerHTML = ""; + + const table = document.createElement("table"); + table.className = "table table-striped"; + + const thead = document.createElement("thead"); + const headerRow = document.createElement("tr"); + ["Title", "Author", "Pages", "Read", "Delete"].forEach((label) => { + const th = document.createElement("th"); + th.textContent = label; + headerRow.appendChild(th); + }); + thead.appendChild(headerRow); + table.appendChild(thead); + + const tbody = document.createElement("tbody"); + const bookRows = myLibrary.map((book, index) => createBookRow(book, index)); + tbody.append(...bookRows); + table.appendChild(tbody); + + displayBooks.appendChild(table); } diff --git a/debugging/book-library/style.css b/debugging/book-library/style.css index 302950cb..f98aad67 100644 --- a/debugging/book-library/style.css +++ b/debugging/book-library/style.css @@ -1,8 +1,9 @@ .form-group { width: 400px; - height: 300px; + min-height: 360px; align-self: left; padding-left: 20px; + padding-bottom: 20px; } .btn { @@ -16,4 +17,78 @@ button.btn-info { margin: 20px; + color: black; +} + +.display-books table { + width: 100%; + margin-top: 20px; + border-collapse: collapse; +} + +.display-books th, +.display-books td { + padding: 0.75rem; + border: 1px solid #dee2e6; + text-align: left; + vertical-align: middle; +} + +.display-books thead th { + background-color: #343a40; + color: white; +} + +.display-books tbody tr:nth-child(even) { + background-color: #f8f9fa; +} + +.display-books .book-delete { + color: #dc3545; + font-weight: 600; +} + +.display-books .book-read { + font-weight: 600; +} + +.display-books .book-read .btn, +.display-books .book-delete .btn { + width: 100%; + max-width: 90px; +} + +.form-control.is-invalid { + border-color: #dc3545; + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} + +.invalid-feedback { + display: none; + color: #dc3545; + font-size: 0.875rem; + margin-bottom: 0.5rem; +} + +.invalid-feedback.show { + display: block; +} + +/* error messages */ +.error { + color: red; + font-size: 0.8rem; +} + +.book-delete-message { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: #ff7f7f; + color: white; + padding: 1rem 2rem; + border-radius: 6px; + z-index: 1000; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); } From e971cda851f30889bf12a6161f232617a12a4691 Mon Sep 17 00:00:00 2001 From: Martin Mwaka Date: Sat, 8 Aug 2026 09:47:57 +0100 Subject: [PATCH 6/7] update index.html --- debugging/book-library/index.html | 39 +++++++++++++++++-------------- debugging/book-library/script.js | 25 ++++++++++---------- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/debugging/book-library/index.html b/debugging/book-library/index.html index d83c6da2..d3580b08 100644 --- a/debugging/book-library/index.html +++ b/debugging/book-library/index.html @@ -3,22 +3,25 @@ Book Library - + + - - + +
@@ -36,33 +39,33 @@

Library

- +
- +
- +
-
- - + + +
-
+
- + \ No newline at end of file diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index 764c83ee..86822575 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -7,20 +7,19 @@ class Book { } } -const form = document.getElementById("add-book"); +const addBookForm = document.getElementById("add-book"); const submitBtn = document.getElementById("submit-button"); -const title = document.getElementById("title"); -const author = document.getElementById("author"); -const pages = document.getElementById("pages"); -const check = document.getElementById("check"); +const titleInput = document.getElementById("title"); +const authorInput = document.getElementById("author"); +const pagesInput = document.getElementById("pages"); +const checkInput = document.getElementById("check"); const displayBooks = document.querySelector(".display-books"); -const demo = document.getElementById("demo"); +const bookEntryTab = document.getElementById("demo"); let myLibrary = []; window.addEventListener("load", function (e) { populateStorage(); - render(); }); function populateStorage() { @@ -34,7 +33,7 @@ function populateStorage() { } // form submission event listeners - add new books -form.addEventListener("submit", (event) => { +addBookForm.addEventListener("submit", (event) => { event.preventDefault(); processEntries(); }); @@ -42,17 +41,17 @@ form.addEventListener("submit", (event) => { // book field validations const fields = { title: { - input: title, + input: titleInput, error: document.querySelector(".error-title"), message: "Title is required", }, author: { - input: author, + input: authorInput, error: document.querySelector(".error-author"), message: "Author is required", }, pages: { - input: pages, + input: pagesInput, error: document.querySelector(".error-pages"), message: "Enter page numbers (whole numbers only)", }, @@ -84,9 +83,9 @@ function processEntries() { if (isValid) { let book = new Book(title.value, author.value, pages.value, check.checked); myLibrary.push(book); - demo.classList.remove("show"); + bookEntryTab.classList.remove("show"); render(); - form.reset(); + addBookForm.reset(); } } From 0e2ea0a2d6b0c1902113daa881fe30db37635654 Mon Sep 17 00:00:00 2001 From: Martin Mwaka Date: Sun, 9 Aug 2026 09:50:21 +0100 Subject: [PATCH 7/7] update my code to fix issues highlighted by volunteer review --- debugging/book-library/index.html | 38 ++++--- debugging/book-library/script.js | 168 +++++++++++++++++------------- debugging/book-library/style.css | 18 ++-- 3 files changed, 126 insertions(+), 98 deletions(-) diff --git a/debugging/book-library/index.html b/debugging/book-library/index.html index d3580b08..835b300f 100644 --- a/debugging/book-library/index.html +++ b/debugging/book-library/index.html @@ -13,17 +13,6 @@ -
@@ -39,29 +28,44 @@

Library

- +
- +
- +
-
-
+
TitleAuthorNumber of PagesRead
+ + + + + + + + + + + + +
TitleAuthorPagesReadDelete
+ diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index 86822575..bfa6edf4 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -7,37 +7,27 @@ class Book { } } -const addBookForm = document.getElementById("add-book"); +const addBook = document.getElementById("add-book"); const submitBtn = document.getElementById("submit-button"); const titleInput = document.getElementById("title"); const authorInput = document.getElementById("author"); const pagesInput = document.getElementById("pages"); const checkInput = document.getElementById("check"); -const displayBooks = document.querySelector(".display-books"); +const displayBooks = document.getElementById("display-books"); const bookEntryTab = document.getElementById("demo"); -let myLibrary = []; +const myLibrary = []; -window.addEventListener("load", function (e) { - populateStorage(); -}); - -function populateStorage() { +function initLibrary() { if (myLibrary.length === 0) { - myLibrary.push(new Book("Robison Crusoe", "Daniel Defoe", "252", true)); + myLibrary.push(new Book("Robison Crusoe", "Daniel Defoe", 252, true)); myLibrary.push( - new Book("The Old Man and the Sea", "Ernest Hemingway", "127", true) + new Book("The Old Man and the Sea", "Ernest Hemingway", 127, true) ); render(); } } -// form submission event listeners - add new books -addBookForm.addEventListener("submit", (event) => { - event.preventDefault(); - processEntries(); -}); - // book field validations const fields = { title: { @@ -56,17 +46,57 @@ const fields = { message: "Enter page numbers (whole numbers only)", }, }; +// validate that pages input is a whole number +function validatePagesInput() { + const rawValue = pagesInput.value.trim(); + const isValidPages = + rawValue !== "" && /^\d+$/.test(rawValue) && Number(rawValue) >= 1; + + if (!isValidPages) { + fields.pages.error.textContent = "Enter page numbers (whole numbers only)"; + return false; + } + + fields.pages.error.textContent = ""; + return true; +} Object.values(fields).forEach(({ input, error }) => { input.addEventListener("input", () => { - if (input.value.trim() !== "") { + if (input === pagesInput) { + if (validatePagesInput()) { + error.textContent = ""; + } + } else if (input.value.trim() !== "") { error.textContent = ""; } }); + + // replace browser's invalid event with bespoke error messages for inputs + input.addEventListener("invalid", (event) => { + event.preventDefault(); + const fieldInput = Object.values(fields).find( + (field) => field.input === input + ); + if (fieldInput) { + // use bespoke error message from fields object + error.textContent = fieldInput.message; + } else { + // only use default browser error message if there is no bespoke error message + error.textContent = input.validationMessage; + } + }); }); -// check book entry is valid before adding to library -function processEntries() { +// check book entries are valid before adding to library +function processEntries(event) { + event.preventDefault(); + // override browser default error messages so that my default error messages can show + if (!addBook.checkValidity()) { + addBook.reportValidity(); + return; + } + let isValid = true; Object.entries(fields).forEach(([key, field]) => { @@ -80,48 +110,24 @@ function processEntries() { } }); + if (!validatePagesInput()) { + isValid = false; + } + if (isValid) { - let book = new Book(title.value, author.value, pages.value, check.checked); + let book = new Book( + titleInput.value, + authorInput.value, + pagesInput.value, + checkInput.checked + ); myLibrary.push(book); bookEntryTab.classList.remove("show"); render(); - addBookForm.reset(); + addBook.reset(); } } -const createBookRow = (book, index) => { - const { title, author, pages, check: hasBeenRead } = book; - const row = document.createElement("tr"); - - const titleCell = document.createElement("td"); - const authorCell = document.createElement("td"); - const pagesCell = document.createElement("td"); - const readCell = document.createElement("td"); - const deleteCell = document.createElement("td"); - - titleCell.textContent = title; - authorCell.textContent = author; - pagesCell.textContent = pages; - - const readButton = document.createElement("button"); - readButton.className = `btn btn-sm ${hasBeenRead ? "btn-success" : "btn-secondary"}`; - readButton.textContent = hasBeenRead ? "Yes" : "No"; - readButton.style.color = "black"; - readCell.appendChild(readButton); - - const deleteButton = document.createElement("button"); - deleteButton.className = "btn btn-sm btn-warning"; - deleteButton.textContent = "Delete"; - deleteCell.appendChild(deleteButton); - - readButton.addEventListener("click", () => toggleReadStatus(index)); - - deleteButton.addEventListener("click", () => deleteBook(index)); - - row.append(titleCell, authorCell, pagesCell, readCell, deleteCell); - return row; -}; - function toggleReadStatus(index) { myLibrary[index].check = !myLibrary[index].check; render(); @@ -147,26 +153,44 @@ function bookDeleteMessage(message, duration = 3000) { }, duration); } -function render() { - displayBooks.innerHTML = ""; +function createBookRow(book, index) { + const row = document.createElement("tr"); - const table = document.createElement("table"); - table.className = "table table-striped"; + const titleCell = document.createElement("td"); + titleCell.textContent = book.title; - const thead = document.createElement("thead"); - const headerRow = document.createElement("tr"); - ["Title", "Author", "Pages", "Read", "Delete"].forEach((label) => { - const th = document.createElement("th"); - th.textContent = label; - headerRow.appendChild(th); - }); - thead.appendChild(headerRow); - table.appendChild(thead); + const authorCell = document.createElement("td"); + authorCell.textContent = book.author; + + const pagesCell = document.createElement("td"); + pagesCell.textContent = book.pages; + + const readCell = document.createElement("td"); + const readButton = document.createElement("button"); + readButton.className = `btn btn-sm ${book.check ? "btn-success" : "btn-secondary"}`; + readButton.textContent = book.check ? "Yes" : "No"; + readButton.style.color = "black"; + readButton.addEventListener("click", () => toggleReadStatus(index)); + readCell.appendChild(readButton); + + const deleteCell = document.createElement("td"); + const deleteButton = document.createElement("button"); + deleteButton.className = "btn btn-sm btn-warning"; + deleteButton.textContent = "Delete"; + deleteButton.addEventListener("click", () => deleteBook(index)); + deleteCell.appendChild(deleteButton); - const tbody = document.createElement("tbody"); - const bookRows = myLibrary.map((book, index) => createBookRow(book, index)); - tbody.append(...bookRows); - table.appendChild(tbody); + row.append(titleCell, authorCell, pagesCell, readCell, deleteCell); + return row; +} - displayBooks.appendChild(table); +function render() { + displayBooks.innerHTML = ""; + + const rows = myLibrary.map((book, index) => createBookRow(book, index)); + displayBooks.append(...rows); } + +// event listeners +addBook.addEventListener("submit", processEntries); +window.addEventListener("DOMContentLoaded", initLibrary); diff --git a/debugging/book-library/style.css b/debugging/book-library/style.css index f98aad67..bd6577a8 100644 --- a/debugging/book-library/style.css +++ b/debugging/book-library/style.css @@ -20,40 +20,40 @@ button.btn-info { color: black; } -.display-books table { +#book-table { width: 100%; margin-top: 20px; border-collapse: collapse; } -.display-books th, -.display-books td { +#book-table th, +#book-table td { padding: 0.75rem; border: 1px solid #dee2e6; text-align: left; vertical-align: middle; } -.display-books thead th { +#book-table thead th { background-color: #343a40; color: white; } -.display-books tbody tr:nth-child(even) { +#book-table tbody tr:nth-child(even) { background-color: #f8f9fa; } -.display-books .book-delete { +#book-table .book-delete { color: #dc3545; font-weight: 600; } -.display-books .book-read { +#book-table .book-read { font-weight: 600; } -.display-books .book-read .btn, -.display-books .book-delete .btn { +#book-table .book-read .btn, +#book-table .book-delete .btn { width: 100%; max-width: 90px; }