Skip to content

Commit 1582ca0

Browse files
committed
fix(book-library): resolve all functional bugs and update the html structure and titles
1 parent c89c066 commit 1582ca0

File tree

3 files changed

+204
-100
lines changed

3 files changed

+204
-100
lines changed

debugging/book-library/index.html

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
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-
/>
4+
<title>Book Library</title>
5+
<meta charset="utf-8" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
107
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
118
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
129
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
@@ -19,7 +16,7 @@
1916

2017
<body>
2118
<div class="jumbotron text-center">
22-
<h1>Library</h1>
19+
<h1>My Book Library</h1>
2320
<p>Add books to your virtual library</p>
2421
</div>
2522

@@ -31,15 +28,15 @@ <h1>Library</h1>
3128
<div class="form-group">
3229
<label for="title">Title:</label>
3330
<input
34-
type="title"
31+
type="text"
3532
class="form-control"
3633
id="title"
3734
name="title"
3835
required
3936
/>
4037
<label for="author">Author: </label>
4138
<input
42-
type="author"
39+
type="text"
4340
class="form-control"
4441
id="author"
4542
name="author"
@@ -64,32 +61,26 @@ <h1>Library</h1>
6461
<input
6562
type="submit"
6663
value="Submit"
67-
class="btn btn-primary"
68-
onclick="submit();"
64+
class="btn btn-primary btn-block"
65+
id="submit-book-btn"
6966
/>
7067
</div>
7168
</div>
7269

73-
<table class="table" id="display">
74-
<thead class="thead-dark">
75-
<tr>
76-
<th>Title</th>
77-
<th>Author</th>
78-
<th>Number of Pages</th>
79-
<th>Read</th>
80-
<th></th>
81-
</tr>
82-
</thead>
83-
<tbody>
84-
<tr>
85-
<td></td>
86-
<td></td>
87-
<td></td>
88-
<td></td>
89-
<td></td>
90-
</tr>
91-
</tbody>
92-
</table>
70+
<div class="table-responsive">
71+
<table class="table table-hover" id="display">
72+
<thead class="thead-dark">
73+
<tr>
74+
<th>Title</th>
75+
<th>Author</th>
76+
<th>Number of Pages</th>
77+
<th>Read</th>
78+
<th></th>
79+
</tr>
80+
</thead>
81+
<tbody></tbody>
82+
</table>
83+
</div>
9384

9485
<script src="script.js"></script>
9586
</body>

debugging/book-library/script.js

Lines changed: 58 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,47 @@
1+
const titleInput = document.getElementById("title");
2+
const authorInput = document.getElementById("author");
3+
const pagesInput = document.getElementById("pages");
4+
const readCheckbox = document.getElementById("check");
5+
const table = document.getElementById("display");
6+
const submitBtn = document.getElementById("submit-book-btn");
7+
18
let myLibrary = [];
29

3-
window.addEventListener("load", function (e) {
10+
window.addEventListener("load", function () {
411
populateStorage();
512
render();
613
});
714

15+
submitBtn.addEventListener("click", addBook);
16+
817
function populateStorage() {
9-
if (myLibrary.length == 0) {
10-
let book1 = new Book("Robison Crusoe", "Daniel Defoe", "252", true);
11-
let book2 = new Book(
12-
"The Old Man and the Sea",
13-
"Ernest Hemingway",
14-
"127",
15-
true
16-
);
17-
myLibrary.push(book1);
18-
myLibrary.push(book2);
19-
render();
18+
const storedLibrary = localStorage.getItem("myLibrary");
19+
if (storedLibrary) {
20+
myLibrary = JSON.parse(storedLibrary);
2021
}
2122
}
2223

23-
const title = document.getElementById("title");
24-
const author = document.getElementById("author");
25-
const pages = document.getElementById("pages");
26-
const check = document.getElementById("check");
24+
function saveStorage() {
25+
localStorage.setItem("myLibrary", JSON.stringify(myLibrary));
26+
}
27+
28+
// Validates input and adds new book
29+
function addBook(e) {
30+
if (e) e.preventDefault();
2731

28-
//check the right input from forms and if its ok -> add the new book (object in array)
29-
//via Book function and start render function
30-
function submit() {
31-
if (
32-
title.value == null ||
33-
title.value == "" ||
34-
pages.value == null ||
35-
pages.value == ""
36-
) {
32+
if (!titleInput.value || !authorInput.value || !pagesInput.value) {
3733
alert("Please fill all fields!");
3834
return false;
39-
} else {
40-
let book = new Book(title.value, title.value, pages.value, check.checked);
41-
library.push(book);
42-
render();
4335
}
36+
let book = new Book(
37+
titleInput.value,
38+
authorInput.value,
39+
pagesInput.value,
40+
readCheckbox.checked
41+
);
42+
myLibrary.push(book);
43+
saveStorage();
44+
render();
4445
}
4546

4647
function Book(title, author, pages, check) {
@@ -51,52 +52,51 @@ function Book(title, author, pages, check) {
5152
}
5253

5354
function render() {
54-
let table = document.getElementById("display");
55-
let rowsNumber = table.rows.length;
56-
//delete old table
57-
for (let n = rowsNumber - 1; n > 0; n-- {
58-
table.deleteRow(n);
59-
}
60-
//insert updated row and cells
55+
// Clears table body efficiently
56+
const tbody = table.querySelector("tbody");
57+
tbody.innerHTML = "";
58+
59+
// Inserts updated row and cells
6160
let length = myLibrary.length;
6261
for (let i = 0; i < length; i++) {
63-
let row = table.insertRow(1);
62+
// Insert at the end of the table
63+
let row = tbody.insertRow(-1);
6464
let titleCell = row.insertCell(0);
6565
let authorCell = row.insertCell(1);
6666
let pagesCell = row.insertCell(2);
6767
let wasReadCell = row.insertCell(3);
6868
let deleteCell = row.insertCell(4);
69-
titleCell.innerHTML = myLibrary[i].title;
70-
authorCell.innerHTML = myLibrary[i].author;
71-
pagesCell.innerHTML = myLibrary[i].pages;
7269

73-
//add and wait for action for read/unread button
74-
let changeBut = document.createElement("button");
75-
changeBut.id = i;
76-
changeBut.className = "btn btn-success";
77-
wasReadCell.appendChild(changeBut);
70+
// Uses textContent to prevent XSS
71+
titleCell.textContent = myLibrary[i].title;
72+
authorCell.textContent = myLibrary[i].author;
73+
pagesCell.textContent = myLibrary[i].pages;
74+
75+
// Toggles read status
76+
let readBtn = document.createElement("button");
77+
wasReadCell.appendChild(readBtn);
78+
7879
let readStatus = "";
79-
if (myLibrary[i].check == false) {
80-
readStatus = "Yes";
81-
} else {
80+
if (myLibrary[i].check === false) {
8281
readStatus = "No";
82+
} else {
83+
readStatus = "Yes";
8384
}
84-
changeBut.innerText = readStatus;
85+
readBtn.textContent = readStatus;
8586

86-
changeBut.addEventListener("click", function () {
87+
readBtn.addEventListener("click", function () {
8788
myLibrary[i].check = !myLibrary[i].check;
89+
saveStorage();
8890
render();
8991
});
9092

91-
//add delete button to every row and render again
92-
let delButton = document.createElement("button");
93-
delBut.id = i + 5;
94-
deleteCell.appendChild(delBut);
95-
delBut.className = "btn btn-warning";
96-
delBut.innerHTML = "Delete";
97-
delBut.addEventListener("clicks", function () {
98-
alert(`You've deleted title: ${myLibrary[i].title}`);
93+
// Deletes book
94+
let deleteBtn = document.createElement("button");
95+
deleteCell.appendChild(deleteBtn);
96+
deleteBtn.textContent = "Delete";
97+
deleteBtn.addEventListener("click", function () {
9998
myLibrary.splice(i, 1);
99+
saveStorage();
100100
render();
101101
});
102102
}

debugging/book-library/style.css

Lines changed: 123 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,132 @@
1-
.form-group {
2-
width: 400px;
3-
height: 300px;
4-
align-self: left;
5-
padding-left: 20px;
1+
/* Google Fonts */
2+
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap");
3+
4+
body {
5+
font-family: "Roboto", sans-serif;
6+
background-color: #f8f9fa;
7+
color: #333;
68
}
79

10+
.jumbotron {
11+
background-color: #343a40;
12+
color: white;
13+
padding: 2rem 1rem;
14+
margin-bottom: 2rem;
15+
border-radius: 0;
16+
}
17+
18+
.jumbotron h1 {
19+
font-weight: 700;
20+
}
21+
22+
/* Button Styling */
823
.btn {
9-
display: block;
24+
border-radius: 20px;
25+
padding: 8px 20px;
26+
font-weight: 500;
27+
transition: all 0.3s ease;
28+
}
29+
30+
.btn-info {
31+
background-color: #17a2b8;
32+
border-color: #17a2b8;
33+
color: white;
34+
}
35+
36+
.btn-info:hover {
37+
background-color: #138496;
38+
border-color: #117a8b;
39+
transform: translateY(-2px);
40+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
41+
}
42+
43+
/* Form Styling */
44+
#demo.collapse.show {
45+
display: flex;
46+
justify-content: center;
47+
margin-bottom: 20px;
48+
}
49+
50+
.form-group {
51+
background: white;
52+
padding: 2rem;
53+
border-radius: 8px;
54+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
55+
width: 100%;
56+
max-width: 500px;
57+
margin: 0 auto;
58+
}
59+
60+
.form-control {
61+
border-radius: 5px;
62+
border: 1px solid #ced4da;
63+
padding: 10px;
64+
}
65+
66+
.form-control:focus {
67+
box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.25);
68+
border-color: #17a2b8;
69+
}
70+
71+
label {
72+
font-weight: 500;
73+
margin-top: 10px;
1074
}
1175

1276
.form-check-label {
13-
padding-left: 20px;
14-
margin: 5px 0px 5px 0px;
77+
display: flex;
78+
align-items: center;
79+
margin: 15px 0;
80+
cursor: pointer;
1581
}
1682

17-
button.btn-info {
18-
margin: 20px;
83+
.form-check-input {
84+
margin-right: 10px;
85+
margin-top: 0;
86+
}
87+
88+
/* Table Styling */
89+
.table-responsive {
90+
margin-top: 20px;
91+
padding: 0 15px;
92+
}
93+
94+
.table {
95+
background: white;
96+
border-radius: 8px;
97+
overflow: hidden;
98+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
99+
}
100+
101+
.thead-dark th {
102+
background-color: #343a40;
103+
border-color: #454d55;
104+
color: white;
105+
}
106+
107+
.table td,
108+
.table th {
109+
vertical-align: middle;
110+
}
111+
112+
/* Responsive Adjustments */
113+
@media (max-width: 576px) {
114+
.jumbotron {
115+
padding: 1.5rem 1rem;
116+
}
117+
118+
.btn {
119+
width: 100%;
120+
margin-bottom: 10px;
121+
}
122+
123+
.form-group {
124+
padding: 1rem;
125+
}
126+
127+
button.btn-info {
128+
margin: 10px auto;
129+
display: block;
130+
width: 90%;
131+
}
19132
}

0 commit comments

Comments
 (0)