Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to get an element inside a function javascript

I’m trying to use the value that each book has on its "status" and make the function "changeStatus()" run but "book.status" is defined inside a function, how can I get it? or is there any other way i can change the button behavior on click? I tried using a querySelector but it only allows me to click one button per refresh

let books = [];

const $name = document.querySelector("#name");
const $author = document.querySelector("#author");
const $status = document.querySelector("#status");
const $pages = document.querySelector("#pages"); 
const $tableBody = document.querySelector("#book-table-body");


function addBookToTable() {
    // checkLocalStorage();
    $tableBody.innerHTML = "";
    books.forEach((book) => {
      const htmlBook = `
        <tr>
          <td>${book.title}</td>
          <td>${book.author}</td>
          <td>${book.pages}</td>
          <td><button class="status-button" onclick="changeStatus()">${book.status}</button></td>
          <td><button class="delete">delete</button></td>
        </tr>
        `;
      $tableBody.insertAdjacentHTML("afterbegin", htmlBook);
    });
  }

 function changeStatus(){
   
 }

const addBook = (event) => {
    event.preventDefault();
    let book = {
        title: $("#title").val(),
        author: $("#author").val(),
        pages: $("#pages").val(),
        status: $("#status").val(),
    };
    const cb = document.querySelector("#status");

    if (cb.checked === true) {
        book.status = "read";
    } else {
        book.status = "not read";

    }

    books.push(book);

    document.forms[0].reset();
    // Update DOM
    addBookToTable(book);

    const deleteBtn = document.querySelector(".delete");
    deleteBtn.addEventListener("click", function deleteBook(){
        books.splice(books.indexOf(book), 1);
        addBookToTable(book);
    })

    // const myBtn = document.querySelector(".status-button");
    // myBtn.addEventListener('click', function changeStatus(){
    //     if (book.status === "read"){
    //         myBtn.innerHTML="not read"
    //         book.status = "not read"
    //     } 
    //     else if(book.status === "not read"){
    //         myBtn.innerHTML = "read";
    //         book.status = "read"
    //     }
    // }
    // );


    localStorage.setItem("myMangaList", JSON.stringify(books));
};

function popForm() {
    $("#popup").removeClass("hide");
}

function minimizeForm(){
    $("#popup").addClass("hide");
}

function hideForm() {
    $("#popup").addClass("hide");
    $("#main-page").removeClass("hide");
}

function toggle() {
    $("#main-page").addClass("hide");

}
* {
  font-family: 'Lato', sans-serif;
  text-align: center;
  /* background-image: url(./images/image.jpg);
  background-position: bottom;
  background-size: cover; */
}

.hide {
  display: none;
}

.hide-form {
  background-color: transparent;
  color: white;
  border: none;
  cursor: pointer;
  font-size: 1.5rem;
  margin-top: 20px;
  margin-right: 15px;
  position: absolute;
  top: 0;
  right: 0;
}

h1 {
  font-size: 2.5rem;
  font-weight: 900;
  font-family: 'Work Sans', sans-serif;
}

h1 span {
  color: #48abe0;
}

table {
  border-collapse: collapse;
  width: 100%;
}

td,
th {
  /* border: 1px solid #dddddd; */
  text-align: center;
  padding: 8px;
}


#main-page {
  margin-right: 80px;
  margin-left: 80px;

}

#addBook {
  border-radius: 70%;
  background-color: #48abe0;
  color: white;
  border: none;
  padding: 5px;
  font-size: 31px;
  height: 65px;
  width: 65px;
  box-shadow: 0 2px 4px darkslategray;
  cursor: pointer;
  transition: all 0.2s ease;
  position: fixed;
  bottom: 25px;
  right: 25px;
}


#popup {
  /* display: flex; */
  justify-content: center;
  align-items: center;
  flex-direction: column;
  gap: 30px;
  padding-top: 50px;
  padding-bottom: 50px;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 300px;
  background: #48abe0;
  border-radius: 10px;
}

#popup input {
  width: 80%;
  padding: 15px;
  margin-top: 25px;
  border: 1px solid;
  border-radius: 5px;
  outline: none;
  color: white;
  font-weight: bold;
  font-size: 1em;
  background: #48abe0;

}

.status-box {
  margin-top: 25px;
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <!-- Stylesheet -->
    <link rel="stylesheet" href="style.css">

    <!-- fonts -->
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link
        href="https://fonts.googleapis.com/css2?family=Edu+NSW+ACT+Foundation:wght@500&family=Edu+QLD+Beginner:wght@400;600;700&family=Edu+TAS+Beginner:wght@700&family=Josefin+Sans:wght@300&family=Lato&family=Montserrat:wght@100;600&family=Mouse+Memoirs&family=Poppins:ital,wght@0,500;1,200&family=Quicksand:wght@300&family=Ubuntu:wght@300&family=Work+Sans:wght@200&display=swap"
        rel="stylesheet">

    <title>Library</title>
</head>

<body>
    <h1>My <span>Manga</span> Library</h1>

    <div id="popup" class="hide">
        <form>
            <button class="hide-form" onclick=" minimizeForm()">X</button>
            <!-- <label for="title">Manga Title:</label> -->
            <input type="text" id="title" placeholder="Title eg: One Piece"> <br>

            <!-- <label for="author">Author:</label> -->
            <input type="text" id="author" placeholder="Author eg: Eichiro Oda"><br>

            <!-- <label for="pages">Pages:</label> -->
            <input type="text" id="pages" placeholder="Pages eg: 2000"><br>

            <div class="status-box">
                <label for="status">Read the book</label>
                <input type="checkbox" id="status" name="status" value="">

            </div>


            <button type="submit" id="submit" onclick="addBook(event); hideForm()">Submit</button>

        </form>
    </div>


    <!-- onclick="addBook() -->
    <div id="main-page">
        <h1>list</h1>
        <div id="books-grid">
            <table id="di-books">
                <tr>
                    <th>Name</th>
                    <th>Author</th>
                    <th>Pages</th>
                    <th>Status</th>
                    <th></th>
                </tr>
                <tbody id="book-table-body"></tbody>
            </table>
        </div>

        <button id="addBook" onclick="popForm(); toggle()">+</button>

    </div>

    <!-- JQuery -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="app.js"></script>
</body>

</html>

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

If you want to update the status of a book, you need a way to identify each book uniquely. Although it is possible to do this based on e.g. title or author, the reality is that those fields are not guaranteed to be unique.

Typically, you’d use the Id number of a database entry, but since you’re using mock data that isn’t realy an option here. We could e.g. use a UUID though:

    let book = {
        title: $("#title").val(),
        author: $("#author").val(),
        pages: $("#pages").val(),
        status: $("#status").val(),
        id: self.crypto.randomUUID() //Warning: might only work with HTTPS sites. Implement your own unique id in any way you please.
    };

Now we have a unique id, we can use it to couple each status button with a unique book entry. Lets adjust the HTML:

 const htmlBook = `
        <tr>
          <td>${book.title}</td>
          <td>${book.author}</td>
          <td>${book.pages}</td>
          <td><button class="status-button" onclick="changeStatus('${book.id}')">${book.status}</button></td>
          <td><button class="delete">delete</button></td>
        </tr>
        `;

and lets write the update function:

 function changeStatus(id){
        //step 1: find our book with the matching unique id
        let book = books.filter(book => book.id === id)[0];
         //Step 2: update the book its status
         if (book.status === "read"){
             book.status = "not read";
         } 
         else if(book.status === "not read"){
             book.status = "read"
         }
   //Step 3: update our table with the new data.
   addBookToTable();
     };

And voila, we’re able to switch the status of any book!

I tried to stick as close to your code as possible so you’d better understand it, but a lot more improvements can be implemented, such as event listeners instead of explicitly calling the changeStatus function, but I’ll leave that as an exercise to you.

Full working example:
codepen

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading