From 8bd778edb5bd9d7a00ddd3eaeab3762a7f68edb9 Mon Sep 17 00:00:00 2001 From: Samiuk Date: Mon, 18 Aug 2025 16:17:12 +0100 Subject: [PATCH 01/16] - change title.value to author.value. - change library.push(book) to myLibrary.push(book). - add a ) to the end of the for loop condition to avoid syntax error. - change myLibrary[i].check to myLibrary[i].check == true to check if the book is read or not. - change delBut to delButton because we declare it. - The event listener is "clicks" instead of "click". --- debugging/book-library/script.js | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index 75ce6c1d..26f537f8 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -37,8 +37,10 @@ function submit() { alert("Please fill all fields!"); return false; } else { - let book = new Book(title.value, title.value, pages.value, check.checked); - library.push(book); + //fix: change title.value to author.value + let book = new Book(title.value, author.value, pages.value, check.checked); + //Fix: change library.push(book) to myLibrary.push(book). + myLibrary.push(book); render(); } } @@ -54,7 +56,9 @@ function render() { let table = document.getElementById("display"); let rowsNumber = table.rows.length; //delete old table - for (let n = rowsNumber - 1; n > 0; n-- { + // Fix : add a ) to the end of the for loop condition + // to avoid syntax error. + for (let n = rowsNumber - 1; n > 0; n--) { table.deleteRow(n); } //insert updated row and cells @@ -76,7 +80,9 @@ function render() { changeBut.className = "btn btn-success"; wasReadCell.appendChild(changeBut); let readStatus = ""; - if (myLibrary[i].check == false) { + // Fix: change myLibrary[i].check to myLibrary[i].check == true + // to check if the book is read or not. + if (myLibrary[i].check == true) { readStatus = "Yes"; } else { readStatus = "No"; @@ -89,12 +95,15 @@ function render() { }); //add delete button to every row and render again + // Fix : + // change delBut to delButton because we declare it. + // The event listener is "clicks" instead of "click". 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 () { alert(`You've deleted title: ${myLibrary[i].title}`); myLibrary.splice(i, 1); render(); From f439e87e1907c174e72e45fec686c5113e554323 Mon Sep 17 00:00:00 2001 From: Samiuk Date: Mon, 15 Sep 2025 00:17:33 +0100 Subject: [PATCH 02/16] Validate my HTML code online using W3.org --- debugging/book-library/index.html | 34 +++++++++---------------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/debugging/book-library/index.html b/debugging/book-library/index.html index 23acfa71..666606f2 100644 --- a/debugging/book-library/index.html +++ b/debugging/book-library/index.html @@ -1,20 +1,13 @@ - + - - + Book Library + - - + + @@ -31,42 +24,35 @@

Library

+ required> + required> + required> + onclick="submit();">
From 2537f480b93099ff6f92369a007d1d23e43fd411 Mon Sep 17 00:00:00 2001 From: Samiuk Date: Mon, 15 Sep 2025 00:23:10 +0100 Subject: [PATCH 03/16] Remove calling render() function to avoid duplicate --- 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 26f537f8..afdf256d 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -2,7 +2,7 @@ let myLibrary = []; window.addEventListener("load", function (e) { populateStorage(); - render(); + //render(); }); function populateStorage() { From fd3649e0bce6faa4c6e9478205cc95f261f3fda4 Mon Sep 17 00:00:00 2001 From: Samiuk Date: Mon, 15 Sep 2025 00:29:11 +0100 Subject: [PATCH 04/16] Fix the page number to passe and input as a number not as a string --- debugging/book-library/script.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index afdf256d..4d9eabc9 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -7,13 +7,8 @@ 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 - ); + let book1 = new Book("Robison Crusoe", "Daniel Defoe", 252, true); + let book2 = new Book("The Old Man and the Sea","Ernest Hemingway",127,true); myLibrary.push(book1); myLibrary.push(book2); render(); @@ -38,7 +33,7 @@ function submit() { return false; } else { //fix: change title.value to author.value - let book = new Book(title.value, author.value, pages.value, check.checked); + let book = new Book(title.value, author.value, Number(pages.value), check.checked); //Fix: change library.push(book) to myLibrary.push(book). myLibrary.push(book); render(); From 94f7e3ca22ef86bd103925998fce74eb9a5f5a02 Mon Sep 17 00:00:00 2001 From: Samiuk Date: Mon, 15 Sep 2025 00:51:50 +0100 Subject: [PATCH 05/16] add a suffix like El and rename them to indicate DOM elements --- debugging/book-library/script.js | 41 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index 4d9eabc9..7a7f318a 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -15,25 +15,24 @@ function populateStorage() { } } -const title = document.getElementById("title"); -const author = document.getElementById("author"); -const pages = document.getElementById("pages"); -const check = document.getElementById("check"); +const titleEl = document.getElementById("title"); +const authorEl = document.getElementById("author"); +const pagesEl = document.getElementById("pages"); +const checkEl = 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() { if ( - title.value == null || - title.value == "" || - pages.value == null || - pages.value == "" + !titleEl.value || + !pagesEl.value || + !authorEl.value ) { alert("Please fill all fields!"); return false; } else { //fix: change title.value to author.value - let book = new Book(title.value, author.value, Number(pages.value), check.checked); + let book = new Book(titleEl.value, authorEl.value, Number(pagesEl.value), checkEl.checked); //Fix: change library.push(book) to myLibrary.push(book). myLibrary.push(book); render(); @@ -70,10 +69,10 @@ function render() { 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 readBtn = document.createElement("button"); + readBtn.id = `readBtn-${i}`; + readBtn.className = "btn btn-success"; + wasReadCell.appendChild(readBtn); let readStatus = ""; // Fix: change myLibrary[i].check to myLibrary[i].check == true // to check if the book is read or not. @@ -82,9 +81,9 @@ function render() { } else { readStatus = "No"; } - changeBut.innerText = readStatus; + readBtn.innerText = readStatus; - changeBut.addEventListener("click", function () { + readBtn.addEventListener("click", function () { myLibrary[i].check = !myLibrary[i].check; render(); }); @@ -93,12 +92,12 @@ function render() { // Fix : // change delBut to delButton because we declare it. // The event listener is "clicks" instead of "click". - let delButton = document.createElement("button"); - delButton.id = i + 5; - deleteCell.appendChild(delButton); - delButton.className = "btn btn-warning"; - delButton.innerHTML = "Delete"; - delButton.addEventListener("click", function () { + let deleteBtn = document.createElement("button"); + deleteBtn.id = `deleteBtn-${i}`; + deleteCell.appendChild(deleteBtn); + deleteBtn.className = "btn btn-warning"; + deleteBtn.innerHTML = "Delete"; + deleteBtn.addEventListener("click", function () { alert(`You've deleted title: ${myLibrary[i].title}`); myLibrary.splice(i, 1); render(); From b5a0f4b31d69fab5b5e7aa34121e6e62887469a0 Mon Sep 17 00:00:00 2001 From: Samiuk Date: Mon, 15 Sep 2025 01:02:46 +0100 Subject: [PATCH 06/16] Removes leading/trailing spaces and converts pages to a number and rejects empty or invalid inputs --- debugging/book-library/script.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index 7a7f318a..1e6eccb0 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -23,16 +23,19 @@ const checkEl = 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() { + const titleVal = titleEl.value.trim(); + const authorVal = authorEl.value.trim(); + const pagesVal = Number(pagesEl.value); if ( - !titleEl.value || - !pagesEl.value || - !authorEl.value + !titleVal || + !pagesVal || + !authorVal ) { alert("Please fill all fields!"); return false; } else { //fix: change title.value to author.value - let book = new Book(titleEl.value, authorEl.value, Number(pagesEl.value), checkEl.checked); + let book = new Book(titleVal, authorVal, pagesVal, checkEl.checked); //Fix: change library.push(book) to myLibrary.push(book). myLibrary.push(book); render(); From b0c66279c4a19b06996fe3cb2562863badf173f0 Mon Sep 17 00:00:00 2001 From: Samiuk Date: Mon, 15 Sep 2025 01:08:56 +0100 Subject: [PATCH 07/16] Update to remove all rows at once and use innerText instead innerHTML --- debugging/book-library/script.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index 1e6eccb0..d10cbab1 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -55,9 +55,8 @@ function render() { //delete old table // Fix : add a ) to the end of the for loop condition // to avoid syntax error. - for (let n = rowsNumber - 1; n > 0; n--) { - table.deleteRow(n); - } + const tbody = table.querySelector("tbody"); + tbody.innerHTML = ""; //insert updated row and cells let length = myLibrary.length; for (let i = 0; i < length; i++) { @@ -67,9 +66,9 @@ function render() { 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; + titleCell.innerText = myLibrary[i].title; + authorCell.innerText = myLibrary[i].author; + pagesCell.innerText = myLibrary[i].pages; //add and wait for action for read/unread button let readBtn = document.createElement("button"); From 283fda21dfa4f0a62309ff962e1da80b9d50b0af Mon Sep 17 00:00:00 2001 From: Samiuk Date: Mon, 15 Sep 2025 01:41:52 +0100 Subject: [PATCH 08/16] Renamed submit() to submitBook() to avoid HTML form conflicts --- debugging/book-library/index.html | 2 +- debugging/book-library/script.js | 122 +++++++++++++----------------- 2 files changed, 52 insertions(+), 72 deletions(-) diff --git a/debugging/book-library/index.html b/debugging/book-library/index.html index 666606f2..a8ba76bb 100644 --- a/debugging/book-library/index.html +++ b/debugging/book-library/index.html @@ -52,7 +52,7 @@

Library

type="submit" value="Submit" class="btn btn-primary" - onclick="submit();"> + onclick="submitBook(event);"> diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index d10cbab1..4b90cb9c 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -1,18 +1,16 @@ let myLibrary = []; -window.addEventListener("load", function (e) { +window.addEventListener("load", function () { populateStorage(); - //render(); }); 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); - myLibrary.push(book1); - myLibrary.push(book2); - render(); + if (myLibrary.length === 0) { + const book1 = new Book("Robison Crusoe", "Daniel Defoe", 252, true); + const book2 = new Book("The Old Man and the Sea", "Ernest Hemingway", 127, true); + myLibrary.push(book1, book2); } + render(); } const titleEl = document.getElementById("title"); @@ -20,26 +18,28 @@ const authorEl = document.getElementById("author"); const pagesEl = document.getElementById("pages"); const checkEl = 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() { +// Add book from form +function submitBook(event) { + event.preventDefault(); // Prevent page reload + const titleVal = titleEl.value.trim(); const authorVal = authorEl.value.trim(); const pagesVal = Number(pagesEl.value); - if ( - !titleVal || - !pagesVal || - !authorVal - ) { + + if (!titleVal || !authorVal || !pagesVal) { alert("Please fill all fields!"); - return false; - } else { - //fix: change title.value to author.value - let book = new Book(titleVal, authorVal, pagesVal, checkEl.checked); - //Fix: change library.push(book) to myLibrary.push(book). - myLibrary.push(book); - render(); + return; } + + const book = new Book(titleVal, authorVal, pagesVal, checkEl.checked); + myLibrary.push(book); + render(); + + // Clear form + titleEl.value = ""; + authorEl.value = ""; + pagesEl.value = ""; + checkEl.checked = false; } function Book(title, author, pages, check) { @@ -50,59 +50,39 @@ function Book(title, author, pages, check) { } function render() { - let table = document.getElementById("display"); - let rowsNumber = table.rows.length; - //delete old table - // Fix : add a ) to the end of the for loop condition - // to avoid syntax error. + const table = document.getElementById("display"); const tbody = table.querySelector("tbody"); - tbody.innerHTML = ""; - //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.innerText = myLibrary[i].title; - authorCell.innerText = myLibrary[i].author; - pagesCell.innerText = myLibrary[i].pages; + tbody.innerHTML = ""; // clear old rows - //add and wait for action for read/unread button - let readBtn = document.createElement("button"); - readBtn.id = `readBtn-${i}`; - readBtn.className = "btn btn-success"; - wasReadCell.appendChild(readBtn); - let readStatus = ""; - // Fix: change myLibrary[i].check to myLibrary[i].check == true - // to check if the book is read or not. - if (myLibrary[i].check == true) { - readStatus = "Yes"; - } else { - readStatus = "No"; - } - readBtn.innerText = readStatus; + myLibrary.forEach((book, i) => { + const row = tbody.insertRow(); + row.insertCell(0).textContent = book.title; + row.insertCell(1).textContent = book.author; + row.insertCell(2).textContent = book.pages; - readBtn.addEventListener("click", function () { - myLibrary[i].check = !myLibrary[i].check; + // Read/Unread button + const readCell = row.insertCell(3); + const readBtn = document.createElement("button"); + readBtn.className = "btn btn-success"; + readBtn.textContent = book.check ? "Yes" : "No"; + readBtn.addEventListener("click", () => { + book.check = !book.check; render(); }); + readCell.appendChild(readBtn); - //add delete button to every row and render again - // Fix : - // change delBut to delButton because we declare it. - // The event listener is "clicks" instead of "click". - let deleteBtn = document.createElement("button"); - deleteBtn.id = `deleteBtn-${i}`; - deleteCell.appendChild(deleteBtn); - deleteBtn.className = "btn btn-warning"; - deleteBtn.innerHTML = "Delete"; - deleteBtn.addEventListener("click", function () { - alert(`You've deleted title: ${myLibrary[i].title}`); - myLibrary.splice(i, 1); - render(); + // Delete button + const delCell = row.insertCell(4); + const delBtn = document.createElement("button"); + delBtn.className = "btn btn-warning"; + delBtn.textContent = "Delete"; + delBtn.addEventListener("click", () => { + if (confirm(`Are you sure you want to delete "${book.title}"?`)) { + myLibrary.splice(i, 1); + render(); + } }); - } + delCell.appendChild(delBtn); + }); } + From b2a7d5ec484fec51bf92114871a674a173d4459f Mon Sep 17 00:00:00 2001 From: Samiuk Date: Mon, 15 Sep 2025 01:47:38 +0100 Subject: [PATCH 09/16] fix: correct Book Library JS functionality --- debugging/book-library/script.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index 4b90cb9c..9ff9d0b3 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -20,7 +20,8 @@ const checkEl = document.getElementById("check"); // Add book from form function submitBook(event) { - event.preventDefault(); // Prevent page reload + // Prevent page reload + event.preventDefault(); const titleVal = titleEl.value.trim(); const authorVal = authorEl.value.trim(); @@ -52,7 +53,8 @@ function Book(title, author, pages, check) { function render() { const table = document.getElementById("display"); const tbody = table.querySelector("tbody"); - tbody.innerHTML = ""; // clear old rows + // clear old rows + tbody.innerHTML = ""; myLibrary.forEach((book, i) => { const row = tbody.insertRow(); From 9adee933ca8501875c1d4ea3be41f4705f899c0c Mon Sep 17 00:00:00 2001 From: Samiuk Date: Thu, 18 Sep 2025 10:59:18 +0100 Subject: [PATCH 10/16] add validation for page count input in Book Library --- debugging/book-library/script.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index 9ff9d0b3..b6adfc74 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -27,10 +27,16 @@ function submitBook(event) { const authorVal = authorEl.value.trim(); const pagesVal = Number(pagesEl.value); - if (!titleVal || !authorVal || !pagesVal) { + if (!titleVal || !authorVal) { alert("Please fill all fields!"); return; } + if (isNaN(pagesVal) || pagesVal <= 0) { + alert("Please enter a valid number of pages!"); + return; + } + + // Add book to library const book = new Book(titleVal, authorVal, pagesVal, checkEl.checked); myLibrary.push(book); From b16c7f2af0d85bd59b3af0c439731bd6428907f1 Mon Sep 17 00:00:00 2001 From: Samiuk Date: Thu, 18 Sep 2025 11:35:42 +0100 Subject: [PATCH 11/16] Refactor table row creation to centralize cell creation and modularize button setup --- debugging/book-library/script.js | 58 +++++++++++++++----------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index b6adfc74..f7a47742 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -58,39 +58,35 @@ function Book(title, author, pages, check) { function render() { const table = document.getElementById("display"); - const tbody = table.querySelector("tbody"); - // clear old rows - tbody.innerHTML = ""; + table.innerHTML = ""; myLibrary.forEach((book, i) => { - const row = tbody.insertRow(); - row.insertCell(0).textContent = book.title; - row.insertCell(1).textContent = book.author; - row.insertCell(2).textContent = book.pages; - - // Read/Unread button - const readCell = row.insertCell(3); - const readBtn = document.createElement("button"); - readBtn.className = "btn btn-success"; - readBtn.textContent = book.check ? "Yes" : "No"; - readBtn.addEventListener("click", () => { - book.check = !book.check; - render(); - }); - readCell.appendChild(readBtn); - - // Delete button - const delCell = row.insertCell(4); - const delBtn = document.createElement("button"); - delBtn.className = "btn btn-warning"; - delBtn.textContent = "Delete"; - delBtn.addEventListener("click", () => { - if (confirm(`Are you sure you want to delete "${book.title}"?`)) { - myLibrary.splice(i, 1); - render(); - } - }); - delCell.appendChild(delBtn); + const row = table.insertRow(); + + // keep all cells in one place + const titleCell = row.insertCell(0); + const authorCell = row.insertCell(1); + const pagesCell = row.insertCell(2); + const checkCell = row.insertCell(3); + const delCell = row.insertCell(4); // delete button cell + + titleCell.textContent = book.title; + authorCell.textContent = book.author; + pagesCell.textContent = book.pages; + checkCell.textContent = book.check ? "Read" : "Not Read"; + + // use helper function for delete button + createDeleteCell(delCell, i); + }); +} + +function createDeleteCell(cell, index) { + const deleteBtn = document.createElement("button"); + deleteBtn.textContent = "Delete"; + deleteBtn.addEventListener("click", () => { + myLibrary.splice(index, 1); + render(); }); + cell.appendChild(deleteBtn); } From 1de78038fdab3d885aa2cf56366f35a23c98f8fd Mon Sep 17 00:00:00 2001 From: Samiuk Date: Thu, 18 Sep 2025 22:26:58 +0100 Subject: [PATCH 12/16] update the render() function to delete just the the rows not the whole table --- debugging/book-library/script.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index f7a47742..dee693db 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -58,7 +58,10 @@ function Book(title, author, pages, check) { function render() { const table = document.getElementById("display"); - table.innerHTML = ""; + const tbody = table.querySelector("tbody"); + + // Clear existing rows + tbody.innerHTML = ""; myLibrary.forEach((book, i) => { const row = table.insertRow(); @@ -88,5 +91,4 @@ function createDeleteCell(cell, index) { render(); }); cell.appendChild(deleteBtn); -} - +} \ No newline at end of file From 9b6df603d3259bac21ed780648f84fd1c94c1e2c Mon Sep 17 00:00:00 2001 From: Samiuk Date: Thu, 18 Sep 2025 22:47:08 +0100 Subject: [PATCH 13/16] update the code to handle the toggle checkbox Read or Not Read --- debugging/book-library/script.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index dee693db..daa4bcd7 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -64,7 +64,7 @@ function render() { tbody.innerHTML = ""; myLibrary.forEach((book, i) => { - const row = table.insertRow(); + const row = tbody.insertRow(); // keep all cells in one place const titleCell = row.insertCell(0); @@ -76,19 +76,30 @@ function render() { titleCell.textContent = book.title; authorCell.textContent = book.author; pagesCell.textContent = book.pages; - checkCell.textContent = book.check ? "Read" : "Not Read"; + + const readBtn = document.createElement("button"); + readBtn.textContent = book.check ? "Read" : "Not Read"; + readBtn.className = book.check ? "btn btn-success" : "btn btn-secondary"; + readBtn.addEventListener("click", () => { + book.check = !book.check; // toggle + render(); // re-render table + }); + checkCell.appendChild(readBtn); // use helper function for delete button - createDeleteCell(delCell, i); + createDeleteCell(delCell, book); }); } -function createDeleteCell(cell, index) { +function createDeleteCell(cell, book) { const deleteBtn = document.createElement("button"); deleteBtn.textContent = "Delete"; deleteBtn.addEventListener("click", () => { + const index = myLibrary.indexOf(book); + if (index > -1){ myLibrary.splice(index, 1); render(); + } }); cell.appendChild(deleteBtn); } \ No newline at end of file From e953bb4d25144bfc94c3d362faae8d1ec370b623 Mon Sep 17 00:00:00 2001 From: Samiuk Date: Fri, 19 Sep 2025 13:05:21 +0100 Subject: [PATCH 14/16] validate pages input to accept only positive whole numbers --- debugging/book-library/script.js | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index daa4bcd7..9423d7c3 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -25,15 +25,24 @@ function submitBook(event) { const titleVal = titleEl.value.trim(); const authorVal = authorEl.value.trim(); - const pagesVal = Number(pagesEl.value); + const pagesRaw = pagesEl.value.trim(); + + // Check if pages input is a positive whole number + if (!/^\d+$/.test(pagesRaw)) { + alert("Please enter a valid positive whole number for pages!"); + return; + } + + const pagesVal = Number(pagesRaw); if (!titleVal || !authorVal) { - alert("Please fill all fields!"); - return; + alert("Please fill all fields!"); + return; } - if (isNaN(pagesVal) || pagesVal <= 0) { - alert("Please enter a valid number of pages!"); - return; + + if (pagesVal <= 0) { + alert("Please enter a realistic positive number of pages!"); + return; } // Add book to library From 25f7083d83532efe92a8321e92c64d97a1aac74b Mon Sep 17 00:00:00 2001 From: Samiuk Date: Fri, 19 Sep 2025 13:25:50 +0100 Subject: [PATCH 15/16] Refactor delete button to use index instead of book object --- debugging/book-library/script.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index 9423d7c3..d52a2400 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -96,15 +96,14 @@ function render() { checkCell.appendChild(readBtn); // use helper function for delete button - createDeleteCell(delCell, book); + createDeleteCell(delCell, i); }); } -function createDeleteCell(cell, book) { +function createDeleteCell(cell, index) { const deleteBtn = document.createElement("button"); deleteBtn.textContent = "Delete"; deleteBtn.addEventListener("click", () => { - const index = myLibrary.indexOf(book); if (index > -1){ myLibrary.splice(index, 1); render(); From e5f6ec3fd327ea95920a509a3d74184c70902d58 Mon Sep 17 00:00:00 2001 From: Samiuk Date: Fri, 19 Sep 2025 13:39:56 +0100 Subject: [PATCH 16/16] Refactor read/unread button creation to use a helper function --- debugging/book-library/script.js | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/debugging/book-library/script.js b/debugging/book-library/script.js index d52a2400..38766f02 100644 --- a/debugging/book-library/script.js +++ b/debugging/book-library/script.js @@ -85,15 +85,9 @@ function render() { titleCell.textContent = book.title; authorCell.textContent = book.author; pagesCell.textContent = book.pages; - - const readBtn = document.createElement("button"); - readBtn.textContent = book.check ? "Read" : "Not Read"; - readBtn.className = book.check ? "btn btn-success" : "btn btn-secondary"; - readBtn.addEventListener("click", () => { - book.check = !book.check; // toggle - render(); // re-render table - }); - checkCell.appendChild(readBtn); + + // use helper function for read button + createReadButton(checkCell, i); // use helper function for delete button createDeleteCell(delCell, i); @@ -110,4 +104,18 @@ function createDeleteCell(cell, index) { } }); cell.appendChild(deleteBtn); +} + +// helper function for read button +function createReadButton(cell, index) { + const readBtn = document.createElement("button"); + readBtn.textContent = myLibrary[index].check ? "Read" : "Not Read"; + readBtn.className = myLibrary[index].check ? "btn btn-success" : "btn btn-secondary"; + + readBtn.addEventListener("click", () => { + myLibrary[index].check = !myLibrary[index].check; + render(); + }); + + cell.appendChild(readBtn); } \ No newline at end of file