Apologies if something similar has been posted but I am trying to delete a row the button is on and not just the last row as the search results seem to give me.
I have the following code that adds to an HTML table but onclick
doesn't work, the delete button doesn't work and addRow doesn't function. Why not?
java code
function addRow() {
var table = document.getElementById("createOrderTable");
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
... other cells ...
var cell4 = row.insertCell(3);
var btn = document.createElement("input");
btn.type = "button";
btn.value = "Close";
btn.onclick = deleteRow('createOrderTable', rowCount);
cell4.appendChild(btn);
}
function deleteRow(id, row) {
document.getElementById(id).deleteRow(row);
}
table code
<table id="createOrderTable" width="100%">
<tr>
<th>Count</th><th>Product</th><th>Mesh</th><th>Delete</th>
</tr>
<tr>
<td>1</td><td>OL</td><td>200</td><td><button type="button" class="close" aria-hidden="true" onclick="deleteRow('createOrderTable', 1)">×</button></td>
</tr>
</table>
if I change
btn.onclick = deleteRow('createOrderTable', rowCount );
to
btn.onclick = deleteRow('createOrderTable', rowCount + 1 );
I can get the row to show but it throws
Uncaught IndexSizeError: Failed to execute 'deleteRow' on 'HTMLTableElement': The index provided (3) is greater than the number of rows in the table (3).
and doesn't show the button. I'm confused about what I'm doing wrong here.
Apologies if something similar has been posted but I am trying to delete a row the button is on and not just the last row as the search results seem to give me.
I have the following code that adds to an HTML table but onclick
doesn't work, the delete button doesn't work and addRow doesn't function. Why not?
java code
function addRow() {
var table = document.getElementById("createOrderTable");
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
... other cells ...
var cell4 = row.insertCell(3);
var btn = document.createElement("input");
btn.type = "button";
btn.value = "Close";
btn.onclick = deleteRow('createOrderTable', rowCount);
cell4.appendChild(btn);
}
function deleteRow(id, row) {
document.getElementById(id).deleteRow(row);
}
table code
<table id="createOrderTable" width="100%">
<tr>
<th>Count</th><th>Product</th><th>Mesh</th><th>Delete</th>
</tr>
<tr>
<td>1</td><td>OL</td><td>200</td><td><button type="button" class="close" aria-hidden="true" onclick="deleteRow('createOrderTable', 1)">×</button></td>
</tr>
</table>
if I change
btn.onclick = deleteRow('createOrderTable', rowCount );
to
btn.onclick = deleteRow('createOrderTable', rowCount + 1 );
I can get the row to show but it throws
Uncaught IndexSizeError: Failed to execute 'deleteRow' on 'HTMLTableElement': The index provided (3) is greater than the number of rows in the table (3).
and doesn't show the button. I'm confused about what I'm doing wrong here.
Share Improve this question edited Jan 19, 2016 at 21:02 Cristiano Mendonça 1,3121 gold badge10 silver badges21 bronze badges asked Jan 19, 2016 at 20:14 johnjohn 7874 gold badges15 silver badges31 bronze badges 6-
2
You know what is the difference between function call and a reference? Just apply that knowledge, when you assign an event handler to
btn
. – Teemu Commented Jan 19, 2016 at 20:17 - Ah I see what you mean Teemu, I e from Java and am new to this way of doing things.. how can i reference a function with parameters? – john Commented Jan 19, 2016 at 20:25
-
You wrap the invokation in a function expression:
function () {deleteRow('createOrderTable', rowCount);}
. Please read also Maxali's answer, they have pointed an important issue too. – Teemu Commented Jan 19, 2016 at 20:28 - Ah that worked, and its functioning now. I am looking at Maxali's answer right now and his changes are having some unintended side effects but I'll post those down there. – john Commented Jan 19, 2016 at 20:34
-
1
Wait! There will be more problems. After adding a couple of rows you'll remove some of them randomly (i.e. not always the last-one).
rowCount
will point to a row position which it had when it was created, but that position might be wrong at the time you remove a row. I'd getparentElement.parentElement.rowIndex
of the clicked button, and used that as an index to pass totable.deleteRow
method. – Teemu Commented Jan 19, 2016 at 20:41
3 Answers
Reset to default 3The row index is not static, so as you delete rows, the row index of remaining rows can change if a row with a lower index is deleted. A solution is to not use rowIndex at all, and just use DOM relationships instead.
You can get a reference to the button that was clicked by passing this to the function, then go up parent nodes until you reach a TR element and delete it, e.g.
// Helper function:
function upTo(el, tagName) {
tagName = tagName.toLowerCase();
while (el && el.parentNode) {
el = el.parentNode;
if (el.tagName && el.tagName.toLowerCase() == tagName) {
return el;
}
}
return null;
}
function deleteRow(el) {
var row = upTo(el, 'tr')
if (row) row.parentNode.removeChild(row);
}
<table>
<tr>
<td>1</td><td>OL</td><td>200</td>
<td><button type="button" onclick="deleteRow(this)">×</button></td>
</tr>
<tr>
<td>2</td><td>AB</td><td>400</td>
<td><button type="button" onclick="deleteRow(this)">×</button></td>
</tr>
</table>
You can also use event delegation and put a single listener on the table, then use the associated event object's target property to see if the event was initiated by a click on a button with class close. If so, call deleteRow and pass the element reference as a parameter as for the above.
You shoud modify your code like this:
btn.onclick = deleteRow;
And the deleteRow
declaration to this:
function deleteRow() {
this.parentElement.parentElement.remove();
}
UPDATE
Check working example.
To delete the current row that the button belongs to
Change onclick of <button>
to :
onclick="this.parentNode.parentNode.parentNode.deleteRow(this.parentNode.parentNode.rowIndex)"
or change button in html like:
<input type="button" onclick="deleteRow(this)">X</button>
or by JavaScript code using
btn.setAttribute('onclick','deleteRow(this)');
Delete function is like:
function deleteRow(el) {
var tbl = el.parentNode.parentNode.parentNode;
var row = el.parentNode.parentNode.rowIndex;
tbl.deleteRow(row);
}