Right. So guys, I'm stuck with a simple problem that I can't for the life of me figure out. I'm trying to insert a new row (using response data from an AJAX call) at the end of a Bootstrap table using JavaScript. I'm using a simple function like so;
function insertRow(data) {
let tbody = document.querySelector('tbody');
let spacer = document.createElement('tr');
let tr = document.createElement('tr');
// append rows to table
tbody.appendChild(spacer);
tbody.appendChild(tr);
// apply styles
tr.className = 'rounded-3 card-body shadow-sm reg-rows';
spacer.className = 'spacer';
spacer.style.height = '6px';
let id_input = document.createElement("input");
spacer.appendChild(id_input);
id_input.value = `${data.identifier}`;
id_input.name = "keys_array[]";
id_input.type = "hidden";
let cells_array = new Array();
// create cells
var td_id, td_ba, td_code, td_num;
td_id = td_ba = td_code = td_num = document.createElement('td');
// append cells to row
tr.append(td_id, td_ba, td_code, td_num);
// add cells to array
cells_array.push(td_id, td_ba, td_code, td_num);
Array.prototype.slice.call(cells_array)
.forEach(function(cell) {
cell.className = "p-1 border-0";
tr.appendChild(cell);
});
td_status.classList.add("rounded-end");
let div = document.createElement("div");
let input = document.createElement("input");
input.className = "form-check-input position-static";
input.name = "some_action[]";
input.type = "checkbox";
div.appendChild(input);
td_status.appendChild(div);
// write text to cells
td_id.innerHTML = `${data.id}`;
td_ba.innerHTML = `${data.ba}`;
td_code.innerHTML = `${data.code}`;
td_num.innerHTML = `${data.num}`;
}
The problem is that only the last cell (in this case td_num) gets inserted into the newly created row when I call the function, and it is inserted as the very first one.
I've tried using appendChild to append each cell individually to the new row but that didn't either.
I've even tried to change the order in which the cells are created and appended but that didn't work. What could I be doing wrong? Thanks.
You are creating 3 references for a one and same Element in this line:
td_id = td_ba = td_code = td_num = document.createElement('td');
Meaning, the only document.createElement('td') created here can be called with td_id, td_ba and td_code. You are not creating 3 td's here, only one with 3 references.
If you want to create 3 elements you need to create them for every variable
[ td_id, td_ba, td_code ].map(myVarRef => myVarRef = document.createElement('td'))
<html>
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous">
</script>
<script>
function insertRow() {
let data = [{
cell1: "3",
cell2: "Item 3",
cell3: "$3"
}, {
cell1: "4",
cell2: "Item 4",
cell3: "$4"
}];
// I choose table body over table by adding an ID specifically
let table_body = document.getElementById("tbody_id");
for (let i = 0; i < data.length; i++) {
// Create an empty <tr> element and add it to the last position of the table:
let row = table_body.insertRow(-1);
// Insert new cells (<td> elements) at the 1st and 2nd position of the "new" <tr> element:
let cell1 = row.insertCell(0);
let cell2 = row.insertCell(1);
let cell3 = row.insertCell(2);
// Add some text to the new cells:
cell1.innerHTML = data[i].cell1;
cell2.innerHTML = data[i].cell2;
cell3.innerHTML = data[i].cell3;
}
}
</script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-sm-3">
<button type="button" onclick="insertRow()" class="btn btn-primary">Click Me</button>
</div>
</div>
<div class="row">
<div class="col-sm">
<table data-toggle="table" id="test-table">
<thead>
<tr>
<th>Item ID</th>
<th>Item Name</th>
<th>Item Price</th>
</tr>
</thead>
<tbody id="tbody_id">
<tr>
<td>1</td>
<td>Item 1</td>
<td>$1</td>
</tr>
<tr>
<td>2</td>
<td>Item 2</td>
<td>$2</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
I created one sample that you can directly run, Hope this helps. I added comments in the code itself for better understanding, while inserting row you can give -1 to append into the bottom of the table body.