I'm trying to loop through array of objects to display them on a grid based off of input values for my library project. My code for loop is
const addBook = (ev) => {
ev.preventDefault();
let myLibrary = [];
let bookInfo = {
title: document.getElementById('title').value,
author: document.getElementById('author').value,
pages: document.getElementById('pages').value,
}
myLibrary.push(bookInfo)
for (i = 0; i < myLibrary.length; i ) {
console.log(myLibrary)
var container = document.getElementById('book-shelf')
var div = document.createElement('div')
div.classList.add('cell')
container.appendChild(div);
}
var submitBtn = document.querySelector('.submit-btn');
submitBtn.addEventListener('click', addBook)
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Each time I enter title,author, and pages value and click submit button, it goes through and gives me a cell. If try to add another book, it gives me 3 cells rather then 2. Doing another add gives me 6 instead of 3. How can I make it where I can add a book each time one by one rather then it adding multiple times?
CodePudding user response:
There are three main issues.
A missing curly brace after the function and before the button listener.
myLibrary
is being redefined each time the function is called which is one of the reasons you're having to look over the data each time. You want to define it outside the function so you can add one book at a time to it whenaddBook
is called.With
myLibrary
no longer being redefined each time there's no need for the loop. We can just add the HTML for the book to the book shelfonSubmit
.
(Note: In this working example (I've added some HTML for a table, and the inputs and buttons, and created some code to add the new book to the shelf), I've renamed the myLibrary
variable to bookShelf
to keep things consistent with the HTML naming.)
// Cache all the elements up front
const titleEl = document.getElementById('title');
const authorEl = document.getElementById('author');
const pagesEl = document.getElementById('pages');
const bookshelfEl = document.getElementById('bookshelf');
const submitBtn = document.querySelector('.submit-btn');
// Add the listener
submitBtn.addEventListener('click', addBook, false);
titleEl.focus();
// Our bookShelf variable is now
// outside the function
const bookShelf = [];
function addBook() {
// Because we've cached the elements
// we can now just grab the values from each
const bookInfo = {
title: titleEl.value,
author: authorEl.value,
pages: pagesEl.value,
}
bookShelf.push(bookInfo);
// Once we've added our book we can grab the
// title, author, and pages variables from it
const { title, author, pages } = bookInfo;
// Create a row for the table
const row = document.createElement('tr')
// Create some HTML and add it to the div
row.innerHTML = `
<td>${title}</td>
<td>${author}</td>
<td>${pages}</td>
`;
bookshelfEl.appendChild(row);
}
table { border-collapse: collapse; border: 2px solid #565656; width: 100%; }
td { text-align: center; }
.heading { background-color: #efefef; border-top: solid thin #565656; }
tr { border: solid thin #ababab; }
<input placeholder="Title" id="title" />
<input placeholder="Author" id="author" />
<input placeholder="Pages" id="pages" />
<button type="button" class="submit-btn">Submit</button>
<H3>Book shelf</H3>
<table>
<tbody id="bookshelf">
<tr class="heading">
<td>Title</td>
<td>Author</td>
<td>Pages</td>
</tr>
</tbody>
</table>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Additional documentation
CodePudding user response:
Your issue is with the loop. Each time you click the submit button, you add a cell for each item in myLibrary
in this block:
for (i = 0; i < myLibrary.length; i ) {
console.log(myLibrary)
var container = document.getElementById('book-shelf')
var div = document.createElement('div')
div.classList.add('cell')
container.appendChild(div);
}
I don't think you need to loop through the array each time. Just add the cell directly whenever you are adding bookInfo data to myLibrary
, without using for
loop e.g
const addBook = (ev) => {
ev.preventDefault();
let myLibrary = [];
let bookInfo = {
title: document.getElementById('title').value,
author: document.getElementById('author').value,
pages: document.getElementById('pages').value,
}
myLibrary.push(bookInfo)
var container = document.getElementById('book-shelf')
var div = document.createElement('div')
div.classList.add('cell')
container.appendChild(div);
}
var submitBtn = document.querySelector('.submit-btn');
submitBtn.addEventListener('click', addBook)