I use Javascript to search within a HTML table column. However, I can only search a value by typing the first letters of the table cells content.
An example of my data is shown below.
If I search for the value 123 in column 2, the desired table cell pops up like it should.
If I search for the value 456 or 23 for example , nothing happens.
|column1|column2|
__________________
|000|123 456|
|001|123 456|
My current Javascript:
<script type="text/javascript">
$("#searchn").on("keyup", function() {
var value = $(this).val();
$("table tr").each(function(index) {
if (index !== 0) {
$row = $(this);
var id = $row.find("td").children().eq(1).text();
if (id.indexOf(value) !== 0) {
$row.hide();
}
else {
$row.show();
}
}
});
});
</script>
Your logic is flawed as indexOf() returns -1 if the value you're searching for is not found, and the zero-based index of the match if it was found. Because of this, your if statement is flawed as it excludes matches at the start of the value.
You should change your if condition to this instead:
if (id.indexOf(value) !== -1) {
$row.hide();
}
else {
$row.show();
}
Also note that you can shorten this by using filter() and toggle() instead:
$("#searchn").on("keyup", function() {
var value = $(this).val();
$("table tr:not(:first)").show().filter(function(index) {
return $(this).find("td:eq(1)").text().indexOf(value) == -1;
}).hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<th>Col 1</th>
<th>Col 2</th>
</tr>
<tr>
<td>000</td>
<td>123 456</td>
</tr>
<tr>
<td>001</td>
<td>123 456</td>
</tr>
</table>
<input id="searchn" />
Related
I have this following code which does filter a table but when there is no result it is blank.
Could someone help me out here to add a "No results found" message show when nothing found?
$(document).ready(function() {
$("#table_search").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#filter tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
<table>
<tbody id="filter"></tbody>
</table>
Firstly note that your use of filter() isn't quite correct. It's intended to be used to reduce a set of elements based on a predicate condition supplied within the function argument which returns a boolean. Instead your current logic is using it as a basic looping mechanism.
With regard to the issue, you can use filter() to find matching rows by their text, then based on the number of filtered rows, hide or display the 'No matches' message. Something like this:
jQuery($ => {
let $rows = $('#filter tr');
let $tfoot = $('tfoot');
$("#table_search").on("input", function() {
var value = this.value.toLowerCase();
if (!value) {
$rows.show();
$tfoot.hide()
return;
}
let $filteredRows = $rows.filter((i, el) => el.innerText.toLowerCase().indexOf(value) != -1);
if ($filteredRows.length) {
$tfoot.hide();
$rows.hide();
$filteredRows.show()
} else {
$rows.hide();
$tfoot.show();
}
});
});
tfoot { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="table_search" />
<table>
<tbody id="filter">
<tr><td>Lorem</td></tr>
<tr><td>Ipsum</td></tr>
<tr><td>Dolor</td></tr>
<tr><td>Sit</td></tr>
<tr><td>Amet</td></tr>
<tr><td>Consectetur</td></tr>
<tr><td>Adipiscing</td></tr>
<tr><td>Elit</td></tr>
</tbody>
<tfoot>
<tr><td>No matches</td></tr>
</tfoot>
</table>
Finally, note the use of input instead of keyup. The latter works better in this instance as it also works for users who copy/paste text in to the search box.
I've got a search box where as I type, table data gets filtered through and only matching results get shown. It works great; however, I want to make it better.
I want the code to ignore spaces and dashes. I'd prefer make it easy to add additional characters I want it to ignore as well in the future..
For instance...
Product Table
FH-54
TDN 256
TDN25678
FH54
In the search box, if I type FH54, I'd like both the FH-54 and the FH54 to show up. If I type in FH-54 I'd also like the FH54 and the FH-54 to show up and so on to include FH 54 as well.
If I type in TDN2 or TDN 2 in the search box, I'd like TDN 256 and TDN25678 to show up.
<b>Product Search</b><br /><form class="formatted">
<input id="Search" data-class="search_product" type="text" /></form>
<script type="text/javascript">
$('#Search').on('keyup', function(e) {
$("#noData").remove();
var value = $(this).val();
value = value.replace(/\\/g, '');
var patt = new RegExp(value, "i");
var sw = 0;
var counter = 0;
$('#Data tbody').find('tr').each(function() {
counter++;
if (!($(this).find('td').text().search(patt) >= 0)) {
$(this).not('#header').hide();
sw++;
} else if (($(this).find('td').text().search(patt) >= 0)) {
$(this).show();
}
});
if (sw == counter) {
$("#Data tbody").append(`<tr id="noData">
<td colspan="3">No data</td>
</tr>`);
} else {
$("#noData").remove();
}
});
</script>
I've tried to reconstruct your scenario the best I could and made a working example.
As per your requirement to ignore all spaces and dashes: How about removing spaces and dashes from search string and from your values within the columns?
$('#Search').on('keyup', function(e) {
$("#noData").remove();
var value = $(this).val();
var spacesAndDashes = /\s|-/g;
value = value.replace(spacesAndDashes, "");
var patt = new RegExp(value, "i");
var sw = 0;
var counter = 0;
$('#Data tbody').find('tr').each(function() {
counter++;
if (!($(this).find('td').text().replace(spacesAndDashes, "").search(patt) >= 0)) {
$(this).not('#header').hide();
sw++;
} else if (($(this).find('td').text().replace(spacesAndDashes, "").search(patt) >= 0)) {
$(this).show();
}
});
if (sw == counter) {
$("#Data tbody").append(`<tr id="noData">
<td colspan="3">No data</td>
</tr>`);
} else {
$("#noData").remove();
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<b>Product Search</b>
<br />
<form class="formatted">
<input id="Search" data-class="search_product" type="text" />
</form>
<table id="Data">
<thead>
<tr>
<th>Product Table</th>
</tr>
</thead>
<tbody>
<tr>
<td>FH-54</td>
</tr>
<tr>
<td>TDN 256</td>
</tr>
<tr>
<td>FH54</td>
</tr>
<tr>
<td>FH 54</td>
</tr>
<tr>
<td>TDN25678</td>
</tr>
</tbody>
</table>
I created a manual search functionality that displays the results as the user types. Here is the fiddle: https://jsfiddle.net/rtq4jfuq/1/
Here is the HTML
<script src='https://code.jquery.com/jquery-3.2.1.min.js'></script>
<input style='width: 300px;' placeholder='search' id='search'>
<table border='1'>
<tr>
<th>Name</th>
</tr>
<tr class='names'>
<td>Bob</td>
</tr>
<tr class='names'>
<td>Ted</td>
</tr>
<tr class='names'>
<td>Steve</td>
</tr>
<tr class='names'>
<td>Sven</td>
</tr>
<tr class='names'>
<td>Magnus</td>
</tr>
</table>
Here is the script
$(document).ready(function() {
$("#search").keyup(function(){
var query = $(this).val();
$(".names").each(function(){
var n = $(this).children("td").html();
if (n.toUpperCase().includes(query.toUpperCase())) {
$(this).css("display", "");
}
else {
$(this).css("display", "none");
}
});
});
});
I want to display a message once there are no rows displayed but how do I check if there are no rows displayed?
Use the :visible filter so see if you've hidden all results:
$(document).ready(function() {
$("#search").keyup(function() {
var query = $(this).val();
$(".names").each(function() {
var n = $(this).children("td").html();
if (n.toUpperCase().includes(query.toUpperCase())) {
$(this).css("display", "");
} else {
$(this).css("display", "none");
// Check to see if all elements have been hidden
if (!$(".names:visible").length) {
// All element hidden, do something here
alert("no results");
}
}
});
});
});
EDIT
FYI - your code can be greatly simplified. This is a quick and dirty example - I'm sure that there's room for further improvement:
$(document).ready(function() {
$("#search").keyup(function() {
var query = $(this).val();
var matches = $(".names").filter(function() {
return $(this).children("td").html().toUpperCase().includes(query.toUpperCase())
}).show();
$(".names").not($(matches)).hide();
if (!$(".names:visible").length) {
$("#myTable").append("<tr class='noRecords'><td>No records found</td></tr>");
} else {
$(".noRecords").remove();
}
});
});
Here's a working fiddle.
I will suggest you that instead of adding/removing an inline CSS add/remove a class with display none, so you can find how much elements has that class and compare it againist of how much cells you have, if number matches you will know that is not displaying any cell
In the table the first column is editable and after edit it/change it I want to show the alert as Changed. I am calling the check function after 5000ms.
Adding Code Snippet for My code
Something I missed or wrong somewhere. Please Help.
Here is the Code.
var table = $("table tbody");
table.find('tr').each(function (i) {
var $tds = $(this).find('td'),
id = $tds.eq(0).text(),
product = $tds.eq(1).text();
$check = function() {
if(($tds.eq(0).text() != id) && ($tds.eq(1).text() != product)){
alert("Changed");
}
else{
alert("Not changed");
}
}
setInterval(function() { $check(); }, 5000);
alert(id + ":" + product);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td contentEditable>63</td>
<td>Computer</td>
</tr>
</tbody>
</table>
if(($tds.eq(0).text() != id) && ($tds.eq(1).text() != product)){
This only triggers when both fields changed, change it to a "||"
Also check out this: https://developer.mozilla.org/en-US/docs/Web/Events/input for capturing contenteditable changes.
If i have a table:
<table id="myTable">
<tr>
<td>1</td><td>2</td><td>NoMatch</td><td>4</td>
</tr>
<tr>
<td>1</td><td>2</td><td>Match</td><td>4</td>
</tr>
</table>
I have been trying:
$(document).ready(function () {
$('input#myInput').keyup(function (val) {
// for each third td of each row, if this value does not contain: this.val() then hide it
});
});
Something like this:
var $cells = $('#myTable tr td:nth-child(3)'),
$hidden = $();
$('#myInput').keyup(function () {
var search = this.value;
var $to_hide = $cells.filter(function() {
return $(this).text() !== search;
}).parent();
$hidden.not($to_hide.get()).show();
$hidden = $to_hide.hide();
});
I assumed that when you say contains, you mean that the text has to be equal to the provided input (otherwise NoMatch and Match would not make sense). But if the content of cell just has to contain the search string as substring, you can use .indexOf() [docs].
DEMO
There are other things you have to consider, like what should happen when the search string is empty, but this is for you to play around ;)
Use "this" in your key up event handler to get the value of the input.
$(document).ready(function () {
$('input#myInput').keyup(function () {
//add if statement
alert($(this).val());
});
});
Not quite sure what you are trying to do with the table. There is not enough information.
Try this:
jsfiddle
HTML
<table id="myTable">
<tr>
<td>1</td><td>2</td><td>NoMatch</td><td>4</td>
</tr>
<tr>
<td>1</td><td>2</td><td>Match</td><td>4</td>
</tr>
</table>
<input id="myInput"/>
Javascript/Jquery
$('#myInput').keyup(function () {
var me = $(this);
var val = me.val();
$("#myTable tr").each(function() {
var tr = $(this);
var td = tr.find("td:eq(2)");
if(td.text().substring(0, val.length) === val) {
tr.show();
} else {
tr.hide();
}
});
});