Home > front end >  Looping through array of objects after button press
Looping through array of objects after button press

Time:11-17

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.

  1. A missing curly brace after the function and before the button listener.

  2. 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 when addBook is called.

  3. 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 shelf onSubmit.

(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)

  • Related