@@ -23,12 +23,6 @@ class Book {
2323 }
2424}
2525
26- // Load library when page starts
27- window . addEventListener ( "DOMContentLoaded" , ( ) => {
28- loadLibrary ( ) ; // Called once — no duplicated calls
29- render ( ) ;
30- } ) ;
31-
3226// Load from localStorage
3327function loadLibrary ( ) {
3428 const stored = localStorage . getItem ( STORAGE_KEY ) ;
@@ -62,27 +56,36 @@ function clearForm() {
6256function submitBook ( ) {
6357 const title = titleInput . value . trim ( ) ;
6458 const author = authorInput . value . trim ( ) ;
65- const pages = pagesInput . value ;
66-
67- // FEEDBACK APPLIED: improved validation and normalization
68- if ( ! title || ! author || ! pages || Number ( pages ) <= 0 ) {
69- alert ( "Please fill all fields correctly." ) ;
59+ const rawPages = pagesInput . value . trim ( ) ;
60+
61+ // --- STRICT & SAFE PAGE VALIDATION ---
62+ const pagesNum = Number ( rawPages ) ;
63+
64+ if (
65+ ! title ||
66+ ! author ||
67+ ! rawPages ||
68+ ! Number . isInteger ( pagesNum ) ||
69+ pagesNum <= 0 ||
70+ pagesNum > 10000 || // reject unrealistic values
71+ ! isFinite ( pagesNum ) // rejects Infinity and NaN
72+ ) {
73+ alert ( "Please enter a valid page count (1–10,000)." ) ;
7074 return ;
7175 }
7276
73- const book = new Book ( title , author , pages , readCheckbox . checked ) ;
77+ const book = new Book ( title , author , pagesNum , readCheckbox . checked ) ;
7478
7579 myLibrary . push ( book ) ;
7680 saveLibrary ( ) ;
7781 render ( ) ;
7882 clearForm ( ) ;
7983
80- // Collapse form
81- $ ( "#addForm" ) . collapse ( "hide" ) ;
84+ // Collapse form using Bootstrap 5 JS API (plain JS, no jQuery)
85+ const collapse = bootstrap . Collapse . getOrCreateInstance ( document . getElementById ( "addForm" ) ) ;
86+ collapse . hide ( ) ;
8287}
8388
84- addBtn . addEventListener ( "click" , submitBook ) ;
85-
8689// Render the table
8790function render ( ) {
8891 // FEEDBACK APPLIED: efficient clearing of table
@@ -113,14 +116,11 @@ function render() {
113116 readCell . appendChild ( readBtn ) ;
114117
115118 const deleteCell = document . createElement ( "td" ) ;
116-
117- // FEEDBACK APPLIED: consistent naming (deleteBtn)
118119 const deleteBtn = document . createElement ( "button" ) ;
119120 deleteBtn . textContent = "Delete" ;
120121 deleteBtn . className = "btn btn-sm btn-warning btn-small" ;
121122
122123 deleteBtn . addEventListener ( "click" , ( ) => {
123- // FEEDBACK APPLIED: confirmation before delete (acceptable)
124124 if ( confirm ( `Delete "${ book . title } "?` ) ) {
125125 myLibrary . splice ( index , 1 ) ;
126126 saveLibrary ( ) ;
@@ -135,3 +135,12 @@ function render() {
135135 displayBody . appendChild ( row ) ;
136136 } ) ;
137137}
138+
139+ // ---------------------------
140+ // PAGE LOAD SETUP (all in one place)
141+ // ---------------------------
142+ window . addEventListener ( "DOMContentLoaded" , ( ) => {
143+ loadLibrary ( ) ; // load saved books or defaults
144+ render ( ) ; // display books
145+ addBtn . addEventListener ( "click" , submitBook ) ; // set up add button
146+ } ) ;
0 commit comments