Gore
Gore

Reputation: 163

How to insert <tr> after every <tr> with pure JS

I would like to insert new <tr> after every existing <tr>. My function :

var element = document.querySelector('tr.cart-item');
var newElement = document.createElement('tr');
newElement.className = "tr-spacer";
var elementParent = element.parentNode;
elementParent.insertBefore(newElement, element.nextSibling);

but it insert <tr> only after first <tr>, is it possible insert <tr> after every existing <tr>? I also tried querySelectorAll or insertRow but it does not seem to work. Thanks you

Upvotes: 1

Views: 572

Answers (3)

Zenoo
Zenoo

Reputation: 12880

You'll have to loop through your <tr> tags.

First select them all using querySelectorAll instead of querySelector.

Then loop through them and add a new one after each.


As @T.J. Crowder pointed out in the comments, notice how there's an added step to check if the current <tr> has a next sibling by checking if nextElementSibling is truthy.

let lines = document.querySelectorAll('tr');

for(let line of lines){
  let newLine = document.createElement('tr');
  newLine.innerText = 'Inserted';
  if(line.nextElementSibling) line.parentNode.insertBefore(newLine, line.nextElementSibling);
}
<table>
<tr><td>1</td></tr>
<tr><td>2</td></tr>
<tr><td>3</td></tr>
<tr><td>4</td></tr>
</table>

Upvotes: 1

Andrzej Smyk
Andrzej Smyk

Reputation: 1724

You need to get all elements matching selector using querySelectorAll and then either in naked for loop or using Array.prototype.forEach create ad insert new tr after each element:

[].forEach.call(document.querySelectorAll('tr.cart-item'), function (element) {
  var newElement = document.createElement('tr');
  newElement.className = "tr-spacer";
  element.parentNode.insertBefore(newElement, element.nextSibling);
});
<table>
  <tr class="cart-item">
    <td>First</td>
  </tr>
  <tr class="cart-item">
    <td>Second</td>
  </tr>
  <tr class="cart-item">
    <td>Third</td>
  </tr>
</table>

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1075119

It works just fine with querySelectorAll. You didn't show your code trying to use that, but you'd have a loop:

var list = document.querySelectorAll('tr.cart-item');
for (var i = 0; i < list.length; ++i) {
    var element = list[i];
    var newElement = document.createElement('tr');
    newElement.className = "tr-spacer";
    element.parentNode.insertBefore(newElement, element.nextSibling);
}

or on modern browsers (or with a polyfill, which is trivial; more in this answer):

document.querySelectorAll('tr.cart-item').forEach(function(element) {
    var newElement = document.createElement('tr');
    newElement.className = "tr-spacer";
    element.parentNode.insertBefore(newElement, element.nextSibling);
});

or (again, modern browsers):

for (const element of document.querySelectorAll('tr.cart-item') {
    const newElement = document.createElement('tr');
    newElement.className = "tr-spacer";
    element.parentNode.insertBefore(newElement, element.nextSibling);
}

Upvotes: 1

Related Questions