|
1 | 1 | <!DOCTYPE html> |
2 | 2 | <html lang="en"> |
3 | | - <head> |
4 | | - <meta charset="UTF-8" /> |
5 | | - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
6 | | - <title>Library App</title> |
7 | | - |
8 | | - <link |
9 | | - rel="stylesheet" |
10 | | - href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" |
11 | | - /> |
12 | | - </head> |
13 | | - <body> |
14 | | - <div class="jumbotron text-center"> |
15 | | - <h1>Library</h1> |
16 | | - <p>Add books to your virtual library</p> |
17 | | - </div> |
18 | | - |
19 | | - <button data-toggle="collapse" data-target="#formCollapse" class="btn btn-info"> |
20 | | - Add new book |
21 | | - </button> |
22 | | - |
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 |
36 | | - </label> |
37 | | - |
38 | | - <button type="submit" class="btn btn-primary mt-3">Submit</button> |
39 | | - </form> |
40 | | - </div> |
41 | | - |
42 | | - <table class="table" id="displayTable"> |
43 | | - <thead class="thead-dark"> |
44 | | - <tr> |
45 | | - <th>Title</th> |
46 | | - <th>Author</th> |
47 | | - <th>Pages</th> |
48 | | - <th>Read</th> |
49 | | - <th>Action</th> |
50 | | - </tr> |
51 | | - </thead> |
52 | | - <tbody></tbody> |
53 | | - </table> |
54 | | - |
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> |
146 | | - </body> |
| 3 | +<head> |
| 4 | + <meta charset="UTF-8" /> |
| 5 | + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| 6 | + <title>Library App</title> |
| 7 | + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" /> |
| 8 | +</head> |
| 9 | +<body> |
| 10 | + <div class="jumbotron text-center"> |
| 11 | + <h1>Library</h1> |
| 12 | + <p>Add books to your virtual library</p> |
| 13 | + </div> |
| 14 | + |
| 15 | + <button data-toggle="collapse" data-target="#formCollapse" class="btn btn-info">Add new book</button> |
| 16 | + |
| 17 | + <div id="formCollapse" class="collapse mt-3"> |
| 18 | + <form id="bookForm" class="form-group"> |
| 19 | + <label for="titleInput">Title:</label> |
| 20 | + <input id="titleInput" class="form-control" required /> |
| 21 | + |
| 22 | + <label for="authorInput">Author:</label> |
| 23 | + <input id="authorInput" class="form-control" required /> |
| 24 | + |
| 25 | + <label for="pagesInput">Pages:</label> |
| 26 | + <input id="pagesInput" type="number" class="form-control" required /> |
| 27 | + |
| 28 | + <label class="form-check-label mt-2"> |
| 29 | + <input type="checkbox" class="form-check-input" id="readCheckbox" /> Read |
| 30 | + </label> |
| 31 | + |
| 32 | + <button type="submit" class="btn btn-primary mt-3">Submit</button> |
| 33 | + </form> |
| 34 | + </div> |
| 35 | + |
| 36 | + <table class="table" id="displayTable"> |
| 37 | + <thead class="thead-dark"> |
| 38 | + <tr> |
| 39 | + <th>Title</th> |
| 40 | + <th>Author</th> |
| 41 | + <th>Pages</th> |
| 42 | + <th>Read</th> |
| 43 | + <th>Action</th> |
| 44 | + </tr> |
| 45 | + </thead> |
| 46 | + <tbody></tbody> |
| 47 | + </table> |
| 48 | + |
| 49 | + |
| 50 | + <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> |
| 51 | + <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script> |
| 52 | + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script> |
| 53 | + |
| 54 | + |
| 55 | + <script type="module" src="script.js"></script> |
| 56 | +</body> |
147 | 57 | </html> |
0 commit comments