Find table row by a given cell value and delete that row - javascript

I have a table with 3 columns-
<table id="my_list">
<thead>
<tr>
<th>column 1</th>
<th>column 2</th>
<th>column 3</th>
</tr>
</thead>
<tr>
<td>value 1</td>
<td>value 2</td>
<td>value 3</td>
</tr>
</table>
I'm writing a function that searches the table for a given_value and deletes the row that contains it-
function delete_row (given_value) {
var table_row = $("td").filter(function() {
return $('#my_list').text() == given_value;
}).closest("tr");
// Removing the row from `my_list` table
table_row.remove();
}
But this is not deleting the row.
Also, I only want to search the text values in column 2, so if there's a faster way to search the table, that would be great to know too.

I think this is what you are looking for, but you can loop over the td elements and check their text and if you get a match, delete the tr element.
Edit: If you wanted to specify an id, you could add that to the function like such. Then just give the function the id name and what value to look for.
function delete_row(id, given_value) {
var td = $("#" + id + " td");
$.each(td, function(i) {
if ($(td[i]).text() === given_value) {
$(td[i]).parent().remove();
}
});
}
delete_row('my_list', 'value 1');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="my_list">
<thead>
<tr>
<th>column 1</th>
<th>column 2</th>
<th>column 3</th>
</tr>
</thead>
<tr>
<td>value 1</td>
<td>value 2</td>
<td>value 3</td>
</tr>
</table>

The filter function actually passes a couple things as arguments, including the current element. To check the text of that element, rather than the text of "#my_list", use $(el).text().
After that, 'trim' the value of the text, to remove the whitespace before and after the text. Otherwise its comparing ' value 2 ' with 'value 2', and it will not produce a match.
As a side note, the standard within JavaScript is to use camelCase instead of snake_case.
function deleteRow(givenValue) {
var tableRow = $("td")
.filter(function(index, el) {
return (
$(el) // <-- the <td> element
.text()
.trim() === givenValue
);
})
.closest("tr");
// Removing the row from `my_list` table
tableRow.remove();
}

Are you sure given_value matches the html text? There's spaces before and after text which may be your problem. Also, make sure table_row is not empty after the filter function.
function delete_row(given_value) {
var table_row = $("td").filter(function () {
return $('#my_list').text() == given_value;
});
if (table_row.length > 0) {
// Removing the row from `my_list` table
table_row.closest("tr").remove();
} else {
console.log('nothing matching given_value!')
}
}

Try this simple code:
function RemoveFromTable(tblID, VALUE){
$("#"+tblID).find("td:contains('"+VALUE+"')").closest('tr').remove();
}
Call the function as follows:
RemoveFromTable('table ID','value')

You need to match <td> instead of the entire table. Then trim the value to remove any leading/trailing white spaces. Then use the index parameter from the filter function to get the nth <td> element (using eq) and check its value for the desired value, and then remove it.
function delete_row (given_value) {
var table_row = $("td").filter(function(idx) {
return $("td").eq(idx).text().trim() == given_value;
});
// Removing the row from `my_list` table
table_row.remove();
}
I would also suggest to set the value to be an empty string so as to not disrupt the structure of the table.

Related

Check if td element have certain value

i have a table with number :
<td id="table-number">{{ $loop->index + 1 }}</td>
now i want to get the number of "9" from the table row
Here is what i do :
const number = document.getElementById('table-number');
if(number.textContent.includes('9')) {
console.log('heyhey');
}
but it returns nothing. So, what should i do? I expect to get the table number.
ok guys, i got the answer at this post, sorry i didnt serach thoroughly. Need to upgrade my google skils
Assuming the <td> elements are produced in a loop and you want to know if any of them contain a 9, give the elements a class instead of id...
<td class="table-number">
and try something like this instead
const tableNumbers = Array.from(
document.querySelectorAll(".table-number"),
({ textContent }) => textContent
);
if (tableNumbers.some((content) => content.includes("9"))) {
console.log("heyhey");
}
You probably don't need an id or a class on the cells.
Use querySelectorAll to get a node list of all of the cells, coerce the node list to an array, and then find the cell with the text content that includes your query.
// Cache all the cells
const cells = document.querySelectorAll('td');
// Coerce the node list to an array on which you can
// use the `find` method to find the cell with the matching
// text
const found = [...cells].find(cell => {
return cell.textContent.includes(3);
});
if (found) console.log(found.textContent);
<table>
<tbody>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 3</td>
<td>Cell 4</td>
</tr>
</tbody>
</table>

table mapping by th and first td in row to populate from json object

using php to echo json array inline i want js/jquery to populate table according to these data.
HTML table
<table>
<thead>
<tr>
<th>Time</th>
<th data-day='2013-03-15'>15-3</th>
<th data-day='2013-03-16'>16-3</th>
<th data-day='2013-03-17'>17-3</th>
</tr>
</thead>
<tbody>
<tr data-time='09'>
<td>9am</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<script>
var arr=[
{"date":"2013-03-15","id":"4","time_booked":"09:00:00"},
{"date":"2013-03-15","id":"1","time_booked":"09:10:00"},
{"date":"2013-03-17","id":"5","time_booked":"09:30:00"}
];
$.each(arr,function(){
console.log('id:'+this.id+'inside:'+this.date+'|'+this.time_booked);
});
</script>
i want to loop thro arr and according to its date and time_booked write id inside td.
for example first row will go to td with date-day='2013-03-15' and data-time='09'
so how can i do this using javascript ?
im thinking should i include data-day,data-time inside each td in tbody ? or is there a better way to do it ?
current approach:
include data-day inside each tr so html of tbody is
<tr data-time='09'>
<td data-day='2013-03-15'></td>
<td data-day='2013-03-16'></td>
etc..
</tr>
then use js
$.each(arr,function(){
var rday=this.date;
var rtime=this.time_booked;
var sel='tr[data-hr="'+rtime.substr(0,2)+'"]';
var dom=$(sel).find('td[data-day="'+rday+'"]').first();
if(dom.length)dom.append(this.id);
});
but i have a feeling its stupid ! there must be a way to map table using x,y (table head,row head) or there is none ?
I think the jQuery index function is what you're looking for. In the code sample below, I've used it to fetch the colIndex for the date. In this case, it fetches all of the th cells within the table, and uses .index(..) with a selector seeking the required date. This gives the column index of the date you're seeking, and from there it's all pretty straight-forward.
var arr=[
{"date":"2013-03-15","id":"4","time_booked":"0900"},
{"date":"2013-03-15","id":"1","time_booked":"0910"},
{"date":"2013-03-17","id":"5","time_booked":"0930"}
];
$.each(arr,function(){
var cell = GetCellByDateAndTime(this.date, this.time_booked);
$(cell).text(this.id);
});
function GetCellByDateAndTime(date, time) {
var colIndex = $("#BookingsTable th").index($("[data-day='" + date + "']"));
var row = $("#BookingsTable tr[data-time='" + time + "']")
var cell = $(row).children($("td"))[colIndex];
return cell;
}
And a Fiddle.

jQuery - selector inside another selector - passed in variable loses its value and becomes an indexer?

I'm somewhat new to jQuery and am just wondering how I go about passing in a string value rather than what appears to be a reference to a jQuery item from a selector? I'm having a hard time explaining so here's a sample demo. Don't even know what to title this so please have at editing the title if you can think of a better one.
At the line where I do $("td").filter(function(str){ the str that is passed in becomes an index position of which TD I'm in. So while debugging the first time in it's a 0 the next time a 1 and so on. I tried google but I'm not even sure what to search for, any documentation/code help would be much appreciated
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("select[name='showTeam']").change(function () {
$("select[name='showTeam'] option:selected").each(function () {
var str = $(this).val().toLowerCase();
//str = what it was set to up there
//alert(str);
$("td").filter(function(str) {
//str = becomes a number = to position of TD.. ie for 5th TD match STR = 4 (starts at index 0)
return $(this).text().toLowerCase().indexOf(str) != -1;
}).css('background','red');
});
})
});
</script>
Show Team: <select id="showTeam" name="showTeam">
<option>All</option>
<option>Chelsea</option>
</select>
<div id="games">
<table border="1">
<tbody>
<tr>
<th>ID</th>
<th>Game date</th>
<th>Field</th>
<th>Home team</th>
<th>Home team score</th>
<th>Away team</th>
<th>Away team score</th>
<th>Game type</th>
</tr>
<tr class="odd_line" id="game_460">
<td>459</td>
<td>03 Nov 19:00</td>
<td>Field 2</td>
<td>Madrid </td>
<td>3</td>
<td>Bayern Munich </td>
<td>1</td>
<td>Season</td>
</tr>
<tr class="odd_line" id="game_461">
<td>460</td>
<td>03 Nov 19:00</td>
<td>Field 3</td>
<td>chelsea</td>
<td>5</td>
<td>arsenal</td>
<td>4</td>
<td>Season</td>
</tr>
</div>
$(document).ready(function(){
$("#showTeam").change(function () {
var searchFor = $(this).val().toLowerCase();
$("#games table tbody tr td:contains('" + searchFor + "')").parent().css('background','red');
})
});
Demo
Well, yes. The first parameter will refer to the index of the element in the set of matched elements. Just do:
...
$("select[name='showTeam'] option:selected").each(function() {
var str = $(this).val().toLowerCase();
$("td").filter(function() {
return $(this).text().toLowerCase().indexOf(str) != -1;
}).css('background', 'red');​
...
since str will already be available within the scope of the filter callback function.
From the docs:
.filter( function(index) )
function(index)A function used as a test for each element in the set.
this is the current DOM element.
$(document).ready(function(){
$("#showTeam").change(function() {
var target = $("#showTeam").val();
$("#games td:contains(" + target + ")").css('background','red');
});
});
I've made a jsfiddle to demonstrate this.
http://jsfiddle.net/Zf5dA/
Notes:
:contains() is case sensitive so I had to make "Chelsea" capitalized in the table.
I simplified the selector on the select element - it has an id, so I selected that. Faster and simpler.
This will find td cells that contain the text, but they can also contain other text. This will get you started.

Delete all rows in an HTML table

How can I delete all rows of an HTML table except the <th>'s using Javascript, and without looping through all the rows in the table? I have a very huge table and I don't want to freeze the UI while I'm looping through the rows to delete them
this will remove all the rows:
$("#table_of_items tr").remove();
Keep the <th> row in a <thead> and the other rows in a <tbody> then replace the <tbody> with a new, empty one.
i.e.
var new_tbody = document.createElement('tbody');
populate_with_new_rows(new_tbody);
old_tbody.parentNode.replaceChild(new_tbody, old_tbody)
Very crude, but this also works:
var Table = document.getElementById("mytable");
Table.innerHTML = "";
Points to note, on the Watch out for common mistakes:
If your start index is 0 (or some index from begin), then, the correct code is:
var tableHeaderRowCount = 1;
var table = document.getElementById('WRITE_YOUR_HTML_TABLE_NAME_HERE');
var rowCount = table.rows.length;
for (var i = tableHeaderRowCount; i < rowCount; i++) {
table.deleteRow(tableHeaderRowCount);
}
NOTES
1. the argument for deleteRow is fixed
this is required since as we delete a row, the number of rows decrease.
i.e; by the time i reaches (rows.length - 1), or even before that row is already deleted, so you will have some error/exception (or a silent one).
2. the rowCount is taken before the for loop starts
since as we delete the "table.rows.length" will keep on changing, so again you have some issue, that only odd or even rows only gets deleted.
Hope that helps.
This is an old question, however I recently had a similar issue.
I wrote this code to solve it:
var elmtTable = document.getElementById('TABLE_ID_HERE');
var tableRows = elmtTable.getElementsByTagName('tr');
var rowCount = tableRows.length;
for (var x=rowCount-1; x>0; x--) {
elmtTable.removeChild(tableRows[x]);
}
That will remove all rows, except the first.
Cheers!
If you can declare an ID for tbody you can simply run this function:
var node = document.getElementById("tablebody");
while (node.hasChildNodes()) {
node.removeChild(node.lastChild);
}
Assuming you have just one table so you can reference it with just the type.
If you don't want to delete the headers:
$("tbody").children().remove()
otherwise:
$("table").children().remove()
hope it helps!
I needed to delete all rows except the first and solution posted by #strat but that resulted in uncaught exception (referencing Node in context where it does not exist). The following worked for me.
var myTable = document.getElementById("myTable");
var rowCount = myTable.rows.length;
for (var x=rowCount-1; x>0; x--) {
myTable.deleteRow(x);
}
the give below code works great.
It removes all rows except header row. So this code really t
$("#Your_Table tr>td").remove();
this would work iteration deletetion in HTML table in native
document.querySelectorAll("table tbody tr").forEach(function(e){e.remove()})
Assing some id to tbody tag. i.e. . After this, the following line should retain the table header/footer and remove all the rows.
document.getElementById("yourID").innerHTML="";
And, if you want the entire table (header/rows/footer) to wipe out, then set the id at table level i.e.
How about this:
When the page first loads, do this:
var myTable = document.getElementById("myTable");
myTable.oldHTML=myTable.innerHTML;
Then when you want to clear the table:
myTable.innerHTML=myTable.oldHTML;
The result will be your header row(s) if that's all you started with, the performance is dramatically faster than looping.
If you do not want to remove th and just want to remove the rows inside, this is working perfectly.
var tb = document.getElementById('tableId');
while(tb.rows.length > 1) {
tb.deleteRow(1);
}
Pure javascript, no loops and preserving headers:
function restartTable(){
const tbody = document.getElementById("tblDetail").getElementsByTagName('tbody')[0];
tbody.innerHTML = "";
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"/>
<table id="tblDetail" class="table table-bordered table-hover table-ligth table-sm table-striped">
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 2</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>
a
</td>
<td>
b
</td>
<td>
c
</td>
<td>
d
</td>
</tr>
<tr>
<td>
1
</td>
<td>
2
</td>
<td>
3
</td>
<td>
4
</td>
<tr>
<td>
e
</td>
<td>
f
</td>
<td>
g
</td>
<td>
h
</td>
</tr>
</tr>
</tbody>
</table>
<button type="button" onclick="restartTable()">restart table</button>
If you have far fewer <th> rows than non-<th> rows, you could collect all the <th> rows into a string, remove the entire table, and then write <table>thstring</table> where the table used to be.
EDIT: Where, obviously, "thstring" is the html for all of the rows of <th>s.
This works in IE without even having to declare a var for the table and will delete all rows:
for(var i = 0; i < resultsTable.rows.length;)
{
resultsTable.deleteRow(i);
}
this is a simple code I just wrote to solve this, without removing the header row (first one).
var Tbl = document.getElementById('tblId');
while(Tbl.childNodes.length>2){Tbl.removeChild(Tbl.lastChild);}
Hope it works for you!!.
Assign an id or a class for your tbody.
document.querySelector("#tbodyId").remove();
document.querySelectorAll(".tbodyClass").remove();
You can name your id or class how you want, not necessarily #tbodyId or .tbodyClass.
#lkan's answer worked for me, however to leave the first row, change
from
for (var x=rowCount-1; x>0; x--)
to
for (var x=rowCount-1; x>1; x--)
Full code:
var myTable = document.getElementById("myTable");
var rowCount = myTable.rows.length;
for (var x=rowCount-1; x>1; x--) {
myTable.deleteRow(x);
}
This will remove all of the rows except the <th>:
document.querySelectorAll("td").forEach(function (data) {
data.parentNode.remove();
});
Same thing I faced. So I come up with the solution by which you don't have to Unset the heading of table only remove the data..
<script>
var tablebody =document.getElementById('myTableBody');
tablebody.innerHTML = "";
</script>
<table>
<thead>
</thead>
<tbody id='myTableBody'>
</tbody>
</table>
Try this out will work properly...
Assuming the <table> element is accessible (e.g. by id), you can select the table body child node and then remove each child until no more remain. If you have structured your HTML table properly, namely with table headers in the <thead> element, this will only remove the table rows.
We use lastElementChild to preserve all non-element (namely #text nodes and ) children of the parent (but not their descendants). See this SO answer for a more general example, as well as an analysis of various methods to remove all of an element's children.
const tableEl = document.getElementById('my-table');
const tableBodyEl = tableEl.querySelector('tbody');
// or, directly get the <tbody> element if its id is known
// const tableBodyEl = document.getElementById('table-rows');
while (tableBodyEl.lastElementChild) {
tableBodyEl.removeChild(tableBodyEl.lastElementChild);
}
<table id="my-table">
<thead>
<tr>
<th>Name</th>
<th>Color</th>
</tr>
</thead>
<tbody id="table-rows">
<tr>
<td>Apple</td>
<td>Red</td>
</tr>
<!-- comment child preserved -->
text child preserved
<tr>
<td>Banana</td>
<td>Yellow</td>
</tr>
<tr>
<td>Plum</td>
<td>Purple</td>
</tr>
</tbody>
</table>
Just Clear the table body.
$("#tblbody").html("");
const table = document.querySelector('table');
table.innerHTML === ' ' ? null : table.innerHTML = ' ';
The above code worked fine for me. It checks to see if the table contains any data and then clears everything including the header.

jQuery Table Row Filtering by Column

I'm trying to filter table rows in an intelligent way (as opposed to just tons of code that get the job done eventually) but a rather dry of inspiration.
I have 5 columns in my table. At the top of each there is either a dropdown or a textbox with which the user may filter the table data (basically hide the rows that don't apply)
There are plenty of table filtering plugins for jQuery but none that work quite like this, and thats the complicated part :|
Here is a basic filter example http://jsfiddle.net/urf6P/3/
It uses the jquery selector :contains('some text') and :not(:contains('some text')) to decide if each row should be shown or hidden. This might get you going in a direction.
EDITED to include the HTML and javascript from the jsfiddle:
$(function() {
$('#filter1').change(function() {
$("#table td.col1:contains('" + $(this).val() + "')").parent().show();
$("#table td.col1:not(:contains('" + $(this).val() + "'))").parent().hide();
});
});
Slightly enhancing the accepted solution posted by Jeff Treuting, filtering capability can be extended to make it case insensitive. I take no credit for the original solution or even the enhancement. The idea of enhancement was lifted from a solution posted on a different SO post offered by Highway of Life.
Here it goes:
// Define a custom selector icontains instead of overriding the existing expression contains
// A global js asset file will be a good place to put this code
$.expr[':'].icontains = function(a, i, m) {
return $(a).text().toUpperCase()
.indexOf(m[3].toUpperCase()) >= 0;
};
// Now perform the filtering as suggested by #jeff
$(function() {
$('#filter1').on('keyup', function() { // changed 'change' event to 'keyup'. Add a delay if you prefer
$("#table td.col1:icontains('" + $(this).val() + "')").parent().show(); // Use our new selector icontains
$("#table td.col1:not(:icontains('" + $(this).val() + "'))").parent().hide(); // Use our new selector icontains
});
});
This may not be the best way to do it, and I'm not sure about the performance, but an option would be to tag each column (in each row) with an id starting with a column identifier and then a unique number like a record identifier.
For example, if you had a column Produce Name, and the record ID was 763, I would do something like the following:
​​<table id="table1">
<thead>
<tr>
<th>Artist</th>
<th>Album</th>
<th>Genre</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td id="artist-127">Red Hot Chili Peppers</td>
<td id="album-195">Californication</td>
<td id="genre-1">Rock</td>
<td id="price-195">$8.99</td>
</tr>
<tr>
<td id="artist-59">Santana</td>
<td id="album-198">Santana Live</td>
<td id="genre-1">Rock</td>
<td id="price-198">$8.99</td>
</tr>
<tr>
<td id="artist-120">Pink Floyd</td>
<td id="album-183">Dark Side Of The Moon</td>
<td id="genre-1">Rock</td>
<td id="price-183">$8.99</td>
</tr>
</tbody>
</table>
You could then use jQuery to filter based on the start of the id.
For example, if you wanted to filter by the Artist column:
var regex = /Hot/;
$('#table1').find('tbody').find('[id^=artist]').each(function() {
if (!regex.test(this.innerHTML)) {
this.parentNode.style.backgroundColor = '#ff0000';
}
});
You can filter specific column by just adding children[column number] to JQuery filter. Normally, JQuery looks for the keyword from all the columns in every row. If we wanted to filter only ColumnB on below table, we need to add childern[1] to filter as in the script below. IndexOf value -1 means search couldn't match. Anything above -1 will make the whole row visible.
ColumnA | ColumnB | ColumnC
John Doe 1968
Jane Doe 1975
Mike Nike 1990
$("#myInput").on("change", function () {
var value = $(this).val().toLowerCase();
$("#myTable tbody tr").filter(function () {
$(this).toggle($(this.children[1]).text().toLowerCase().indexOf(value) > -1)
});
});
step:1 write the following in .html file
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">
<table id="myTable">
<tr class="header">
<th style="width:60%;">Name</th>
<th style="width:40%;">Country</th>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Germany</td>
</tr>
<tr>
<td>Berglunds snabbkop</td>
<td>Sweden</td>
</tr>
<tr>
<td>Island Trading</td>
<td>UK</td>
</tr>
<tr>
<td>Koniglich Essen</td>
<td>Germany</td>
</tr>
</table>
step:2 write the following in .js file
function myFunction() {
// Declare variables
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
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";
}
}
}
}

Categories