0

I want to use jQuery to create a table. Currently I have an empty table body and I would like to use some jQuery to fill up the table:

var $tr = $("<tr>"),
  $td = $("<td>");
var date = '2018-01-01'
$td.text(date);
$tr.append($td);

$td.text("New Years");
$tr.append($td);

$("#body").append($tr);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tbody id='body'>

  </tbody>
  <table>

But this only appends the second td. The first one gets overwritten. Any ideas on how to fix?

j08691
  • 204,283
  • 31
  • 260
  • 272
anderish
  • 1,709
  • 6
  • 25
  • 58
  • 3
    Append does not clone elements. If an element is already attached to the dom (or a dom fragment), it will detach it and put it in the new place. An element can only have a single direct parent in the DOM. You could circumvent this by appending `$td.prop('outerHtml')`, or make different td elements when you append – Taplar Jan 19 '18 at 19:38
  • Perhaps this link might assist you [https://stackoverflow.com/questions/171027/add-table-row-in-jquery](https://stackoverflow.com/questions/171027/add-table-row-in-jquery) – Guest Jan 19 '18 at 19:42

5 Answers5

1

Like Taplar said in comments, if the element already is in DOM, the .append will only "move it".

Now in your example, you append it a the same place, but also change the text.

Try the .clone() method to duplicate elements.

var $tr = $("<tr>");
var $td = $("<td>");
var date = '2018-01-01';

$td.text(date);
$tr.append($td);

var secondCell = $td.clone().text("New Years");
$tr.append(secondCell);

$("#body").append($tr);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tbody id='body'>

  </tbody>
</table>
Louys Patrice Bessette
  • 33,375
  • 6
  • 36
  • 64
0

var $tr1 = $("<tr>"),
  $tr2 = $("<tr>"),
  $tr3 = $("<tr>"),
  $td = $("<td>");
var date = '2018-01-01';

$td.text(date);

//various ways to accomplish it
$tr1.append($td.prop('outerHTML'));
$tr2.append($td.clone());
$tr3.append($('<td>', { text: date }));

$td.text("New Years");
$tr1.append($td.prop('outerHTML'));
$tr2.append($td.clone());
$tr3.append($('<td>', { text: 'New Years' }));

$("#body").append([$tr1, $tr2, $tr3]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tbody id='body'>

  </tbody>
  <table>
Taplar
  • 24,788
  • 4
  • 22
  • 35
0

You have to clone $td, so that DOM treats it as a new element.

var $tr = $("<tr>"),
  $td = $("<td>");
var date = '2018-01-01'
$td.text(date);
$tr.append($td.clone());

$td.text("New Years");
$tr.append($td.clone());

$("#body").append($tr);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tbody id='body'>

  </tbody>
  <table>
Nagaraj Raveendran
  • 1,150
  • 15
  • 23
0

You can try next code without jquery:

let tbody =  document.querySelector('#body');
let tr =  document.createElement('tr');
let td = document.createElement('tr');
td.textContent = '2018-01-01';;
let tdClone = td.cloneNode();
tdClone.textContent = "New Years";
tr.append(td,tdClone);
tbody.append(tr);

I think that is true way, because you can create new td instead of clone created td (maybe for example this td has special classes or atributes), and you code repaint DOM only after insert tr in table.

Petrashka Siarhei
  • 733
  • 10
  • 12
0

Hmm... Maybe this could be an alternative to do that:

var texts = ["2018-01-01", "New Years"];

$.each(texts, function(i, val){
    $("<tr><td>"+val+"</td></tr>").appendTo("#body")
});

$.each gets each item on the array texts, wrap it on tr and td, then append to the result on #body.

working fiddle

Eric Gruby
  • 389
  • 3
  • 11