0

I have a function addBookToList() that creates an HTML row of elements. I have a button inside the row along with other elements.

I'm trying to add an "onclick" event with a toggle() function to that button in order to change the read status of a book (yes or no).

Is there a way I can click on that button and have the function toggle() changing the value of the previous element sibling (value.read) and back? I added the event but I don't know how to target the button and value.read.

// Book constructor
function Book(author, title, pages, read) {
  this.title = title;
  this.author = author;
  this.pages = pages;
  this.read = read;
 }

// Empty array to store books
let myLibrary = [];

// Event listener when clicking SUBMIT button on the form
form.addEventListener('submit', (e) => {
e.preventDefault();

// Hide form and show home page
document.querySelector('.table-box').style.display = 'block';
document.querySelector('.para-div').style.display = 'block';
form.style.display = 'none';

// Get values from User
let title = document.querySelector('#title').value;
let author = document.querySelector('#author').value;
let pages = document.querySelector('#num-pages').value;
let read = getRead();

// Instantiate book
const book = new Book(author, title, pages, read);

// Push book to the library, show it on the UI and clear the form
myLibrary.push(book);
addBookToList();

// Add book to Local Storage
addBook();

// Show success alert
showAlert('Book added!', 'success');

// Clear form
form.reset();

});

// Get value of radio button
 function getRead() {
    const radioBtn = document.querySelectorAll('input[name="radio"]');
    let selectValue;

    for(const i of radioBtn) {
      if(i.checked) {
         selectValue = i.value;
      }
    }
    return selectValue;
}


function addBookToList() {

  // Create new row element
  const row = document.createElement('tr');

  // Loop through myLibrary array
  myLibrary.forEach(value => {

    // Add the book to the table
        row.innerHTML = `
        <td>${value.title}</td>
        <td>${value.author}</td>
        <td>${value.pages}</td>
        <td>${value.read}</td>
        <td><button class="toggle" onclick="toggle()">Change read status</button></td>
        <td><a href="#" class="btn delete">X</a></td>`;
  });
  // Append the row to list
  list.appendChild(row);
  }
1987mat
  • 5
  • 4

1 Answers1

0

In your function addBookToList, you can use IIFE.

function addBookToList() {

  // Create new row element
  const row = document.createElement('tr');

  // Loop through myLibrary array
  myLibrary.forEach(value => {

    // Add the book to the table
        row.innerHTML = `
        <td>${value.title}</td>
        <td>${value.author}</td>
        <td>${value.pages}</td>
        <td>${value.read}</td>
        <td><button class="toggle">Change read status</button></td>
        <td><a href="#" class="btn delete">X</a></td>`;
  });
  // Append the row to list
  list.appendChild(row);
  const toggleBtn = document.querySelector('.toggle');
  toggleBtn.onclick = (function(value) {
     return function(){
       // update read property on value
          value.read = !value.read;
     }
   })(value);
  }
gaurav soni
  • 206
  • 1
  • 10
  • I tried that but for some reason I get "value is not defined at addBookToList".. – 1987mat Feb 24 '21 at 21:06
  • I believe you are trying to do something like this. https://jsbin.com/xalegujari/1/edit?html,js,console,output – gaurav soni Feb 24 '21 at 21:26
  • Yes thanks, I see the alert changes every time I click on it but how do I change the actual value from yes to no and viceversa on the page so I can see it on the table? – 1987mat Feb 24 '21 at 23:24
  • You can push id along with other fields to your myLibrary array. After then, attach that id to your tr to uniquely identify it and then when you click the toggle button, find an element by that id and update the text. https://jsbin.com/tuxiyeqilu/2/edit?js,console,output – gaurav soni Feb 25 '21 at 20:41