how to target and delete one row from a table with Javascript? - javascript

I want to remove one specific row from the list in tbody after clicking on the delete button. Could you help me figure out how to make it work with plain javascript?
I always get the error message "cannot get / a".
function updateUI() {
var tbody = document.getElementById('entry-table');
for (var i = 0; i < Storedcontact.length; i++) {
var entry = Storedcontact[i];
var row = document.createElement("tr");
row.innerHTML = `
<td>${entry.name}</td>
<td>${entry.surname}</td>
<td>${entry.phone}</td>
<td>${entry.email}</td>
<td>Delete</td>
<td>Edit</td>
`;
tbody.appendChild(row);
function clearFields() {
document.getElementById("name").value = "";
document.getElementById("surname").value = "";
document.getElementById("phone").value = "";
document.getElementById("email").value = "";
}
clearFields();
}
}
tbody.addEventListener("click", function(ev) {
ev.preventDefault()})
function removeContact(event) {
if (event.classList.contains("delete")) {
event.parentElement.parentElement.remove();
}
}

So basically you weren't that far. Here how you can do that:
const btns = document.querySelectorAll('table td button'); // the delete buttons
for (let i=0; i < btns.length; i++) { // you can use the modern forEach but this is faster
btns[i].addEventListener('click', function() { // trigger event when hitting each button:
this.closest('tr').remove(); // remove the line
});
}
<table>
<tr><td>line1 </td> <td> more </td> <td> <button>remove</button></td></tr>
<tr><td>line2 </td> <td> more </td> <td> <button>remove</button></td></tr>
<tr><td>line3 </td> <td> more </td> <td> <button>remove</button></td></tr>
<tr><td>line4 </td> <td> more </td> <td> <button>remove</button></td></tr>
<tr><td>line5 </td> <td> more </td> <td> <button>remove</button></td></tr>
</table>
You can read more about remove() on MDN
and on closest() too.
Enjoy Code!
Be aware, closest() is not supported in IE. Here's a function that mimics its functionality for your purposes:
function closestParent(element, tagName){
try{
while(element.tagName != tagName.toUpperCase()) element = element.parentNode;
return element;
}
catch(e){
return null;
}
}

I like using inline javascript for this sort of thing, keeps it simple and easy to read.
Delete</td>

I gather that you want to delete them onclick? execute this code after all rows have loaded in the page:
var trs = document.getElementsByTagName("tr");
for(var i = 0; i < trs.length; i++){
trs[i].addEventListener("click", function(){
this.outerHTML = "";
});
}

Related

Search through HTML table columns

I am developing a site that contains a live search. This live search is used to search for contacts in a contact list (An HTML table). The contact list is a table with 2 columns, with each column containing a contact. The search works but, it returns the whole row, not just the matching columns.
Meaning that if I search for A in a table like the one in the snippet below; the search returns the whole row ( A || B ), not just A. Is there any way I could refine my function to search through columns instead of rows?
Hope I explained myself clearly.
<table>
<tr>
<td>A</td>
<td>B</td>
</tr>
<tr>
<td>C</td>
<td>D</td>
</tr>
</table>
Function
<script>
function myFunction() {
//variables
var input, filter, table, tr, td, i;
input = document.getElementById("search");
filter = input.value.toUpperCase();
table = document.getElementById("table");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td)
{
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
</script>
I've modified your code to iterate all the td elements in your table. instead of hiding the cells that don't contain the filter text I've opted to apply an opacity to them. It makes it clearer in the example what is happening.
When doing work on key down, don't forget to debounce the event. See this post for a good introduction: https://davidwalsh.name/javascript-debounce-function
function myFunction() {
//variables
var
input = document.getElementById("search"),
filter = input.value.toUpperCase(),
table = document.querySelector('table'),
cells = table.querySelectorAll('td');
for (var i = 0; i < cells.length; i++) {
var cell = cells[i];
if (cell.innerHTML.toUpperCase().indexOf(filter) > -1) {
cell.classList.remove('no-match');
} else {
cell.classList.add('no-match');
}
}
}
const
form = document.getElementById('form'),
input = document.getElementById("search");
form.addEventListener('submit', onFormSubmit);
input.addEventListener('keyup', onKeyUp);
function onFormSubmit(event) {
event.preventDefault();
myFunction();
}
function onKeyUp(event) {
// Debounce this event in your code or you will run into performance issues.
myFunction();
}
.no-match {
opacity: .2;
}
<form id="form">
<label>
Filter text
<input type="text" id="search"/>
</label>
<button>Filter</button>
</form>
<table>
<tr>
<td>A</td>
<td>B</td>
</tr>
<tr>
<td>C</td>
<td>D</td>
</tr>
</table>

How to reference a element within a table

I am need of help. I am trying to figure out the below:
<script>
var ct = 1;
function new_bank()
{
ct++;
var div1 = document.createElement('div');
div1.id = ct;
// bank to delete extended form elements
var delLink = 'delete';
div1.innerHTML =
document.getElementById("newbanktpl").innerHTML + delLink;
document.getElementById('newbank').appendChild(div1);
}
// function to delete the newly added set of elements
function delIt(eleId)
{
d = document;
var ele = d.getElementById(eleId);
var parentEle = d.getElementById('newbank');
parentEle.removeChild(ele);
findTotalA();
}
</script>
<!-- Template -->
<div id="newbanktpl">
<table>
<tr>
<td></td>
<td><textarea name="BankAccount[]"></textarea></td>
<td><input type="number" onblur="findTotalA()" name="Value[]"/></td>
<td><input type="number" name="Ownership[]" /></td>
<td>**ADD DELETED LINK HERE** </td>
</tr>
</table>
what I am after is the delete function to be within the table - at the moment the delete function is after the newbanktpl, and I want in within... on the last ADD DELETED LINK HERE.
give the link in the template a class
clone the template
update the div's ID
assign the delIt function to the onclick of the link
give the link a data-delete attribute that references the ID to delete.
insert the clone after the last bank that was inserted
assign the clone as the new "last bank"
var ct = 1;
var tmpl = document.getElementById("newbanktpl");
var lastBank = tmpl;
function new_bank() {
var clone = tmpl.cloneNode(true);
clone.id = "bank_" + ct;
ct++;
var delLink = clone.querySelector(".delete_link");
delLink.setAttribute("data-delete", clone.id);
delLink.onclick = delIt;
lastBank.parentNode.insertBefore(clone, lastBank.nextSibling);
lastBank = clone;
}
// function to delete the newly added set of elements
function delIt() {
var id = this.getAttribute("data-delete");
var ele = document.getElementById(id);
if (ele === lastBank) {
lastBank = ele.previousElementSibling;
}
ele.parentNode.removeChild(ele);
// findTotalA();
}
#newbanktpl {
display: none;
}
<!-- Template -->
<div id="newbanktpl">
<table>
<tr>
<td></td>
<td><textarea name="BankAccount[]"></textarea></td>
<td><input type="number" onblur="findTotalA()" name="Value[]" /></td>
<td><input type="number" name="Ownership[]" /></td>
<td><a class="delete_link" href="#">delete</a></td>
</tr>
</table>
</div>
<button onclick="new_bank()">New Bank</button>
Try adding an id to your td, then you can use it in JS.
In your HTML
<table>
<tr>
...
<td>delete</td>
</tr>
</table>
In your script tag
...
document.getElementById("delete").href="javascript:delIt('+ ct +')";
...
The Entire function should look like this:
var ct = 1;
function new_bank() {
ct++;
var div1 = document.createElement('div');
div1.id = ct;
document.getElementById("delete").href="javascript:delIt('+ ct +')";
document.getElementById('newbank').appendChild(div1);
}
P.S. I don't know why you are trying to save bytes from the computer by calling variables with such short names, it's a waist of your time, it won't make any difference to the computer, but it makes it harder to understand your code.

Can't retrieve the data from table using getAttribute() in Javascript

Right now I'm learning nodes. before that I'm sorry if my question isn't specific please let me know how to state it better.
This code is for deleting element attributes.
There's a color in the table column and when I press button the attribute bgcolor in td tag is gone.
When I run it, it always show tdelement is null? while I already use for statement to loop and check it.
And please answer it using Javascript.
function removeColor(color)
{
var table = document.getElementById("multi");
var tdList = table.getElementsByTagName("td");
// Loop through list <td> elements.
for (var i = 0; i <= tdList.length; i++)
{
var tdElement = tdList.item(i);
// Get the attribute.
var colorAtt = tdElement.getAttribute("value");
//If the attribute matches the color then delete attributes
if (colorAtt == color)
{
tdElement.removeAttributeNode(colorAtt);
}
}
}
// the end for javascript -----------------
<table id="multi" border="1">
<tr>
<td></td>
<td bgcolor="#ff0000">1</td>
<td bgcolor="#008000">2</td>
<td bgcolor="#ffff00">3</td>
</tr>
<tr>
<td bgcolor="#ff0000">1</td>
<td bgcolor="#ff0000">1</td>
<td bgcolor="#008000">2</td>
<td bgcolor="#ffff00">3</td>
</tr>
<tr>
<td bgcolor="#008000">2</td>
<td bgcolor="#008000">2</td>
<td bgcolor="#008000">4</td>
<td bgcolor="#ffff00">6</td>
</tr>
<tr>
<td bgcolor="#ffff00">3</td>
<td bgcolor="#ffff00">3</td>
<td bgcolor="#ffff00">6</td>
<td bgcolor="#ffff00">9</td>
</tr>
</table>
<button onclick="removeColor('#ff0000')">Remove Red Background</button><br>
try this
function removeColor(color)
{
var table = document.getElementById("multi");
var tdList = table.getElementsByTagName("td");
// Loop through list <td> elements.
for (var i = 0; i <= tdList.length; i++)
{
var tdElement = tdList.item(i);
// Get the attribute.
var colorAtt = tdElement.getAttributeNode("bgcolor");
//If the attribute matches the color then delete attributes
if (colorAtt && (colorAtt.value == color))
{
tdElement.removeAttributeNode(colorAtt);
}
}
}
using .getAttribute("value"); would try to get the attribute 'value' from the element. where you need to get the node .getAttributeNode("bgcolor");.
Fiddle

Set value of text box using val(value) doesnt work

I have a table in which if checkbox of a row is clicked this row will be disable (mean all inputs be disable and value of text boxes are set to 0)
HTML
#for (int i = 0; i < 3; i++) {
tableID = "tableID" + i;
buttonAddID = "buttonAddID" + i;
<table id="#tableID" class="tableSum">
<tbody>
<tr>
<td>Apple</td>
<td>5</td>
<td>100</td>
<td><input type="checkbox" onclick="highLightRow(this)" /></td>
</tr>
<tr>
<td><input type="text" value="Organe" /></td>
<td>5</td>
<td>200</td>
<td><input type="checkbox" onclick="highLightRow(this)" /></td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Total</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr><td colspan="4"><input type="button" class="addRow" onclick="addRow(this)" value="ADD ROW" id="#buttonAddID"/></td></tr>
</tfoot>
</table>
}
In JS:
function highLightRow(cb) {
var tr = $(cb).closest('tr');
var inputs = tr.find('input[type=text]');
if (cb.checked) {
tr.removeClass('trNormal')
tr.addClass('trHighLight');
for (var i = 0; i < inputs.length; i++) {
inputs[i].disabled = true;
inputs[i].val('0');
}
}
else {
tr.removeClass('trHighLight')
tr.addClass('trNormal');
for (var i = 0; i < inputs.length; i++) {
inputs[i].disabled = false;
}
}
}
The method inputs[i].disabled = true; works, text boxes are disable but the value is not set to 0.
You need convert DOMElement to jQuery object like so
$(inputs[i]).val('0');
because DOMElement does not have .val method, or you can use .value property from DOMElement , like so
inputs[i].value = '0';
.disabled works because this is DOMElement property
For that line, use eq() instead of []
inputs.eq(i).val('0');
What was happening is accessing an item like inputs[i] gives the native javascript DOM element which does not have a method val(). eq() however will retrieve the jQuery object. So, either use above or take the pure javascript alternative
inputs[i].value = '0';
Use jquery each function:
inputs.each(function(){
$(this).val('0');
});
You may use eq and prop:
for (var i = 0; i < inputs.length; i++) {
inputs.eq(i).prop('disabled',true);
inputs.eq(i).val('0');
}
you are trying to call val() function on javaScript DOM object, val() is not JavaScript Native method, it will only work with jQuery object, so you can call only with jQuery selector
$(inputs[i]).val('0');
Or you can also assign value in value variable,
inputs[i].value = '0';

Strange behaviour with loop in Javascript

I've got a table-like structure with text inputs in which I am trying to make an entire row to be removed with all their children, but first passing the values of cells up one by one
in the rows below to keep IDs numbering structure.
The table structure is like this:
<table cellpadding=0>
<tr id="myRow1">
<td id="#R1C1">
<input class="myCell">
</td>
<td id="#R1C2">
<input class="myCell">
</td>
<td id="#R1C3">
<input class="myCell">
</td>
<td id="#R1C4">
<input class="myCell">
</td>
</tr>
<tr id="myRow2">
<td id="#R2C1">
<input class="myCell">
</td>
<td id="#R2C2">
<input class="myCell">
</td>
<td id="#R2C3">
<input class="myCell">
</td>
<td id="#R2C4">
<input class="myCell">
</td>
</tr>
<!-- ...and so on. -->
</table>
Having this table, when some event is triggered,I make this code run:
var rows = 1; // This value is updated when adding/removing a line
//This code runs from any <tr> by event keyup
if (event.altKey) { // I define here all Alt+someKey actions.
// Getting position values
var currentId = $(this).attr('id');
var row = Number(currentId.split('C')[0].substring(1));
var column = Number(currentId.split('C')[1]);
var belowVal;
if (event.which == 66) { //Case Ctrl+B
// If not the last row, start looping
if (rows > row) {
var diff = rows - row;
// Iteration over rows below
for (var i = 0; i < diff; i++) {
// Iteration over each column
for (var c = 1; c <= 4; c++) {
// here I try to get the value from column below
belowVal = $('#R'+(row+1+i).toString() +
'C'+c.toString()).val();
$('#R'+(row+i).toString()+'C' +
c.toString()).find('.myCell').val(belowVal);
}
}
}
$('#myRow'+rows.toString()).empty();
$('#myRow'+rows.toString()).remove();
rows--;
}
}
It works fine for removing the last row, but, when trying to remove an upper row, the values of current row and the ones below become blank instead of moving up. I made this code for each row below to pass it's values to the upper row, but it isn't doing what I wanted.
Why is this happening? I couldn't figure it out.
The problem seem to be, that the ids you are using to access the values are not the ids of the input elements, but rather the ids of the containing table cells.
Here an approach, which doesnt use the ids, but relies on the nodes structure instead, code not tested:
if (event.which == 66) {
var currentrow = $(this);
var currentinputs = currentrow.find('input.myCell');
while(var nextrow = currentrow.next('tr')) {
var nextinputs = nextrow.find('input.myCell');
currentinputs.each(function(index,element){
element.val(nextinputs.get(index).val());
});
currentrow = nextrow;
currentinputs = nextinputs;
}
currentrow.remove();
}
RESOLVED
Thanks to #JHoffmann, I was able to resolve my problem like this:
for (var c = 1; c <= 4; c++) {
// here I try to get the value from column below
belowVal = $('#R'+(row+1+i).toString()+'C'+c.toString())
.find('.myCell').val();
$('#R'+(row+i).toString()+'C'+c.toString())
.find('.myCell').val(belowVal);
}
In the line that assigns a value to belowVal, I forgot to call the method .find('.myCell') before calling .val(). That was the mistake that caused my code to fail, as #JHoffmann commented in his answer.

Categories