Adjusting Table Filter Javascript - javascript

I'm trying to adjust some javascript that currently allows a user to enter text into an input, then it would hide all rows that do not contain that text. Right now it only checks the first column, but I would like it to check columns 1 and 2:
HTML:
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<table id="myTable">
<tr class="header">
<th style="width:60%;">Name</th>
<th style="width:20%;">Country</th>
<th style="width:20%;">Size</th>
</tr>
<tr>
<td>Joe Smith</td>
<td>Canada</td>
<td>Medium</td>
</tr>
<tr>
<td>Jane Doe</td>
<td>Germany</td>
<td>Small</td>
</tr>
</table>
So in the simple example below, you could type either Jane or Germany to have that row show filter.
JAVASCRIPT:
<script>
function myFunction() {
var input, filter, table, tr, td, i, txtValue;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
</script>

Try this:
for (i = 0; i < tr.length; i++) {
var found = false;
for (j = 0; j < 3; j++){
td = tr[i].getElementsByTagName("td")[j];
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
found = true;
break;
}
}
}
if (found) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
Create an inner loop over the columns, checking each columns. When text is found, break the loop. After loop, check found property, set route display.

Related

Filter between two input dates on html table - Java script

I'm trying to filter on my html table by inputting two dates(From and To) and then it should filter the data in the html table column[0] "Date Column" accordingly.
The inputs on my page::
<input type="date" id="date-start" onselect="searchDate()" />
<input type="date" id="date-stop" onselect="searchDate()" />
The java script I have together so far is:
function searchDate() {
var input_startDate, input_stopDate, table, tr, i;
input_startDate = document.getElementById("date-start");
input_stopDate = document.getElementById("date-stop");
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td_date = tr[i].getElementsByTagName("td")[0];
if (td_date) {
if (td_date >= input_startDate && td_name <= input_stopDate) {
??? - Display Rows;
}
else {
??? - Hide Rows;
}
}
}
}
I know this might be pretty straight forward but I have no idea what to do as I can't seem to get it working.
My table gets created as follows:
#if (employees is null)
{
<p style="color:white;"><em>Loading . . .</em></p>
}
else
{
<table class="table" id="myTable">
<thead>
<tr>
<th style="border: none;">Entry Date</th>
<th style="border: none;">Employee</th>
</tr>
</thead>
<tbody>
#foreach (var employee in employees)
{
<tr>
<td style="vertical-align: middle; border: none;">#employee.EntryDate</td>
<td style="vertical-align: middle; border: none;">#employee.POI</td>
</tr>
}
</tbody>
</table>
}
Any help would be appreciated.
Database format is: 2020-06-05 10:57:10
Thanks.
You have multiple issues in the sample:
you are not getting the actual values from the table td cells or
inputs
you need to convert the values to dates to compare
correctly
you can then hide/show a row by setting the display
property on the style
See the commented demo below:
function searchDate() {
var input_startDate, input_stopDate, table, tr, i;
// get the values and convert to date
input_startDate = new Date(document.getElementById("date-start").value);
input_stopDate = new Date(document.getElementById("date-stop").value);
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
// you need to get the text and convert to date
let td_date = new Date(tr[i].getElementsByTagName("td")[0].textContent);
// now you can compare dates correctly
if (td_date) {
if (td_date >= input_startDate && td_date <= input_stopDate) {
// show the row by setting the display property
tr[i].style.display = 'table-row;';
} else {
// hide the row by setting the display property
tr[i].style.display = 'none';
}
}
}
}
function searchDateAlternative() {
// get the values and convert to date
const input_startDate = new Date(document.getElementById("date-start").value);
const input_stopDate = new Date(document.getElementById("date-stop").value);
// only process table body rows, ignoring footer/headers
const tr = document.querySelectorAll("#myTable tbody tr")
for (let i = 0; i < tr.length; i++) {
// ensure we have a relevant td
let td = tr[i].getElementsByTagName("td");
if (!td || !td[0]) continue;
// you need to get the text and convert to date
let td_date = new Date(td[0].textContent);
// now you can compare dates correctly
if (td_date) {
if (td_date >= input_startDate && td_date <= input_stopDate) {
// show the row by setting the display property
tr[i].style.display = 'table-row;';
} else {
// hide the row by setting the display property
tr[i].style.display = 'none';
}
}
}
}
#myTable td {
border: 1px solid;
border-collapse: collapse;
}
<input id="date-start" type="text" value="2020-01-01"></input>
<input id="date-stop" type="text" value="2020-01-02"></input>
<button type="button" onclick="searchDateAlternative()">Go</button>
<hr/>
<table id="myTable">
<thead>
<tr>
<td>Date</td>
<td>Name</td>
</tr>
</thead>
<tbody>
<tr>
<td>2020-01-01</td>
<td>Foo</td>
</tr>
<tr>
<td>2020-01-02</td>
<td>Bar</td>
</tr>
<tr>
<td>2020-01-03</td>
<td>Baz</td>
</tr>
</tbody>
</table>
You can use style.display to hide/show your rows. Set it to 'none' to hide the rows or 'block' to view them.
function searchDate() {
var input_startDate, input_stopDate, table, tr, i;
input_startDate = document.getElementById("date-start");
input_stopDate = document.getElementById("date-stop");
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td_date = tr[i].getElementsByTagName("td")[0];
if (td_date) {
if (td_date >= input_startDate && td_name <= input_stopDate) {
tr[i].style.display = "block";
}
else {
tr[i].style.display = "none";
}
}
}
}

Javascript Search on HTML Table based on multiple columns

I am trying to perform search on 4 columns and expecting results to have union of the results.
For example : if keyword 'Test' is in two column in two different rows
then both rows should be displayed.
But currently I am able to search only on one column. Is there a way to search on multiple columns. My search function is below. Any suggestions are appreciated thank you.
function MySearch() {
// Declare variables
var input, filter, table, tr, td, td1,td2,td3, i;
input = document.getElementById("TxtSearch");
filter = input.value.toUpperCase();
table = document.getElementById("TblSearchData");
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];
td1 = tr[i].getElementsByTagName("td")[1];
td2 = tr[i].getElementsByTagName("td")[2];
td3 = tr[i].getElementsByTagName("td")[3];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
if (td1) {
if (td1.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
else if (td2) {
if (td2.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
else if (td3) {
if (td3.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
Here is a partial jQuery version, should work even if you add rows since it starts from the top each time. I added a clear button just to show how to do that.
IF you wish to match ALL terms entered you would need to modify slightly like for "bunny fish" for example to only return 1 row.
Supports multiple terms (inclusive): try "red orange" or "black bunny"
Supports an empty search (shows all)
Does not support partial words.
Supports adding new columns.
$('#searchem').on('click', function() {
let searchText = $('#TxtSearch').val();
let searchTerms = searchText != ""? searchText.split(" "): [];
MySearch(searchTerms);
});
$('#clearem').on('click', function() {
let searchText = $('#TxtSearch');
searchText.val("");
let searchTerms = [];
MySearch(searchTerms);
});
function MySearch(terms) {
let searchTable = $('#TblSearchData');
let searchRows = searchTable.find('tbody').find('tr');
let searchValues = searchRows.find('td');
// console.log("terms:",terms.length);
searchValues.closest('tr').toggle(!terms.length); //hide em all
// show ones with matches
searchValues.filter(function(index, element) {
let found = false;
var fieldTerms = $(element).text().split(" ");
for (let term of fieldTerms) {
// console.log("term:", term);
if (terms.includes(term)) {
// console.log("Found:", term);
found = true;
break;
}
}
return found;
}).closest('tr').toggle(true);
// Declare variables
}
td {
border: solid blue 1px;
}
.found {
display: solid red 1px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<input id="TxtSearch" type="text" />
<button id="searchem" type="button">Search</button><button id="clearem" type="button">Clear</button>
<table id="TblSearchData">
<tbody>
<tr>
<td>Row 1 blue fish</td>
<td>feet, what are feet</td>
<td>reep red</td>
<td>sad panda</td>
<td>black panda</td>
<td>cheese ball</td>
</tr>
<tr>
<td>Row 2 red fish</td>
<td>white fish</td>
<td>blue cat</td>
<td>orange moose</td>
<td>bunny fish</td>
<td>tish fish</td>
</tr>
<tr>
<td>Row 3 orange fish</td>
<td>wax moose</td>
<td>brown moose</td>
<td>walter here</td>
<td>gone tish</td>
<td>wonder what</td>
</tr>
<tr>
<td>Row 4 one fish</td>
<td>orange cow</td>
<td>moose cow with blue feet</td>
<td>chicken</td>
<td>chicken egg</td>
<td>petes dragon</td>
</tr>
</tbody>
</table>
Basically you have the idea..only i tweaked... the decision to show or not... after perform the search in all "td"...and no at the first occurs of them...because one td cancel the other...and not desired effect.... try the code below
Sorry for my English
function MySearch() {
// Declare variables
var input, filter, table, tr, td, td1,td2,td3, i;
input = document.getElementById("TxtSearch");
filter = input.value.toUpperCase();
table = document.getElementById("TblSearchData");
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];
td1 = tr[i].getElementsByTagName("td")[1];
td2 = tr[i].getElementsByTagName("td")[2];
td3 = tr[i].getElementsByTagName("td")[3];
is_present = 0;
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
is_present = 1
}
}
if (td1) {
if (td1.innerHTML.toUpperCase().indexOf(filter) > -1) {
is_present = 1
}
}
else if (td2) {
if (td2.innerHTML.toUpperCase().indexOf(filter) > -1) {
is_present = 1
}
}
else if (td3) {
if (td3.innerHTML.toUpperCase().indexOf(filter) > -1) {
is_present = 1
}
}
if (is_present == 1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}

How to display multiple cells in Table Search

I'm wondering if there is a way for this search bar that I'm using to display multiple elements. As it is right now if I search for "123" in a pool with "321" "1234" "123" "12345" The only displayed value would be the first one: "1234". I'd like for all values that match my search to be displayed, therefore this would be the correct search result: "1234" "123" "12345".
Any answer is appreciated.
Here's the current code that I have:
var cells = document.querySelectorAll("#myTable td");
var search = document.getElementById("myInput");
search.addEventListener("keyup", function() {
if (search.value.length > 0 && search.value != '') {
for (var i = 0; i < cells.length; ++i) {
if (cells[i].textContent.toLowerCase().indexOf(search.value.toLowerCase()) === 0) {
cells.forEach(function(element) {
element.style.display = "none";
});
cells[i].style.display = "table-cell";
break;
} else {
cells.forEach(function(element) {
if (cells[i] !== element) {
element.style.display = "table-cell";
}
});
}
}
} else {
cells.forEach(function(element) {
if (cells[i] !== element) {
element.style.display = "table-cell";
}
});
}
});
<input id="myInput">
<table id="myTable">
<tr>
<td>321</td>
<td>123</td>
</tr>
<tr>
<td>1234</td>
<td>abc</td>
</tr>
<tr>
<td>12345</td>
<td>abcde</td>
</tr>
</table>
Your cells selector returns a nodelist this is an arrayish object. That doesn't have the forEach function.
However we can borrow from the Array object:
Array.prototype.forEach
What I did to solve the other problem is create an indexArray as a lookup array. that keeps track of the indices that contained the search string. Then when we loop all the cells we can turn the ones of that don't show up in the lookup array
var cells = document.querySelectorAll("#myTable td");
var search = document.getElementById("myInput");
search.addEventListener("keyup", function() {
var indexArray = []; //look up array
for (var i = 0; i < cells.length; ++i) {
//restore the cells:
cells[i].style.display = "table-cell";
//if search value is found the value will be 0 if it starts a the beginning
if (cells[i].textContent.toLowerCase().indexOf(search.value.toLowerCase()) === 0) {
indexArray.push(i); //push index into lookup
}
}
//loop over all cells
Array.prototype.forEach.call(cells, function(element, index) {
if (indexArray.indexOf(index) === -1) //if index is not present in look up, set display to none
element.style.display = "none";
});
});
<input id="myInput">
<table id="myTable">
<tr>
<td>321</td>
<td>123</td>
</tr>
<tr>
<td>1234</td>
<td>abc</td>
</tr>
<tr>
<td>12345</td>
<td>abcde</td>
</tr>
</table>
below code is enough if you want to show which cell has contain that search; also you can test on jsfiddle https://jsfiddle.net/bzcdomjs/
var cells = document.querySelectorAll("#myTable td");
var search = document.getElementById("myInput");
search.addEventListener("keyup", function() {
for (var i = 0; i < cells.length; ++i) {
cells[i].style.display = "table-cell";
if (search.value.length > 0 && search.value != '') {
if(cells[i].textContent.toLowerCase().indexOf(search.value.toLowerCase()) === -1) {
cells[i].style.display = "none";
}
}
});

Follow-up of search values from first column in html table using JS?

This is my follow-up question of this... See here. I have a jscript(courtesy of hex494D49), searching values from first column.
All I need is, when the values is searching by the user, the table headers will also displayed and if the values is not store. There's a message will display like this "No results found". How to do that?
Here's the JSfiddle file with html
Here's the JScript:
document.getElementById('term').onkeyup = function(){
var term = this.value;
var column = 0;
var pattern = new RegExp(term, 'g');
var table = document.getElementById('dataTable');
var tr = table.getElementsByTagName('TR');
for(var i = 0; i < tr.length; i++){
var td = tr[i].getElementsByTagName('TD');
for(var j = 0; j < td.length; j++){
if(j == column && td[j].innerHTML == term){
console.log('Found it: ' + td[j].innerHTML);
tr[i].style.display = 'block';
return;
alert('Found it: ' + td[j].innerHTML);
}else{
tr[i].style.display = 'none';
}
}
}
};
This would be the table markup. As you can see, I added thead, tbody and tfoot groups
<!-- search box -->
<input type="text" name="term" id="term" autocomplete = "off" />
<!-- table results -->
<table id="dataTable">
<thead>
<tr>
<th>Example No.</th>
<th>Column 1</th>
<th>Column 2</th>
</tr>
</thead>
<tfoot>
<tr>
<th colspan="3"></th>
</tr>
</tfoot>
<tbody>
<tbody>
<tr>
<td>345678917</td>
<td>Test 1</td>
<td>one_test1#gmail.com</td>
</tr>
<tr>
<td>3512376894</td>
<td>Test 2</td>
<td>two.test2#hotmail.com</td>
</tr>
</tbody>
</table>
Default CSS for the markup above. Next step would be merging the following with the rest of your CSS.
table thead {
display: table-row-group;
}
table tbody {
display: table-row-group;
}
table tbody tr {
display: none;
}
And finally the JavaScript snippet using getElementsByTagName() method
// JavaScript
document.getElementById('term').onkeyup = function(){
var term = this.value;
var column = 0;
var msg = 'No results found!';
var pattern = new RegExp(term, 'g');
var table = document.getElementById('dataTable');
var tr = table.getElementsByTagName('TR');
for(var i = 0; i < tr.length; i++){
var td = tr[i].getElementsByTagName('TD');
for(var j = 0; j < td.length; j++){
if(j == column && td[j].innerHTML == term){
tr[i].style.display = 'table-row';
table.tFoot.innerHTML = '';
return;
}else{
tr[i].style.display = 'none';
table.tFoot.innerHTML = msg;
}
}
}
};
Working jsFiddle | Version without tfoot jsFiddle
The same as above but using rows[] and cells[] collection
HTML
<!-- Search box -->
<input type="text" id="search" autocomplete = "off" />
<!-- Table -->
<table id="table">
<thead>
<tr>
<th>Product</th>
<th>Manufacturer</th>
<th>Price</th>
<th>InStock</th>
</tr>
</thead>
<tbody>
<tr>
<td>MacBook Air</td>
<td>Apple</td>
<td>$456</td>
<td>85</td>
</tr>
<tr>
<td>Arc GIS</td>
<td>ESRI</td>
<td>$4556</td>
<td>15</td>
</tr>
<tr>
<td>3ds MAX</td>
<td>Aurodesk</td>
<td>$6556</td>
<td>359</td>
</tr>
<tr>
<td>Windows 7</td>
<td>Micorsoft</td>
<td>$256</td>
<td>2567</td>
</tr>
</tbody>
</table>
<!-- Message -->
<div id="message"></div>
CSS
table thead {
display: table-row-group;
}
table tbody tr {
display: none;
}
JavaScript
document.getElementById('search').onkeyup = function(){
var table = document.getElementById('table'),
tr = table.rows, td,
term = this.value.toLowerCase(), column = 0, i, j,
message = document.getElementById('message');
for(i = 1; i < tr.length; i++){
td = tr[i].cells;
for(j = 0; j < td.length; j++){
if(j == column && td[j].innerHTML.toLowerCase() == term){
tr[i].style.display = 'table-row';
message.innerHTML = '';
return;
}else{
tr[i].style.display = 'none';
message.innerHTML = 'No results found!';
}
}
}
};
Working jsFiddle If you won't use thead and tbody in your table here is another version jsFiddle
I case you want to search all columns, just change this line
if(j == column && td[j].innerHTML.toLowerCase() == term){
to this one
if(td[j].innerHTML.toLowerCase() == term){
And finally, if you want to have more flexible search try the version below
document.getElementById('search').onkeyup = function(){
var table = document.getElementById('table'),
tr = table.rows, td,
term = this.value.toLowerCase().trim(), column = 0, i, j,
message = document.getElementById('message'),
pattern = new RegExp(term, 'gi');
for(i = 1; i < tr.length; i++){
td = tr[i].cells;
for(j = 0; j < td.length; j++){
if(j == column && term.length > 0 && td[j].innerHTML.match(pattern)){
tr[i].style.display = 'table-row';
message.innerHTML = '';
return;
}else{
tr[i].style.display = 'none';
message.innerHTML = 'No results found!';
}
}
}
};
Working jsFiddle

Show Hide Dynamically Added Table Row

I have implement search on table and it works fine. But there is one problem after I update the table row. Search always show the edited row even if it does not match the search.
eg. steps -
1.enter "user3" in search box then result - user3
2.edit "user3"
3.enter "user1" in search box then result - user1,user3
HTML
<table>
<tbody id="list">
<tr id="o1">
<td class="txtclass">user</td>
<td><a>edit</a></td>
</tr>
<tr id="o2">
<td class="txtclass">user2</td>
<td><a>edit</a></td>
</tr>
<tr id="o3">
<td class="txtclass">user3</td>
<td><a>edit</a></td>
</tr>
<tr id="o4">
<td class="txtclass">user4</td>
<td><a>edit</a></td>
</tr>
</tbody>
</table>
script
// function to replace table row
// d- table row html
function updateRow(d)
{
$("#o3").before(d).remove();
}
// search in table row list
$("#textsearch").change(function () {
var filter = $(this).val().toLowerCase();
var li;
list = list of table rows;
len = list.length;
for (var i = 0; i < len; i++) {
li = list[i];
txt = $(li).find(".txtclass").text();
if ((txt || "").toLowerCase().indexOf(filter) >= 0) {
if (li.style.display == "none") { li.style.display = "block"; }
} else {
if (li.style.display != "none") { li.style.display = "none"; }
}
}
return false;
}

Categories

Resources