-
-
Notifications
You must be signed in to change notification settings - Fork 143
London | 25-ITP-May | Houssam Lahlah | Sprint 2 | Feature/book library #322
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 11 commits
8bd778e
bcdfde3
fff1b69
f439e87
2537f48
fd3649e
94f7e3c
b5a0f4b
b0c6627
283fda2
b2a7d5e
9adee93
b16c7f2
1de7803
9b6df60
e953bb4
25f7083
e5f6ec3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,46 +1,46 @@ | ||
| 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 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"); | ||
|
|
||
| // Add book from form | ||
| function submitBook(event) { | ||
| // Prevent page reload | ||
| event.preventDefault(); | ||
|
|
||
| //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 == "" | ||
| ) { | ||
| const titleVal = titleEl.value.trim(); | ||
| const authorVal = authorEl.value.trim(); | ||
| const pagesVal = Number(pagesEl.value); | ||
|
|
||
| if (!titleVal || !authorVal || !pagesVal) { | ||
| alert("Please fill all fields!"); | ||
| return false; | ||
| } else { | ||
| let book = new Book(title.value, title.value, pages.value, check.checked); | ||
| library.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) { | ||
|
|
@@ -51,53 +51,40 @@ function Book(title, author, pages, check) { | |
| } | ||
|
|
||
| function render() { | ||
| 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; | ||
| const table = document.getElementById("display"); | ||
| const tbody = table.querySelector("tbody"); | ||
| // clear old rows | ||
| tbody.innerHTML = ""; | ||
|
|
||
| //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 = "Yes"; | ||
| } else { | ||
| readStatus = "No"; | ||
| } | ||
| changeBut.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; | ||
|
|
||
| changeBut.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 | ||
| let delButton = document.createElement("button"); | ||
| delBut.id = i + 5; | ||
| deleteCell.appendChild(delBut); | ||
| delBut.className = "btn btn-warning"; | ||
| delBut.innerHTML = "Delete"; | ||
| delBut.addEventListener("clicks", 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); | ||
| }); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Input could be any kind of numbers but some of them should not be considered a valid page count.
Can you add code to sanitize or reject these invalid value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi cjyuan,
Thank you for your guidence. you absoloutly right, I've add another if condition to handle the page number only and now submitBook() function validate the page count input.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you tested the values which you said the app would reject? The modified code does not quite function the way you described here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi cjyuan,
Thanks for catching that — I realized the behavior I described earlier didn’t fully match what was in the code (my mistake!).
I’ve now updated the validation to use a regex (/^\d+$/) instead of the simple Number() check. This ensures only positive whole numbers are accepted.
I tested with "0", "-5", and "12.5" — all of these are now correctly rejected, while "123" works as expected. Also, non-numeric characters like "abc" can’t even be typed into the input field anymore, so they’re automatically prevented at the keyboard level.
This should now fully match the intended behavior.