0

I am receiving JSON data from an API and I am populating this data into an HTML table using vanilla javascript. I am trying to add a button dynamically to the end of each row to perform some functionality, I haven't found a way to do it. Here is my function that populates the table with data


const showArtist = (data) => {
  let tableStructure = `<table>
        <thead>
          <tr>
           <th>Sr#</th>
           <th>Name</th>
           <th>Country</th>
           <th>Disambiguation</th>
           <th>Info</th>
          </tr>
        </thead>
          <tbody id="tbody"></tbody>
        </table>
      `;
  artistTable.innerHTML = tableStructure;
  let tableBody = document.getElementById("tbody");
  for (let i = 0; i < Object.keys(data).length; i++) {
    let tr = "";

    tr += `<tr>
            <td>${i}</td>
            <td>${data[i].name}</td>
            <td>${data[i].country}</td>
            <td>${data[i].disambiguation}</td>

            <td><input type="button" value="" >Add</input></td>
          </tr>`;
    tableBody.innerHTML += tr;
  }
};

I have tried using the appendChild method but it doesn't work either.

3
  • 2
    append is Jquery methond, you should use appendChild developer.mozilla.org/en-US/docs/Web/API/Node/appendChild Commented May 20, 2021 at 6:41
  • I have used the appendChild but it's not working either. Commented May 20, 2021 at 6:46
  • OK, I leave my answer with an example for you. Hope it helps Commented May 20, 2021 at 6:56

2 Answers 2

1

As you comment you don't know how to use appendChild, I leave my answer here.

Example Below

const artistTable = document.querySelector("#artistTable");

const data = [
  {
    name: "a",
    country: "bbb",
    disambiguation: "cc",
  },
  {
    name: "sss",
    country: "eeee",
    disambiguation: "dddddd",
  },
];

const showArtist = data => {
  let tableStructure = `<table>
        <thead>
          <tr>
           <th>Sr#</th>
           <th>Name</th>
           <th>Country</th>
           <th>Disambiguation</th>
           <th>Info</th>
          </tr>
        </thead>
        <tbody id="tbody"></tbody>
        </table>
      `;
  artistTable.innerHTML = tableStructure;
  let tableBody = document.getElementById("tbody");
  for (let i = 0; i < Object.keys(data).length; i++) {
    const tr = document.createElement("tr");
    tr.innerHTML = `<td>${i}</td>
    <td>${data[i].name}</td>
    <td>${data[i].country}</td>
    <td>${data[i].disambiguation}</td>
    <td><input type="button" value="" >Add</input></td>
   `;
    tableBody.appendChild(tr);
  }
};

showArtist(data);
<div id="artistTable"></div>

Sign up to request clarification or add additional context in comments.

5 Comments

In the code tr.innerHTMl=<tr>.....</tr>. Do we have to add tr tag again like you did or we can simply add the table data (td)
It worked and solved my problem. Thank you.@ikhvjs
@SureshMangs, I got your point, I updated my answer. I removed an extra tr tag inside the tr. innerHTML.
@ikhvjs That I know but I'm confused that If we have already created a tr element then why are we again adding tr into its innerHTML. I tried to run the code without the tr in the innerHTML of newly created tr and it worked fine
@ikhvjs Yes, this is what I was talking about. Great.
0

Replace this line:

tableBody.innerHTML += tr;

with

tr = `<tr>
       <td>${i}</td>
       <td>${data[i].name}</td>
       <td>${data[i].country}</td>
       <td>${data[i].disambiguation}</td>
       <td><input type="button" value="" >Add</input></td>
      </tr>`;
const parser = new DOMParser(),
doc = parser.parseFromString(tr, "text/html");
tableBody.appendChild(doc.querySelector('tr'))

This should work.

More cleaner solution is to use combination of document.createElement(), document.cloneNode() and document.appendChild(). Do something like

// Before for loop create tr and td element.
const tr = document.createElement('tr');
const td = document.createElement('td');

// Then inside for loop, Instead of using string definition,

let row = tr.cloneNode(true)
// Repeat these steps to create all <td>:
td1 = td.cloneNode(true);
td1.innerText = i // value
row.appendChld(td1) // Add all td to tr
tbody.appendChild(row)

3 Comments

I did but it shows DOMException: Failed to execute 'appendChild' on 'Node': Nodes of type '#document' may not be inserted inside nodes of type 'TBODY'. error
I have edited the answer. Try that. Or much cleaner method is to use combination of document.createElement() and document.cloneNode() and document.appendChild().
I have tried the recent edit but the error remained the same. The tr is in a for loop and it works for all the other data except for the button

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.