JS function repeating

ghz 7months ago ⋅ 83 views
    const myLibrary = [];
    
    function Book(title, author, numPages, readStatus) {
      // Constructor for a book Object
      this.title = title;
      this.author = author;
      this.numPages = numPages;
      this.readStatus = readStatus;
      this.info = function () {
        return `${title} by ${author}, ${numPages} pages, ${readStatus}`;
      };
    }
    
    function addBookToLibrary(title, author, numPages, readStatus) {
      // Add a new book object to array
      const newBook = new Book(title, author, numPages, readStatus);
      myLibrary.push(newBook);
    }
    
    function deleteBooks(index) {
      // Remove book from array at provided index
      myLibrary.splice(index, 1);
    }
    
    function displayBooks(arr) {
      // Iterate array and display the object to the page
      const mainContainer = document.querySelector(".main-container");
      mainContainer.innerHTML = "";
    
      for (let i = 0; i < arr.length; i++) {
        const div = document.createElement("div");
        div.classList.add("book-card");
        div.setAttribute("id", `arr[${i}]`);
    
        div.innerHTML = `<span class="book-title">Title: ${arr[i].title}</span>
          <span class="book-author">Author: ${arr[i].author}</span>
          <span class="book-pages">Pages: ${arr[i].numPages}</span>
          <div class="read-checkbox">
            <input type="checkbox" id="readStatus" name="readStatus">
            <label for="readStatus">Have read.</label>
          </div>`;
    
        mainContainer.appendChild(div);
    
        if (arr[i].readStatus == true) {
          document
            .getElementById(`arr[${i}]`)
            .getElementsByTagName("input").readStatus.checked = true;
        }
      }
    }
    
    function newBookForm() {
      // Displays a popup form to add a new book when the new button is pressed
      document.getElementById("newBook-form").style.display = "block";
    }
    
    function getFormInfo() {
      const form = document.getElementById("book-form");
      form.addEventListener("submit", (event) => {
        event.preventDefault();
        console.log("Hi There");
        const title = form.bookTitle.value;
        const author = form.bookAuthor.value;
        const pages = form.bookPages.value;
    
        if (document.getElementById("read-yes").checked) {
          addBookToLibrary(title, author, pages, true);
        } else {
          addBookToLibrary(title, author, pages, false);
        }
    
        //addBookToLibrary(title, author, pages, false);
    
        displayBooks(myLibrary);
        form.reset();
    
        document.getElementById("newBook-form").style.display = "none";
      });
    }

**Edited with full code, I tried to be vague by shortening but now after comments and rereading I was just more confusing.

Also here is the form code from the html, since it was asked for:

    <form id="book-form">
            <h1>Add a new book</h1>
    
            <div class="book-formField">
              <label for="bookTitle">Title: </label>
              <input type="text" name="bookTitle" id="bookTitle" required />
            </div>
            <div class="book-formField">
              <label for="bookAuthor">Author: </label>
              <input type="text" name="bookAuthor" id="bookAuthor" required />
            </div>
            <div class="book-formField">
              <label for="bookPages">Number of pages: </label>
              <input type="text" name="bookPages" id="bookPages" required />
            </div>
            <fieldset>
              <legend>Have you read it</legend>
              <div class="read-radio">
                <input
                  type="radio"
                  id="read-yes"
                  name="readStatus-radio"
                  value="yes"
                />
                <label for="read-yes">Yes</label>
    
                <input
                  type="radio"
                  id="read-no"
                  name="readStatus-radio"
                  value="no"
                />
                <label for="read-no">No</label>
              </div>
            </fieldset>
            <div id="formButton-div">
              <input
                type="submit"
                onclick="getFormInfo()"
                id="form-button"
                value="Add Book"
              />
            </div>
          </form>

When the button is pressed on the page the entire function works fine the first time but each form works but also adds an extra empty form. Just looking for any suggestions on where to look.

The form adds form info as an object to an array of objects.

Added a breakpoint at the function start and when skipping through the breaks, right after closing bracket for the arrow function it restarts the start of the arrow function.

Answers

It seems like you are encountering an issue where each time the form is submitted, an extra empty form is added to the page. This might be due to the fact that the getFormInfo function is being called multiple times, potentially due to event listeners being added multiple times.

To prevent this issue, you can ensure that the getFormInfo function is only called once, either by removing the onclick attribute from the submit button and attaching the event listener directly in your JavaScript code, or by adding a check to ensure that the event listener is only added once.

Here's how you can modify your code:

  1. Remove the onclick attribute from the submit button in your HTML:
<input type="submit" id="form-button" value="Add Book" />
  1. Add an event listener to the form submit event in your JavaScript code:
function setupFormEventListener() {
  const form = document.getElementById("book-form");
  form.addEventListener("submit", (event) => {
    event.preventDefault();
    console.log("Hi There");
    const title = form.bookTitle.value;
    const author = form.bookAuthor.value;
    const pages = form.bookPages.value;

    if (document.getElementById("read-yes").checked) {
      addBookToLibrary(title, author, pages, true);
    } else {
      addBookToLibrary(title, author, pages, false);
    }

    displayBooks(myLibrary);
    form.reset();

    document.getElementById("newBook-form").style.display = "none";
  });
}

// Call the function to set up the event listener
setupFormEventListener();

By setting up the event listener programmatically like this, you ensure that it is only added once, regardless of how many times your JavaScript code is executed.

Additionally, make sure that there are no other places in your code where getFormInfo is being called unnecessarily.