Search code examples
javascriptpreventdefault

how to use prevent default and toggle inside a function?


I'm trying to build a library where the user can write the info and the book and add it to the library. I created a modal form where the user can write the info and submit it.

This is the modal html

<form class="modal__container">
    <div class="modal">
        <div class="modal__content">
            <label for="">Title:</label>
            <input type="text" id="title"> 
        </div>
        <div class="modal__content">
            <label for="">Author:</label>
            <input type="text" id="author">
        </div>
        <div class="modal__content">
            <label for="">Pages:</label>
            <input type="number" id="pages">
        </div>
        <label for="">Have you read it?</label>
        <div>
            <label for="yes">Yes</label>
            <input type="radio" name ="read" value="yes">
            <label for="no">No</label>
            <input type="radio" name ="read" value="no">
        </div>
        
        <button class="add__book">Add</button>
        <button class="cancel">Cancel</button>
    </div>
</form>

This is the function that closes the modal when clicking on the cancel button

function toggle() {
    addBtn.addEventListener("click", () => {
        modal.style.display = "block";
        const cancel = document.querySelector(".cancel");
        cancel.addEventListener("click", () => {
            modal.style.display = "none";
        })
    })
}
toggle();

Here I have the constructor and the array to store the books

let myLibrary = [];

function Book(title, author, pages) {
    this.title = title,
    this.author = author,
    this.pages = pages
}

Now I want to create a function that submits the new book

submitBook.addEventListener("click", addBookToLibrary);

function addBookToLibrary() {

   let bookTitle = modalTitle.value;
   let bookAuthor = modalAuthor.value;
   let bookPages = modalPages.value;

   let book = new Book(bookTitle, bookAuthor, bookPages);
   myLibrary.push(book);

   console.log(bookTitle)
   console.log(bookAuthor)
   console.log(bookPages)
   toggle();

}

I see the info for half a second and then it disappears. I know I should use prevent default somewhere. I tried this

function addBookToLibrary(e) {
    e.preventDefault();
   let bookTitle = modalTitle.value;
   let bookAuthor = modalAuthor.value;
   let bookPages = modalPages.value;

   let book = new Book(bookTitle, bookAuthor, bookPages);
   myLibrary.push(book);

   console.log(bookTitle)
   console.log(bookAuthor)
   console.log(bookPages)
   toggle();

}

It displays the info correctly but it doesn't close the modal. How can I fix it?


Solution

  • You currently have an anonymous function that does what you want: close the modal. It's inside another anonymous function which opens the modal:

     addBtn.addEventListener("click", () => {
        modal.style.display = "block";
        const cancel = document.querySelector(".cancel");
        cancel.addEventListener("click", () => {
            modal.style.display = "none";
        });
    });
    

    You can "refactor" out two named functions from that code, like so:

     const hideModal = () => {
        modal.style.display = "none";
     };
     const showModal = () => {
        modal.style.display = "block";
        const cancel = document.querySelector(".cancel");
        cancel.addEventListener("click", hideModal);
     };
     addBtn.addEventListener("click", showModal);
    

    Then, inside your other event handlers, you can call either function:

    function addBookToLibrary() {
      // ...
      hideModal();
    }