Skip to content

Commit 05f6ca0

Browse files
committed
Add error message and improving the code
1 parent 4a0a268 commit 05f6ca0

File tree

3 files changed

+153
-198
lines changed

3 files changed

+153
-198
lines changed

debugging/book-library/index.html

Lines changed: 48 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,54 @@
11
<!DOCTYPE html>
22
<html>
3-
<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>
13-
<link
14-
rel="stylesheet"
15-
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
16-
/>
17-
<link rel="stylesheet" type="text/css" href="style.css" />
18-
</head>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>Library</title>
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" />
8+
<link rel="stylesheet" href="style.css" />
9+
</head>
10+
<body>
11+
<div class="jumbotron text-center">
12+
<h1>Library</h1>
13+
<p>Add books to your virtual library</p>
14+
</div>
15+
<div id="errorMessage"></div>
16+
<button data-toggle="collapse" data-target="#demo" class="btn btn-info">
17+
Add new book
18+
</button>
19+
<div id="demo" class="collapse">
20+
<div class="form-group">
21+
<label for="title">Title:</label>
22+
<input type="text" class="form-control" id="titleInput" name="title" required />
23+
<label for="author">Author:</label>
24+
<input type="text" class="form-control" id="authorInput" name="author" required />
25+
<label for="pages">Pages:</label>
26+
<input type="number" class="form-control" id="pagesInput" name="pages" required />
1927

20-
<body>
21-
<div class="jumbotron text-center">
22-
<h1>Library</h1>
23-
<p>Add books to your virtual library</p>
24-
</div>
25-
26-
<button data-toggle="collapse" data-target="#demo" class="btn btn-info">
27-
Add new book
28-
</button>
28+
<label class="form-check-label">
29+
<input type="checkbox" class="form-check-input" id="readInput" />
30+
Read
31+
</label>
2932

30-
<div id="demo" class="collapse">
31-
<div class="form-group">
32-
<label for="title">Title:</label>
33-
<input type="text" class="form-control" id="title" name="title" required />
34-
<label for="author">Author: </label>
35-
<input type="text" class="form-control" id="author" name="author" required />
36-
<label for="pages">Pages:</label>
37-
<input
38-
type="number"
39-
class="form-control"
40-
id="pages"
41-
name="pages"
42-
required
43-
/>
44-
<label class="form-check-label">
45-
<input
46-
type="checkbox"
47-
class="form-check-input"
48-
id="check"
49-
value=""
50-
/>Read
51-
</label>
52-
<input type="button" value="Submit" class="btn btn-primary" onclick="addBook();" />
53-
</div>
33+
<button id="submitBtn" class="btn btn-primary">Submit</button>
5434
</div>
35+
</div>
36+
<table class="table" id="display">
37+
<thead class="thead-dark">
38+
<tr>
39+
<th>Title</th>
40+
<th>Author</th>
41+
<th>Number of Pages</th>
42+
<th>Read</th>
43+
<th></th>
44+
</tr>
45+
</thead>
46+
<tbody></tbody>
47+
</table>
48+
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
49+
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
50+
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
51+
<script src="script.js" type="module"></script>
52+
</body>
5553

56-
<table class="table" id="display">
57-
<thead class="thead-dark">
58-
<tr>
59-
<th>Title</th>
60-
<th>Author</th>
61-
<th>Number of Pages</th>
62-
<th>Read</th>
63-
<th></th>
64-
</tr>
65-
</thead>
66-
<tbody>
67-
</tbody>
68-
69-
</table>
70-
71-
<script src="script.js"></script>
72-
</body>
73-
</html>
54+
</html>

debugging/book-library/script.js

Lines changed: 91 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,134 +1,108 @@
11
let myLibrary = [];
22

3-
window.addEventListener("load", function () {
4-
populateStorage();
5-
render();
3+
const titleInput = document.getElementById("titleInput");
4+
const authorInput = document.getElementById("authorInput");
5+
const pagesInput = document.getElementById("pagesInput");
6+
const readInput = document.getElementById("readInput");
7+
const errorBox = document.getElementById("errorMessage");
8+
const tableBody = document.querySelector("#display tbody");
9+
10+
window.addEventListener("load", () => {
11+
populateInitialBooks();
12+
render();
613
});
714

8-
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();
20-
}
15+
function Book(title, author, pages, read) {
16+
this.title = title;
17+
this.author = author;
18+
this.pages = pages; // number
19+
this.read = read; // boolean
2120
}
2221

23-
const title = document.getElementById("title");
24-
const author = document.getElementById("author");
25-
const pages = document.getElementById("pages");
26-
const check = document.getElementById("check");
22+
function populateInitialBooks() {
23+
if (myLibrary.length > 0) return;
24+
25+
myLibrary.push(
26+
new Book("Robinson Crusoe", "Daniel Defoe", 252, true),
27+
new Book("The Old Man and the Sea", "Ernest Hemingway", 127, true)
28+
);
29+
}
2730

28-
// Check the input from forms and, if valid, add the new book (object in array)
29-
// via Book constructor and start render function
3031
function addBook() {
31-
if (
32-
title.value == null ||
33-
title.value === "" ||
34-
pages.value == null ||
35-
pages.value === ""
36-
) {
37-
showError("Please fill all fields!");
38-
return false;
39-
}
40-
41-
if (myLibrary.some(b => b.title === title.value && b.author === author.value)) {
42-
showError("This book already exists!");
43-
return;
44-
}
45-
46-
if (!isNaN(title.value.trim()) || !isNaN(author.value.trim())) {
47-
showError("Title and Author must be text!");
48-
return;
49-
}
50-
51-
let book = new Book(title.value, author.value, Number(pages.value), check.checked);
52-
myLibrary.push(book);
53-
render();
32+
const title = titleInput.value.trim();
33+
const author = authorInput.value.trim();
34+
const pages = pagesInput.value.trim();
35+
const read = readInput.checked;
36+
37+
if (!title || !author || !pages) {
38+
showError("Please fill all fields!");
39+
return;
40+
}
41+
42+
if (isNaN(Number(pages)) || Number(pages) <= 0) {
43+
showError("Pages must be a positive number.");
44+
return;
45+
}
46+
47+
if (myLibrary.some(b => b.title === title && b.author === author)) {
48+
showError("This book already exists!");
49+
return;
50+
}
51+
52+
const book = new Book(title, author, Number(pages), read);
53+
myLibrary.push(book);
54+
clearForm();
55+
render();
5456
}
5557

56-
// Clear any previous error messages
57-
document.getElementById("errorMessage").style.display = "none";
58+
document.getElementById("submitBtn").addEventListener("click", addBook);
5859

59-
function Book(title, author, pages, read) {
60-
this.title = title;
61-
this.author = author;
62-
this.pages = pages;
63-
this.read = read;
60+
function clearForm() {
61+
titleInput.value = "";
62+
authorInput.value = "";
63+
pagesInput.value = "";
64+
readInput.checked = false;
6465
}
6566

66-
6767
function render() {
68-
let table = document.getElementById("display");
69-
let rowsNumber = table.rows.length;
70-
71-
// Delete old table rows
72-
for (let n = rowsNumber - 1; n > 0; n--) {
73-
table.deleteRow(n);
74-
}
75-
76-
// Insert updated rows and cells
77-
let length = myLibrary.length;
78-
for (let i = 0; i < length; i++) {
79-
let row = table.insertRow(1);
80-
let titleCell = row.insertCell(0);
81-
let authorCell = row.insertCell(1);
82-
let pagesCell = row.insertCell(2);
83-
let wasReadCell = row.insertCell(3);
84-
let deleteCell = row.insertCell(4);
85-
86-
titleCell.innerHTML = myLibrary[i].title;
87-
authorCell.innerHTML = myLibrary[i].author;
88-
pagesCell.innerHTML = myLibrary[i].pages;
89-
90-
// Add and configure read/unread button
91-
let changeBut = document.createElement("button");
92-
changeBut.id = i;
93-
changeBut.className = "btn btn-primary";
94-
wasReadCell.appendChild(changeBut);
95-
96-
let readStatus = myLibrary[i].check ? "Yes" : "No";
97-
changeBut.innerHTML = readStatus;
98-
99-
if (myLibrary[i].check) {
100-
changeBut.className = "btn btn-success";
101-
}
102-
103-
changeBut.addEventListener("click", function () {
104-
myLibrary[i].check = !myLibrary[i].check;
105-
render();
106-
});
107-
108-
// Add delete button to each row
109-
let delBut = document.createElement("button");
110-
delBut.id = i + 5;
111-
delBut.className = "btn btn-warning";
112-
delBut.innerHTML = "Delete";
113-
deleteCell.appendChild(delBut);
114-
115-
delBut.setAttribute("data-index", i);
116-
delBut.addEventListener("click", function () {
117-
let index = this.getAttribute("data-index");
118-
showError(`You've deleted title: ${myLibrary[index].title}`);
119-
myLibrary.splice(index, 1);
120-
render();
121-
});
122-
}
68+
tableBody.innerHTML = "";
69+
70+
myLibrary.forEach((book, index) => {
71+
const row = tableBody.insertRow();
72+
73+
const titleCell = row.insertCell();
74+
const authorCell = row.insertCell();
75+
const pagesCell = row.insertCell();
76+
const readCell = row.insertCell();
77+
const deleteCell = row.insertCell();
78+
79+
titleCell.textContent = book.title;
80+
authorCell.textContent = book.author;
81+
pagesCell.textContent = book.pages;
82+
83+
const toggleBtn = document.createElement("button");
84+
toggleBtn.className = book.read ? "btn btn-success" : "btn btn-primary";
85+
toggleBtn.textContent = book.read ? "Yes" : "No";
86+
toggleBtn.addEventListener("click", () => {
87+
book.read = !book.read;
88+
render();
89+
});
90+
readCell.appendChild(toggleBtn);
91+
92+
const delBtn = document.createElement("button");
93+
delBtn.className = "btn btn-warning";
94+
delBtn.textContent = "Delete";
95+
delBtn.addEventListener("click", () => {
96+
myLibrary.splice(index, 1);
97+
render();
98+
showError(`Deleted: ${book.title}`);
99+
});
100+
deleteCell.appendChild(delBtn);
101+
});
123102
}
124103

125-
// Handle error messages
126104
function showError(message) {
127-
let errorMessCont = document.getElementById("errorMessage");
128-
errorMessCont.textContent = message;
129-
errorMessCont.classList.add("show");
130-
131-
setTimeout(() => {
132-
errorMessCont.classList.remove("show");
133-
}, 3000);
134-
}
105+
errorBox.textContent = message;
106+
errorBox.classList.add("show");
107+
setTimeout(() => errorBox.classList.remove("show"), 3000);
108+
}

0 commit comments

Comments
 (0)