Skip to content

NW | ITP-May-25 | Geraldine Edwards | Module-Data-Flows | Sprint-2 | Debugging | Book-Library #228

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 110 additions & 72 deletions debugging/book-library/index.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<html lang="en">
<head>
<title> </title>
<title>My Book Library</title>
<meta
charset="utf-8"
name="viewport"
Expand All @@ -18,79 +18,117 @@
</head>

<body>
<div class="jumbotron text-center">
<h1>Library</h1>
<p>Add books to your virtual library</p>
</div>
<div class="container-fluid">
<div class="jumbotron text-center">
<h1 class="text-center mb-4 text-primary">My Book Library</h1>
<p class="text-center mb-4">Add books to your virtual library</p>
</div>

<button data-toggle="collapse" data-target="#demo" class="btn btn-info">
Add new book
</button>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<!-- Reading Progress Section -->
<div class="card mb-4">
<div class="card-header bg-primary text-white">
<h4 class="mb-0" id="progress-header"> Reading Progress</h4>
</div>
<div class="card-body">
<div class="progress" style="height: 25px;">
<div id="progress-bar" class="progress-bar bg-success" role="progressbar" style="width: 0%">
<!-- Progress percentage gets dynamically updated -->
</div>
</div>
</div>
</div>

<div id="demo" class="collapse">
<div class="form-group">
<label for="title">Title:</label>
<input
type="title"
class="form-control"
id="title"
name="title"
required
/>
<label for="author">Author: </label>
<input
type="author"
class="form-control"
id="author"
name="author"
required
/>
<label for="pages">Pages:</label>
<input
type="number"
class="form-control"
id="pages"
name="pages"
required
/>
<label class="form-check-label">
<input
type="checkbox"
class="form-check-input"
id="check"
value=""
/>Read
</label>
<input
type="submit"
value="Submit"
class="btn btn-primary"
onclick="submit();"
/>
</div>
</div>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<button data-toggle="collapse" data-target="#demo" class="btn btn-info mb-3">
Add new book
</button>

<table class="table" id="display">
<thead class="thead-dark">
<tr>
<th>Title</th>
<th>Author</th>
<th>Number of Pages</th>
<th>Read</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<div id="demo" class="collapse">
<div class="card mb-4">
<div class="card-body">
<div class="form-group">
<label for="title">Title:</label>
<input
type="text"
class="form-control"
id="title"
name="title"
required
/>
</div>
<div class="form-group">
<label for="author">Author:</label>
<input
type="text"
class="form-control"
id="author"
name="author"
required
/>
</div>
<div class="form-group">
<label for="pages">Pages:</label>
<input
type="number"
class="form-control"
id="pages"
name="pages"
required
/>
</div>
<div class="form-check mb-3">
<input
type="checkbox"
class="form-check-input"
id="check"
value=""
/>
<label class="form-check-label" for="check">
I have read this book
</label>
</div>
<input
type="submit"
value="Add Book"
class="btn btn-primary"
onclick="submit();"
/>
</div>
</div>
</div>

<div class="table-responsive">
<table class="table table-striped table-hover" id="display">
<thead class="thead-dark">
<tr>
<th>Title</th>
<th>Author</th>
<th>Number of Pages</th>
<th>Read</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>

<script src="script.js"></script>
</body>
</html>
</html>
106 changes: 83 additions & 23 deletions debugging/book-library/script.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,52 @@
// initialise an empty array to hold my book library
let myLibrary = [];

// function to save my library to localStorage
function saveToStorage() {
// convert myLibrary array to a JSON string and save it
localStorage.setItem('myLibrary', JSON.stringify(myLibrary));
}

// function to load my library from localStorage
function loadFromStorage() {
// retrieve the JSON string from localStorage and parse it back to an array
const stored = localStorage.getItem('myLibrary');
// only parse if there is something stored
if (stored) {
myLibrary = JSON.parse(stored);
}
}

// function to display the current number of books read vs unread
function updateProgressBar() {
const totalBooks = myLibrary.length;
const readBooks = myLibrary.filter(book => book.check).length;
const percent = totalBooks === 0 ? 0 : Math.round((readBooks / totalBooks) * 100);

// update the progress bar text
document.getElementById('progress-header').innerText = `Read ${readBooks} out of ${totalBooks} books`;

// update the progress bar width
const progressBar = document.getElementById('progress-bar');
progressBar.style.width = percent + "%";

}

window.addEventListener("load", function (e) {
populateStorage();
render();
// load saved books from local storage
loadFromStorage();
// only add default books if myLibrary is empty
// this prevents overwriting existing books
if (myLibrary.length === 0) {
populateStorage();
}
render();
});

function populateStorage() {
// add default books to myLibrary if it's empty on initial setup
if (myLibrary.length == 0) {
let book1 = new Book("Robison Crusoe", "Daniel Defoe", "252", true);
let book1 = new Book("Robinson Crusoe", "Daniel Defoe", "252", true);
let book2 = new Book(
"The Old Man and the Sea",
"Ernest Hemingway",
Expand All @@ -28,76 +67,97 @@ 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() {
// add validation for empty fields
if (
title.value == null ||
title.value == "" ||
pages.value == null ||
author.value == "" ||
pages.value == ""
) {
alert("Please fill all fields!");
return false;
} else {
let book = new Book(title.value, title.value, pages.value, check.checked);
library.push(book);
// create a new book object and add it to myLibrary and save to storage
let book = new Book(title.value, author.value, pages.value, check.checked);
myLibrary.push(book);
saveToStorage(); // save the book after adding
render();

// Clear the form after successful submission
title.value = "";
author.value = "";
pages.value = "";
check.checked = false;
}
}

function Book(title, author, pages, check) {
// constructor function to create a new book object
this.title = title;
this.author = author;
this.pages = pages;
this.check = check;
}

function render() {
// render the table with books from myLibrary
let table = document.getElementById("display");
// count the existing number of rows in the table
let rowsNumber = table.rows.length;
//delete old table
for (let n = rowsNumber - 1; n > 0; n-- {
//delete all the rows except for the table header row (delete all rows except row 0)
for (let n = rowsNumber - 1; n > 0; n--) {
table.deleteRow(n);

// update the progress bar after deleting rows
updateProgressBar();
}
//insert updated row and cells
//loop through each book and create a new row for each book, insert 5 cells per row
let length = myLibrary.length;
for (let i = 0; i < length; i++) {
let row = table.insertRow(1);
let row = table.insertRow(1); // insert new row at position 1 to keep the header intact
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);

// fill the first 3 cells with book data
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 changeBtn = document.createElement("button");
changeBtn.id = i;
wasReadCell.appendChild(changeBtn)
let readStatus = "";
if (myLibrary[i].check == false) {
if (myLibrary[i].check == true) {
readStatus = "Yes";
changeBtn.className = "btn btn-success";
} else {
readStatus = "No";
changeBtn.className = "btn btn-secondary";
}
changeBut.innerText = readStatus;
changeBtn.innerText = readStatus;


changeBut.addEventListener("click", function () {
changeBtn.addEventListener("click", function () {
myLibrary[i].check = !myLibrary[i].check;
saveToStorage(); // save after changing read status
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 () {
alert(`You've deleted title: ${myLibrary[i].title}`);
myLibrary.splice(i, 1);
saveToStorage(); // save after deleting
render();
});
}
}
// log the library to console for debugging
Loading