|
| 1 | +// Local storage key |
| 2 | +const STORAGE_KEY = "myLibraryBooks"; |
| 3 | + |
| 4 | +// Book list |
1 | 5 | let myLibrary = []; |
2 | 6 |
|
3 | | -window.addEventListener("load", function (e) { |
4 | | - populateStorage(); |
| 7 | +// Cached DOM elements |
| 8 | +const title = document.getElementById("title"); |
| 9 | +const author = document.getElementById("author"); |
| 10 | +const pages = document.getElementById("pages"); |
| 11 | +const check = document.getElementById("check"); |
| 12 | +const addBtn = document.getElementById("addBtn"); |
| 13 | +const displayBody = document.querySelector("#display tbody"); |
| 14 | + |
| 15 | +function Book(title, author, pages, read) { |
| 16 | + this.title = title; |
| 17 | + this.author = author; |
| 18 | + this.pages = pages; |
| 19 | + this.read = !!read; |
| 20 | +} |
| 21 | + |
| 22 | +// Load from localStorage on page start |
| 23 | +window.addEventListener("DOMContentLoaded", () => { |
| 24 | + loadLibrary(); |
5 | 25 | render(); |
6 | 26 | }); |
7 | 27 |
|
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(); |
| 28 | +// Load saved books or create default sample books |
| 29 | +function loadLibrary() { |
| 30 | + const stored = localStorage.getItem(STORAGE_KEY); |
| 31 | + |
| 32 | + if (stored) { |
| 33 | + myLibrary = JSON.parse(stored); |
| 34 | + } else { |
| 35 | + // First-time sample books |
| 36 | + myLibrary = [ |
| 37 | + new Book("Robinson Crusoe", "Daniel Defoe", 252, true), |
| 38 | + new Book("The Old Man and the Sea", "Ernest Hemingway", 127, true) |
| 39 | + ]; |
| 40 | + saveLibrary(); |
20 | 41 | } |
21 | 42 | } |
22 | 43 |
|
23 | | -const title = document.getElementById("title"); |
24 | | -const author = document.getElementById("author"); |
25 | | -const pages = document.getElementById("pages"); |
26 | | -const check = document.getElementById("check"); |
| 44 | +// Save books to localStorage |
| 45 | +function saveLibrary() { |
| 46 | + localStorage.setItem(STORAGE_KEY, JSON.stringify(myLibrary)); |
| 47 | +} |
27 | 48 |
|
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 | | - ) { |
| 49 | +// Clear form after adding |
| 50 | +function clearForm() { |
| 51 | + title.value = ""; |
| 52 | + author.value = ""; |
| 53 | + pages.value = ""; |
| 54 | + check.checked = false; |
| 55 | +} |
| 56 | + |
| 57 | +// Submit new book |
| 58 | +function submitBook() { |
| 59 | + if (!title.value.trim() || !author.value.trim() || !pages.value) { |
37 | 60 | alert("Please fill all fields!"); |
38 | | - return false; |
39 | | - } else { |
40 | | - let book = new Book(title.value, title.value, pages.value, check.checked); |
41 | | - library.push(book); |
42 | | - render(); |
| 61 | + return; |
43 | 62 | } |
44 | | -} |
45 | 63 |
|
46 | | -function Book(title, author, pages, check) { |
47 | | - this.title = title; |
48 | | - this.author = author; |
49 | | - this.pages = pages; |
50 | | - this.check = check; |
| 64 | + const book = new Book( |
| 65 | + title.value.trim(), |
| 66 | + author.value.trim(), |
| 67 | + Number(pages.value), |
| 68 | + check.checked |
| 69 | + ); |
| 70 | + |
| 71 | + myLibrary.push(book); |
| 72 | + saveLibrary(); |
| 73 | + render(); |
| 74 | + clearForm(); |
| 75 | + |
| 76 | + // Collapse form |
| 77 | + $("#addForm").collapse("hide"); |
51 | 78 | } |
52 | 79 |
|
| 80 | +addBtn.addEventListener("click", submitBook); |
| 81 | + |
| 82 | +// Render table |
53 | 83 | 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 |
61 | | - let length = myLibrary.length; |
62 | | - for (let i = 0; i < length; i++) { |
63 | | - let row = table.insertRow(1); |
64 | | - let titleCell = row.insertCell(0); |
65 | | - let authorCell = row.insertCell(1); |
66 | | - let pagesCell = row.insertCell(2); |
67 | | - let wasReadCell = row.insertCell(3); |
68 | | - let deleteCell = row.insertCell(4); |
69 | | - titleCell.innerHTML = myLibrary[i].title; |
70 | | - authorCell.innerHTML = myLibrary[i].author; |
71 | | - pagesCell.innerHTML = myLibrary[i].pages; |
72 | | - |
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); |
78 | | - let readStatus = ""; |
79 | | - if (myLibrary[i].check == false) { |
80 | | - readStatus = "Yes"; |
81 | | - } else { |
82 | | - readStatus = "No"; |
83 | | - } |
84 | | - changeBut.innerText = readStatus; |
85 | | - |
86 | | - changeBut.addEventListener("click", function () { |
87 | | - myLibrary[i].check = !myLibrary[i].check; |
| 84 | + displayBody.innerHTML = ""; |
| 85 | + |
| 86 | + myLibrary.forEach((b, i) => { |
| 87 | + const row = document.createElement("tr"); |
| 88 | + |
| 89 | + row.innerHTML = ` |
| 90 | + <td>${b.title}</td> |
| 91 | + <td>${b.author}</td> |
| 92 | + <td>${b.pages}</td> |
| 93 | + <td></td> |
| 94 | + <td></td> |
| 95 | + `; |
| 96 | + |
| 97 | + // Read button |
| 98 | + const readBtn = document.createElement("button"); |
| 99 | + readBtn.className = "btn btn-sm btn-success btn-small"; |
| 100 | + readBtn.textContent = b.read ? "Yes" : "No"; |
| 101 | + readBtn.addEventListener("click", () => { |
| 102 | + myLibrary[i].read = !myLibrary[i].read; |
| 103 | + saveLibrary(); |
88 | 104 | render(); |
89 | 105 | }); |
| 106 | + row.children[3].appendChild(readBtn); |
90 | 107 |
|
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}`); |
99 | | - myLibrary.splice(i, 1); |
100 | | - render(); |
| 108 | + // Delete button |
| 109 | + const delBtn = document.createElement("button"); |
| 110 | + delBtn.className = "btn btn-sm btn-warning btn-small"; |
| 111 | + delBtn.textContent = "Delete"; |
| 112 | + delBtn.addEventListener("click", () => { |
| 113 | + if (confirm(`Delete "${b.title}"?`)) { |
| 114 | + myLibrary.splice(i, 1); |
| 115 | + saveLibrary(); |
| 116 | + render(); |
| 117 | + } |
101 | 118 | }); |
102 | | - } |
| 119 | + row.children[4].appendChild(delBtn); |
| 120 | + |
| 121 | + displayBody.appendChild(row); |
| 122 | + }); |
103 | 123 | } |
0 commit comments