Skip to content

Commit 0d9263a

Browse files
committed
Improving he Book Library app
1 parent 9f3bdb5 commit 0d9263a

File tree

2 files changed

+204
-134
lines changed

2 files changed

+204
-134
lines changed

debugging/book-library/index.html

Lines changed: 117 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,147 @@
11
<!DOCTYPE html>
2-
<html>
2+
<html lang="en">
33
<head>
4-
<title> </title>
5-
<meta
6-
charset="utf-8"
7-
name="viewport"
8-
content="width=device-width, initial-scale=1.0"
9-
/>
10-
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
11-
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
12-
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Library App</title>
7+
138
<link
149
rel="stylesheet"
1510
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
1611
/>
17-
<link rel="stylesheet" type="text/css" href="style.css" />
1812
</head>
19-
2013
<body>
2114
<div class="jumbotron text-center">
2215
<h1>Library</h1>
2316
<p>Add books to your virtual library</p>
2417
</div>
2518

26-
<button data-toggle="collapse" data-target="#demo" class="btn btn-info">
19+
<button data-toggle="collapse" data-target="#formCollapse" class="btn btn-info">
2720
Add new book
2821
</button>
2922

30-
<div id="demo" class="collapse">
31-
<div class="form-group">
32-
<label for="title">Title:</label>
33-
<input
34-
type="title"
35-
class="form-control"
36-
id="title"
37-
name="title"
38-
required
39-
/>
40-
<label for="author">Author: </label>
41-
<input
42-
type="author"
43-
class="form-control"
44-
id="author"
45-
name="author"
46-
required
47-
/>
48-
<label for="pages">Pages:</label>
49-
<input
50-
type="number"
51-
class="form-control"
52-
id="pages"
53-
name="pages"
54-
required
55-
/>
56-
<label class="form-check-label">
57-
<input
58-
type="checkbox"
59-
class="form-check-input"
60-
id="check"
61-
value=""
62-
/>Read
23+
<div id="formCollapse" class="collapse mt-3">
24+
<form id="bookForm" class="form-group">
25+
<label for="titleInput">Title:</label>
26+
<input id="titleInput" class="form-control" required />
27+
28+
<label for="authorInput">Author:</label>
29+
<input id="authorInput" class="form-control" required />
30+
31+
<label for="pagesInput">Pages:</label>
32+
<input id="pagesInput" type="number" class="form-control" required />
33+
34+
<label class="form-check-label mt-2">
35+
<input type="checkbox" class="form-check-input" id="readCheckbox" /> Read
6336
</label>
64-
<input
65-
type="submit"
66-
value="Submit"
67-
class="btn btn-primary"
68-
onclick="submit();"
69-
/>
70-
</div>
37+
38+
<button type="submit" class="btn btn-primary mt-3">Submit</button>
39+
</form>
7140
</div>
7241

73-
<table class="table" id="display">
42+
<table class="table" id="displayTable">
7443
<thead class="thead-dark">
7544
<tr>
7645
<th>Title</th>
7746
<th>Author</th>
78-
<th>Number of Pages</th>
47+
<th>Pages</th>
7948
<th>Read</th>
80-
<th></th>
49+
<th>Action</th>
8150
</tr>
8251
</thead>
83-
<tbody>
84-
<tr>
85-
<td></td>
86-
<td></td>
87-
<td></td>
88-
<td></td>
89-
<td></td>
90-
</tr>
91-
</tbody>
52+
<tbody></tbody>
9253
</table>
9354

94-
<script src="script.js"></script>
55+
<script type="module">
56+
class Book {
57+
constructor(title, author, pages, read) {
58+
this.title = title;
59+
this.author = author;
60+
this.pages = pages;
61+
this.read = read;
62+
}
63+
}
64+
65+
const library = [
66+
new Book("Robinson Crusoe", "Daniel Defoe", 252, true),
67+
new Book("The Old Man and the Sea", "Ernest Hemingway", 127, true)
68+
];
69+
70+
const bookForm = document.getElementById("bookForm");
71+
const titleInput = document.getElementById("titleInput");
72+
const authorInput = document.getElementById("authorInput");
73+
const pagesInput = document.getElementById("pagesInput");
74+
const readCheckbox = document.getElementById("readCheckbox");
75+
const tableBody = document.querySelector("#displayTable tbody");
76+
77+
bookForm.addEventListener("submit", (event) => {
78+
event.preventDefault();
79+
80+
const title = titleInput.value.trim();
81+
const author = authorInput.value.trim();
82+
const pages = Number(pagesInput.value);
83+
const read = readCheckbox.checked;
84+
85+
if (!title || !author || !Number.isInteger(pages) || pages <= 0) {
86+
alert("Please enter valid book details.");
87+
return;
88+
}
89+
90+
library.push(new Book(title, author, pages, read));
91+
92+
bookForm.reset();
93+
render();
94+
});
95+
96+
function render() {
97+
tableBody.innerHTML = "";
98+
99+
library.forEach((book, index) => {
100+
const row = document.createElement("tr");
101+
102+
row.innerHTML = `
103+
<td>${book.title}</td>
104+
<td>${book.author}</td>
105+
<td>${book.pages}</td>
106+
<td>
107+
<button class="btn btn-sm ${book.read ? 'btn-success' : 'btn-secondary'}" data-index="${index}" data-action="toggle">
108+
${book.read ? 'Yes' : 'No'}
109+
</button>
110+
</td>
111+
<td>
112+
<button class="btn btn-sm btn-danger" data-index="${index}" data-action="delete">Delete</button>
113+
</td>
114+
`;
115+
116+
tableBody.appendChild(row);
117+
});
118+
}
119+
120+
tableBody.addEventListener("click", (e) => {
121+
const button = e.target.closest("button");
122+
if (!button) return;
123+
124+
const index = Number(button.dataset.index);
125+
const action = button.dataset.action;
126+
127+
if (action === "toggle") {
128+
library[index].read = !library[index].read;
129+
render();
130+
}
131+
132+
if (action === "delete") {
133+
const title = library[index].title;
134+
library.splice(index, 1);
135+
render();
136+
alert(`Deleted: ${title}`);
137+
}
138+
});
139+
140+
render();
141+
</script>
142+
143+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
144+
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
145+
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
95146
</body>
96147
</html>

debugging/book-library/script.js

Lines changed: 87 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,109 @@
1-
let myLibrary = [];
2-
3-
window.addEventListener("load", function () {
4-
populateStorage();
5-
render();
6-
});
7-
8-
function populateStorage() {
9-
if (myLibrary.length == 0) {
10-
let book1 = new Book("Robinson Crusoe", "Daniel Defoe", 252, true);
11-
let book2 = new Book("The Old Man and the Sea", "Ernest Hemingway", 127, true);
12-
myLibrary.push(book1);
13-
myLibrary.push(book2);
1+
class Book {
2+
constructor(title, author, pages, read) {
3+
this.title = title;
4+
this.author = author;
5+
this.pages = pages;
6+
this.read = read;
147
}
158
}
169

17-
const title = document.getElementById("title");
18-
const author = document.getElementById("author");
19-
const pages = document.getElementById("pages");
20-
const check = document.getElementById("check");
2110

22-
function submit() {
23-
if (title.value === "" || author.value === "" || pages.value === "") {
24-
alert("Please fill all fields!");
11+
const library = [
12+
new Book("Robinson Crusoe", "Daniel Defoe", 252, true),
13+
new Book("The Old Man and the Sea", "Ernest Hemingway", 127, true),
14+
];
15+
16+
17+
const bookForm = document.getElementById("bookForm");
18+
const titleInput = document.getElementById("titleInput");
19+
const authorInput = document.getElementById("authorInput");
20+
const pagesInput = document.getElementById("pagesInput");
21+
const readCheckbox = document.getElementById("readCheckbox");
22+
const tableBody = document.querySelector("#displayTable tbody");
23+
24+
25+
bookForm.addEventListener("submit", (event) => {
26+
event.preventDefault();
27+
28+
const title = titleInput.value.trim();
29+
const author = authorInput.value.trim();
30+
const pages = Number(pagesInput.value);
31+
const read = readCheckbox.checked;
32+
33+
34+
if (!title || !author || !Number.isInteger(pages) || pages <= 0) {
35+
alert("Please enter valid book details.");
2536
return;
2637
}
2738

28-
let book = new Book(title.value, author.value, pages.value, check.checked);
29-
myLibrary.push(book);
3039

31-
// clear form
32-
title.value = "";
33-
author.value = "";
34-
pages.value = "";
35-
check.checked = false;
40+
library.push(new Book(title, author, pages, read));
41+
42+
43+
bookForm.reset();
44+
3645

3746
render();
38-
}
47+
});
3948

40-
function Book(title, author, pages, read) {
41-
this.title = title;
42-
this.author = author;
43-
this.pages = pages;
44-
this.read = read; // renamed from "check" (more readable)
45-
}
4649

4750
function render() {
48-
let table = document.getElementById("display");
49-
50-
// delete old rows
51-
while (table.rows.length > 1) {
52-
table.deleteRow(1);
53-
}
5451

55-
// insert updated rows
56-
for (let i = 0; i < myLibrary.length; i++) {
57-
let row = table.insertRow(1);
52+
tableBody.innerHTML = "";
53+
54+
library.forEach((book, index) => {
55+
const row = document.createElement("tr");
56+
57+
row.innerHTML = `
58+
<td>${book.title}</td>
59+
<td>${book.author}</td>
60+
<td>${book.pages}</td>
61+
<td>
62+
<button
63+
class="btn btn-sm ${book.read ? "btn-success" : "btn-secondary"}"
64+
data-index="${index}"
65+
data-action="toggle"
66+
>
67+
${book.read ? "Yes" : "No"}
68+
</button>
69+
</td>
70+
<td>
71+
<button
72+
class="btn btn-sm btn-danger"
73+
data-index="${index}"
74+
data-action="delete"
75+
>
76+
Delete
77+
</button>
78+
</td>
79+
`;
80+
81+
tableBody.appendChild(row);
82+
});
83+
}
5884

59-
row.insertCell(0).innerHTML = myLibrary[i].title;
60-
row.insertCell(1).innerHTML = myLibrary[i].author;
61-
row.insertCell(2).innerHTML = myLibrary[i].pages;
6285

63-
// read status toggle button
64-
let readCell = row.insertCell(3);
65-
let readButton = document.createElement("button");
66-
readButton.className = "btn btn-success";
67-
readButton.innerText = myLibrary[i].read ? "Yes" : "No";
86+
tableBody.addEventListener("click", (event) => {
87+
const button = event.target.closest("button");
88+
if (!button) return;
6889

69-
readButton.addEventListener("click", function () {
70-
myLibrary[i].read = !myLibrary[i].read;
71-
render();
72-
});
90+
const index = Number(button.dataset.index);
91+
const action = button.dataset.action;
7392

74-
readCell.appendChild(readButton);
7593

76-
// delete button
77-
let delCell = row.insertCell(4);
78-
let delButton = document.createElement("button");
79-
delButton.className = "btn btn-warning";
80-
delButton.innerText = "Delete";
94+
if (action === "toggle") {
95+
library[index].read = !library[index].read;
96+
render();
97+
}
8198

82-
delButton.addEventListener("click", function () {
83-
alert(`You've deleted: ${myLibrary[i].title}`);
84-
myLibrary.splice(i, 1);
85-
render();
86-
});
8799

88-
delCell.appendChild(delButton);
100+
if (action === "delete") {
101+
const removedTitle = library[index].title;
102+
library.splice(index, 1);
103+
render();
104+
alert(`Deleted: ${removedTitle}`);
89105
}
90-
}
106+
});
107+
108+
109+
render();

0 commit comments

Comments
 (0)