简体   繁体   中英

Create new <tr>as text after 3rd <td> in JS

i want to create new table row as text <tr> after every third table data <td> from user input.

It have to be like this:

<table border="3" align="center" style="width: 100%;">
<tr>
<td><a href="link"><img src="link"></td>
<td><a href="lin"><img src="link"></td>
<td><a href="link"><img src="link"></td>
</tr>
<tr>
<td><a href="link"><img src="link"></td>
<td><a href="lin"><img src="link"></td>
<td><a href="link"><img src="link"></td>
</tr>
</table>

My code:

<script type="text/javascript">
      let x = 0;
      const data = Array();

        document.getElementById('btn').addEventListener("click", fun);
          function fun() {
            var val = document.getElementById('imagename').value;
              source = val;
              img = document.createElement('img');
                img.src = source;
                document.body.appendChild(img);
                // move child to up
                var before = document.getElementById('before');
                before.insertBefore(img, before.children[0]);

          /*var html = document.getElementById('before').innerHTML;
          document.getElementById('code').innerHTML = '<img src=' + src + '>';*/


          document.getElementById('code').innerText = '<img src="' + source + '">';
          data[x] = document.getElementById('imagename').value;
          x++;

          }

          document.getElementById('pasteBtn').addEventListener("click", makeCode);
            function makeCode(){
              let resultData = "<tr>";
                for (let i = 0; i < data.length; i++){
                  resultData += "<td>" + '<a href="' + data[i] + '">' + '<img src="' + data[i] + '"></td>\n';
                  if(i % 3 == 0){
                    resultdata += '</tr><tr>';
                  }
              }
              cssText = 'tr {width: 100%; display: flex;} td {width: 100%;}';
              tableText = '\n<table border="3" align="center" style="width: 100%;">\n';
              document.getElementById("paste").innerText = "<style>" + cssText + "</style>" + tableText + resultData;
            }
      </script>

I was trying with modulo but nothing happened. It have to be done in JS, not JQuery.

There are many ways to accomplish what you are looking for.

For my answer I chunked the array into groups of 3, then I loop through each element in each group.

I also chose to use createElement instead of using the string versions.

 let table = document.querySelector("#paste"); let data = [ 1,2,3,4,5,6,7,8,9 ]; while((row = data.splice(0, 3)).length){ let tr = document.createElement("tr"); for(z=0;z<=row.length-1;z++){ let td = document.createElement("td"); let link = document.createElement("a"); let img = document.createElement("img"); img.src = row[z]; link.href = row[z]; link.appendChild(img) td.appendChild(link) tr.appendChild(td) } table.appendChild(tr) }
 <table id="paste"></table>

Your code has a couple of problems, which have been mentioned in the comments. The last created row is not closed. Some browsers nowadays automatically solve this problem by adding the closing tag for that row, but it leaves you with a floating row.

A second problem is your modulo calculation. Since javascript arrays start at 0 and not at 1 you modulo creates the row to early, for: 0 % 3 = 0
1 % 3 = 1
2 % 3 = 2
3 % 3 = 0

A row is created containing ONLY the first value. This can be fixed by changing the modulo calculation to i + 1 % 3 , however it might not immediatly be clear why you seemingly randomly add the 1.

Another option is to introduce a counter. It is clear what the counter does, it counts. It is also clear to where it counts, 3 . By moving the closing and starting of the row to before the adding of the cell you prevent floating rows. You only start a new row, when you actually need one. Important still is to close the row, but as said before, there are browsers that do this, but you should not rely on that.

let resultData = "<tr>";
let counter = 0;
for (let i in data){
    if(counter == 3){
        resultdata += '</tr><tr>';
        counter = 0;
    }
    resultData += "<td>" + '<a href="' + data[i] + '">' + '<img src="' + data[i] + '"></td>\n';
    counter++;
}
resultdata += "</tr>";

Personally I prefer to use a for...in loop for looping over an array, but that is personal preference

As mentioned @imvain2's answer, it is better to use js document.createElement over the string to create the elements. And here is an approach that uses a single loop.


HTML:

<table id="data-table"></table>

const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const table = document.getElementById('data-table');

const addRows = (data) => {
  let tableRow = null;
  data.forEach((item, index) => {
    // adds a new row on first and then after every third "td"
    if (index % 3 === 0) {
      tableRow = document.createElement('tr');
      tableRow.id = 'tr' + (index + 1);
      table.appendChild(tableRow);
    }

    const tableData = document.createElement('td');
    tableRow.appendChild(tableData);

    const link = document.createElement('a');
    link.href = item;
    link.title = item;
    tableData.appendChild(link);
      
    const img = document.createElement('img');
    img.src = item;
    link.appendChild(img);

  });
};

addRows(data);

Adding EventListener to MakeCode.Btn .getting the count of td each row has with data.length/3 (9/3=3);so each row will have 3 td's .

Creating index variable to iterate over the array. creating Two ForLoops .

1st loop will create a row with an id of r(i) .first row will have an id of id="r1" .

2nd loop will get the row that was created in the first loop and it will add td tCount times which is 3 in this case. & data will also be added inside each td with ${data[index]}

incrementing the index every time a td is added.

 const data = [ "hello", "world", "code", "coding", "javascript", "css", "html", "react", "scss" ]; let table = document.getElementById("table"); let btn = document.getElementById("pasteBtn"); btn.addEventListener("click", () => { let tdCount = data.length / 3; let index = 0; for (let i = 1; i <= 3; i++) { table.innerHTML += `<tr id="r${i}"></tr>`; for (let j = 1; j <= tdCount; j++) { document.getElementById( `r${i}` ).innerHTML += `<td><a href="link"><img src="link">${data[index]}</td>`; index++; } } });
 tr { width: 70px; height: 40px; background-color: red; } tr:nth-child(2) { background-color: yellow; } tr:nth-child(3) { background-color: blue; } td { width: 70px; height: 40px; background-color: hotPink; } td:nth-child(2) { background-color: gray; } td:nth-child(3) { background-color: purple; }
 <button id="pasteBtn">makeCode</button> <table border="3" align="center" style="width: 100%;"> <tbody id="table"> </tbody> </table>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM