FYI, I’m working on a basic web library interface that allows users to add book info and get that info displayed. After some debugging, I notice that my function responsible for taking the book info that people input didn’t function as I wanted. To be specific, document.getElementbyID()
can’t seem to select my html <select>
element even though it could select my input fields with no problems. In addition, it seems that the bookInfo
variable is empty for some reasons unknown to me.
My CSS, for a more user-friendly design. There’s nothing wrong with it, just something to make viewing my preview a bit easier:
let myLibrary = [];
function Book(author,title,pages,readStatus) {
this.author = author
this.title = title
this.pages = pages
this.readStatus = readStatus
}
function addBooktoLibrary(book) {
myLibrary.push(book)
}
document.querySelector('.new').addEventListener('click', ()=>{
document.getElementById('add-dialog').showModal()
})
document.getElementById('cancel').addEventListener('click', ()=>{
document.getElementById('add-dialog').close()
})
function displayBook(bookInfo){
const bookElement = document.createElement('div');
const buttonDiv = document.createElement('div')
const removeButton = document.createElement('button');
removeButton.innerText = 'Remove'
bookElement.innerHTML = `Title: ${bookInfo.title}<br> Author: ${bookInfo.author}<br> Pages: ${bookInfo.pages}<br> Status: ${bookInfo.readStatus}`;
buttonDiv.appendChild(removeButton)
buttonDiv.classList.add('buttonDiv')
bookElement.appendChild(buttonDiv)
bookElement.classList.add('book')
removeButton.classList.add('remove')
document.querySelector('.card-container').appendChild(bookElement);
}
function processInfo(){
let bookInfo = []
document.getElementById("confirmBtn").addEventListener('click', ()=>{
author = document.getElementById("author")
title = document.getElementById("title")
pages = document.getElementById("pages")
readStatus = document.getElementById('status') //Line in question
readStatusInsert = readStatus.options[readStatus.selectedIndex]
bookInfo[author] = author.value
bookInfo[title] = title.value
bookInfo[pages] = pages.value
bookInfo[readStatusInsert] = readStatusInsert.text
})
let newBook = new Book(bookInfo.author, bookInfo.title, bookInfo.pages, bookInfo.readStatusInsert)
addBooktoLibrary(newBook)
}
html{
height: 100vh;
}
body{
margin: 0;
padding: 0;
height: 100%;
}
.header{
background-color: blue;
height: 7%;
display: flex;
align-items: center;
}
.new{
margin-left: 5vw;
}
.card-container{
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
}
.book{
display: flex;
flex-direction: column;
width: 20%;
border: solid;
margin: 15px;
}
.buttonDiv{
display: flex;
justify-content: center;
}
form{
display: flex;
align-items: center;
flex-direction: column;
}
input, select{
margin: 5px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="logic.js" defer></script>
<title>Library</title>
<link rel="stylesheet" href="styles.css" defer>
</head>
<body>
<div class="header">
<button class="new">New</button>
</div>
<div>
<dialog id="add-dialog">
<form>
<label>Add book</label>
<input type="text" placeholder="Author" id="author" required>
<input type="text" placeholder="Title" id="title" required>
<input type="number" placeholder="Pages" id="pages" min="10">
<select id="status">
<option value="">Select your book status</option>
<option value="reading">Reading</option>
<option value="completed">Completed</option>
<option value="onhold">On-hold</option>
<option value="dropped">dropped</option>
</select>
<div>
<button id='cancel' formmethod="dialog">Cancel</button>
<button id="confirmBtn" type="button" onclick="processInfo()">Confirm</button>
</div>
</form>
</dialog>
</div>
<div class="card-container"></div>
</body>
</html>
3
Answers
Here in script.js Change this
With:
In the addBooktoLibrary function, you are pushing the book parameter directly to myLibrary, which isn’t recommended. Instead, you should be pushing the book object you’ve just created. Change this:
To:
Now, your processInfo function should only process the form data without the unnecessary event listener:
Make these changes, and your code should work more accurately.
Code should look like this :
These Are the Best practices 😉
Based on my testing all the values were being properly fetched, including for the select. However, the
bookInfo
variable was not storing the values correctly.The indexes for bookinfo were not in strings so they were taking the HTML element variables as the index and that was creating some issues.
Try replacing the code below
To the following
bookInfo is populated correctly post this correction
In arrays, we cannot do that:
Instead I recommend putting it an object, then push it