0

I have to make a library app which takes an input from user and stores it in a table on a webpage. Been banging my head at this problem for two days, mostly because I'm a beginner and don't understand most advanced code posted, so i'd even ask you if you'd please make your code very beginner friendly.

So, i have a form which takes inputs for the author, title, pages, year, a checkbox whether the book's been read, and a button to delete the book. id = author, title, pages, year, read, respectively, and a class for deleteBtn.

and a table template in html with only the header, with the intention of populating it with JS:

<div id="wrapperDiv">
    <table id="table">
        <thead>
            <th class=titleTh>Title:</th>
            <th>Author:</th>
            <th>Pages:</th>
            <th>Year:</th>
            <th>Read status:</th>
            <th>Edit:</th>
        </thead>
        <tbody id="tbody">    
            <!--add with javascript-->
        </tbody>
    </table>
</div>

and with JS, i have this:

//book array
let books = [];

//saving user input in Object
const addBook =(ev)=>{
ev.preventDefault();

let book = {
    title:document.getElementById("title").value, //.value gives what the user has written
    author:document.getElementById("author").value,
    pages:document.getElementById("pages").value,
    year:document.getElementById("year").value,
    read:document.getElementById("read").checked,
    //edit:document.getElementById("edit").value, 
}
console.log(book);

books.push(book);
document.forms[0].reset(); //clear form for next input
//document.querySelector("form").reset(); same thing
console.log("pushed book")
console.log(books);

localStorage.setItem("BookList", JSON.stringify(books));
//var tbody = document.getElementById("tbody");
var row = document.createElement("tr");
var td1 = document.createElement("td");
var td2 = document.createElement("td");
var td3 = document.createElement("td");
var td4 = document.createElement("td");
var td5 = document.createElement("td");  
td5.classList.add("checkTd");
var td6 = document.createElement("button");
td6.innerHTML = "Delete";
td6.classList.add("deleteBtn");

td1.innerHTML = document.getElementById("title").value;
td2.innerHTML = document.getElementById("author").value;
td3.innerHTML = document.getElementById("pages").value;
td4.innerHTML = document.getElementById("year").value;
td5.innerHTML = document.getElementById("read").checked;

row.appendChild(td1);
row.appendChild(td2);
row.appendChild(td3);
row.appendChild(td4);
row.appendChild(td5);
row.appendChild(td6);

table.children[0].appendChild(row);  
} 

document.addEventListener("DOMContentLoaded", ()=>{
document.getElementById("submitBook").addEventListener("click", addBook);
})

So when i input the fields, array gets made, like this:

[0] Object {

​​title: "game of thrones"

author: "george rr martin"

pages: "8000"

​​year: "2005"

read: true

}

A visual row in the table also gets made, however it's always empty. Also the checkbox is always "false" on the webpage (even if true in array) no matter what kind of if else statement i write. Please help. ​​

  • why are you using the data from the form "td1.innerHTML = document.getElementById("title").value;" to make the row data? shouldn't you use the array of books to create your row? – Sudhanshu Kumar Jan 08 '21 at 07:41
  • @Ashu Aha, so if i comment that whole section of "innerHTML" code out, it still works as before. what you're saying is i should remove that code and replace it with one that takes a value directly out of array and assigns it to "td" element? –  Jan 08 '21 at 08:04
  • of course, loop over the array, create an array of rows using the data and add it to the tbody – Sudhanshu Kumar Jan 08 '21 at 08:15

1 Answers1

0

If I am right according to your requirements, you can map over the array of books and return a row element for each book, finally, with the rows array, you can append it to the body.

let books = [{
  title: 'Book 1', //.value gives what the user has written
  author: 'Author 1',
  pages: '10',
  year: 2020,
  read: false,
}, {
  title: 'Book 2', //.value gives what the user has written
  author: 'Author 2',
  pages: '10',
  year: 2021,
  read: false,
}];


let tbody = document.getElementById("tbody");

books.forEach((book) => {
  let row = document.createElement("tr");
  let td1 = document.createElement("td");
  let td2 = document.createElement("td");
  let td3 = document.createElement("td");
  let td4 = document.createElement("td");
  let td5 = document.createElement("td");
  td5.classList.add("checkTd");
  var td6 = document.createElement("button");
  td6.innerHTML = "Delete";
  td6.classList.add("deleteBtn");

  td1.innerHTML = book.title
  td2.innerHTML = book.author;
  td3.innerHTML = book.pages;
  td4.innerHTML = book.year;
  td5.innerHTML = book.read;

  row.appendChild(td1);
  row.appendChild(td2);
  row.appendChild(td3);
  row.appendChild(td4);
  row.appendChild(td5);
  row.appendChild(td6);
  // append the row element 
  tbody.appendChild(row);
});
<div id="wrapperDiv">
    <table id="table">
        <thead>
            <th class=titleTh>Title:</th>
            <th>Author:</th>
            <th>Pages:</th>
            <th>Year:</th>
            <th>Read status:</th>
            <th>Edit:</th>
        </thead>
        <tbody id="tbody">    
            <!--add with javascript-->
        </tbody>
    </table>
</div>

This might not be the very ideal solution as per readability and performance, should suffice your needs.

Sudhanshu Kumar
  • 1,926
  • 1
  • 9
  • 21
  • thank you! first, table.children[0].appendChild(rows); should probably be tbody.children[0]? second, i get the "Uncaught TypeError: tbody.children[0] is undefined" error –  Jan 08 '21 at 09:18
  • Just do tbody.appendChild(rows); https://stackoverflow.com/questions/5677799/how-to-append-data-to-div-using-javascript, if this solves your problem, you can mark the question as answered by accepting the answer. – Sudhanshu Kumar Jan 08 '21 at 09:32
  • sadly no. i must be going bonkers, because i keep getting errors no matter what i do or google :( this time i get "Uncaught TypeError: Node.appendChild: Argument 1 does not implement interface Node." –  Jan 08 '21 at 10:31
  • I have added a runnable sample with dummy data for books array, you must be able to figure this out now. Although my prev answer had a small issue :) – Sudhanshu Kumar Jan 08 '21 at 10:47