Javascript Search on HTML Table based on multiple columns - javascript

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";
}
}
}

Related

Adjusting Table Filter 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.

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";
}
}
}
}

HTML Table search on each column Individually using JavaScript

I have a table with 5 columns. the following code will filter the data on basis of all columns. I want to filter the data for each column. for ex: if there are 10 columns then 10 search fields and Also how can I make HTML part Dynamic so that I don't have to add one more search text field whenever a new column is added.
<input id="myInput" type="text" />
<script>
function filterTable(event) {
var filter = event.target.value.toUpperCase();
var rows = document.querySelector("#myTable tbody").rows;
for (var i = 1; i < rows.length; i++) {
var Col1 = rows[i].cells[0].textContent.toUpperCase();
var Col2 = rows[i].cells[1].textContent.toUpperCase();
var Col3 = rows[i].cells[2].textContent.toUpperCase();
var Col4 = rows[i].cells[3].textContent.toUpperCase();
var Col5 = rows[i].cells[4].textContent.toUpperCase();
if (Col1.indexOf(filter) > -1 || Col2.indexOf(filter) > -1 || Col3.indexOf(filter) > -1
|| Col4.indexOf(filter) > -1 || Col5.indexOf(filter) > -1) {
rows[i].style.display = "";
} else {
rows[i].style.display = "none";
}
}
}
document.querySelector(''#myInput'').addEventListener(''keyup'', filterTable, false);
</script>
I want to have this kind of functionality:
You can loop over the rows and then the columns. The Array.from method allows you to cast an element list to an array so that you can iterate over the children with Array.prototype.forEach.
All you need to do is have a show initialized to true for each row. Then if any DOES NOT column meets the filter criteria, you set show to false. After looping through all columns you display the row based on the final value of show.
Edit: Make sure you are using a browser that supports ES6+. There is a polyfill available for Array.from on the MDN site.
function filterTable(event) {
let filter = event.target.value.trim().toLowerCase();
let rows = document.querySelector('#myTable tbody').rows;
for (let i = 0; i < rows.length; i++) {
let row = rows[i], show = false;
if (filter.length > 0) {
for (let j = 0; j < row.children.length; j++) {
let col = row.children[j], text = col.textContent.toLowerCase();
if (text.indexOf(filter) > -1) {
show = true;
continue;
}
}
} else {
show = true;
}
// Avoid using 'row.styledisplay' - https://stackoverflow.com/a/28028656/1762224
// Avoid using 'row.visibility' - rows do not collapse
toggleClass(row, 'hidden-row', !show);
}
}
function toggleClass(el, className, state) {
if (el.classList) el.classList.toggle(className, state);
else {
var classes = el.className.split(' ');
var existingIndex = classes.indexOf(className);
if (state === undefined) {
if (existingIndex > -1) classes.splice(existingIndex, 1)
else classes.push(existingIndex);
} else {
if (!state) classes.splice(existingIndex, 1)
else classes.push(existingIndex);
}
el.className = classes.join(' ');
}
}
document.querySelector('#myInput').addEventListener('keyup', filterTable, false);
body {
padding: 8px;
}
.field label {
font-weight: bold;
margin-right: 0.25em;
}
#myTable {
margin-top: 0.667em;
width: 100%;
}
#myTable th {
text-transform: capitalize;
}
.hidden-row {
display: none;
}
<link href="https://unpkg.com/purecss#1.0.0/build/pure-min.css" rel="stylesheet" />
<div class="field"><label for="myInput">Filter:</label><input id="myInput" type="text" /></div>
<table id="myTable" class="pure-table pure-table-horizontal">
<thead>
<tr>
<th>name</th>
<th>drink</th>
<th>pizza</th>
<th>movie</th>
</tr>
</thead>
<tbody>
<tr>
<td>Homer</td>
<td>Squishie</td>
<td>Magheritta</td>
<td>The Avengers</td>
</tr>
<tr>
<td>Marge</td>
<td>Squishie</td>
<td>Magheritta</td>
<td>The Avengers</td>
</tr>
<tr>
<td>Bart</td>
<td>Squishie</td>
<td>Pepperoni</td>
<td>Black Dynamite</td>
</tr>
<tr>
<td>Lisa</td>
<td>Buzz Cola</td>
<td>Pepperoni</td>
<td>Iron Man</td>
</tr>
<tr>
<td>Maggie</td>
<td>Duff Beer</td>
<td>Magheritta</td>
<td>The Avengers</td>
</tr>
<tr>
<td>Kent</td>
<td>Duff Beer</td>
<td>Hawaiian</td>
<td>The Avengers</td>
</tr>
</tbody>
</table>
Search fields example
populateTable(document.getElementById('simpsons'), getData());
function dataFields(data) {
return data.reduce((r, x) => Object.keys(x).reduce((s, k) => s.indexOf(k) === -1 ? s.concat(k) : s, r), []);
}
/* Can be useful if working with raw JSON data */
function searchCriteria(fields) {
return Array.from(fields).reduce((o, field) => {
return Object.assign(o, { [field.getAttribute('placeholder')] : field.value });
}, {});
}
function onFilter(e) {
let table = e.target.parentElement.parentElement.parentElement.parentElement;
let fields = table.querySelectorAll('thead tr th input');
let criteria = searchCriteria(fields); // Unused, but useful if filtering bindable data
let searchText = Array.from(fields).map(field => field.value.trim());
Array.from(table.querySelectorAll('tbody tr')).forEach(row => {
let hideRow = false;
Array.from(row.children).forEach((col, index) => {
var value = col.innerHTML.trim().toLowerCase();
var search = searchText[index].toLowerCase();
if (search.length > 0) {
if (!value.startsWith(search)) { /* or value.indexOf(search) === -1 */
hideRow = true;
return;
}
}
});
row.classList.toggle('hidden-row', hideRow);
});
}
function populateTable(table, data) {
let fields = dataFields(data);
let thead = document.createElement('THEAD');
let tr = document.createElement('TR');
fields.forEach(field => {
let th = document.createElement('TH');
th.innerHTML = field;
tr.appendChild(th);
});
thead.appendChild(tr);
let tbody = document.createElement('TBODY');
tr = document.createElement('TR');
fields.forEach(field => {
let th = document.createElement('TH');
let input = document.createElement('INPUT');
input.setAttribute('placeholder', field);
input.addEventListener('keyup', onFilter);
th.append(input);
tr.appendChild(th);
});
thead.appendChild(tr);
data.forEach(record => {
let tr = document.createElement('TR');
fields.forEach(field => {
let td = document.createElement('TD');
td.innerHTML = record[field];
tr.appendChild(td);
});
tbody.append(tr);
});
table.appendChild(thead);
table.appendChild(tbody);
}
function getData() {
return [{
"name": "Homer",
"drink": "Squishie",
"pizza": "Magheritta",
"movie": "The Avengers"
}, {
"name": "Marge",
"drink": "Squishie",
"pizza": "Magheritta",
"movie": "The Avengers"
}, {
"name": "Bart",
"drink": "Squishie",
"pizza": "Pepperoni",
"movie": "Black Dynamite"
}, {
"name": "Lisa",
"drink": "Buzz Cola",
"pizza": "Pepperoni",
"movie": "Iron Man"
}, {
"name": "Maggie",
"drink": "Duff Beer",
"pizza": "Magheritta",
"movie": "The Avengers"
}, {
"name": "Kent",
"drink": "Duff Beer",
"pizza": "Hawaiian",
"movie": "The Avengers"
}];
}
table {
border-collapse: collapse;
width: 100%;
}
table thead tr th {
text-transform: capitalize;
}
table thead tr:last-child {
background: #eaeaea;
border-bottom: 4px double #cbcbcb;
}
table thead tr th input {
width: 100%;
}
table tbody tr:nth-child(even) {
background-color: #f2f2f2;
}
table tbody tr.hidden-row {
display: none;
}
<link href="https://unpkg.com/purecss#1.0.0/build/pure-min.css" rel="stylesheet" />
<table id="simpsons" class="pure-table pure-table-horizontal"></table>
Browser Compatibility
function onFilter(e) {
var table = e.target.parentElement.parentElement.parentElement.parentElement;
console.log(table);
var fields = table.querySelectorAll('thead tr th input');
console.log(fields);
var searchText = Array.from(fields).map(function (field) {
return field.value.trim();
});
console.log(searchText);
Array.from(table.querySelectorAll('tbody tr')).forEach(function (row) {
var hideRow = false;
Array.from(row.children).forEach(function (col, index) {
var value = col.innerHTML.trim().toLowerCase();
console.log(value);
var search = searchText[index].toLowerCase();
console.log(search);
if (search.length > 0) {
if (value.indexOf(search) === -1) {
hideRow = true;
return;
}
}
});
row.classList.toggle('hidden-row', hideRow);
});
}
All you have to do is iterate the .cells array with a for loop:
For this example, I used a variable to determine if the row should be shown.
function filterTable(event) {
var filter = event.target.value.toUpperCase();
var rows = document.querySelector("#myTable tbody").rows;
for (var i = 1; i < rows.length; i++) {
// Placeholder to indicate if a row matches the given query.
var shouldShowRow = false;
// Loop over all the cells in this row.
for (var k = 0; k < rows[i].cells.length) {
// Check to see if this cell in this row matches the query.
if (rows[i].cells[k].textContent.toUpperCase().indexOf(filter) > -1) {
// Yes, this cell matches, therefore this entire row matches.
// Flip the show row boolean to indicate that we need to show.
shouldShowRow = true;
// Because this cell matches, we do not need to check any more cells.
break;
}
}
// Change the display on the row if we need to.
if (shouldShowRow) {
rows[i].style.display = "";
} else rows[i].style.display = "none";
}
}
You can use array.
First map col to an array colArr and than using some you can match you can match filter content with content of cols .
for (var i = 1; i < rows.length; i++) {
let colArr = new Array(5).fill(0).map((e,index)=> rows[i].cells[index].textContent.toUpperCase();)
if (colArr.some(e=> e.indexOf(filter) > -1 ) {
rows[i].style.display = "";
} else {
rows[i].style.display = "none";
}
})
}

I need to filter table cells in real time (in html jQuery)

Searching Stack Overflow I was able to filter rows in real time, but I need to be more specific.
Right now I'm using this code:
HTML:
<input type="text" id="search" placeholder="Write here to filter">
Script:
$(document).ready(function(){
var $rows = $('#catalogo tbody tr');
$rows.splice(0,1);
$('#search').keyup(function() {
var val = $.trim($(this).val()).replace(/ +/g, ' ').toLowerCase().split(' ');
$rows.hide().filter(function() {
var text = $(this).text().replace(/\s+/g, ' ').toLowerCase();
var matchesSearch = true;
$(val).each(function(index, value) {
matchesSearch = (!matchesSearch) ? false : ~text.indexOf(value);
});
return matchesSearch;
}).show();
});
});
Script based on this: How to perform a real time search and filter on a HTML table
What I would like to do is be able to have 4 different inputs, each one filtering first, second, third and fourth cells of each row (to be able to filter by title, author, year and max price).
How could I acomplish this?
Thanks to blackandorangecat's link I managed to put something together.
HTML:
<label class = "text">Título:<input type="text" id="stitulo" onkeyup="filter(this, 0)" style="margin: 0 auto;"/></label>
<label class = "text">Autor:<input type="text" id="sautor" onkeyup="filter(this, 1)" style="margin: 0 auto;"/></label>
<label class = "text">Año:<input type="text" id="sano" onkeyup="filter(this, 3)" size="1" style="margin: 0 auto;"/></label>
<label class = "text">Precio máximo:<input type="text" id="sprecio" onkeyup="filterNum(this, 4)" size="1" style="margin: 0 auto;"/></label>
JavaScript:
function filter(x, y) {
// Declare variables
var input, filter, table, tr, td, i;
input = x;
filter = input.value.toUpperCase();
table = document.getElementById("catalogo");
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")[y];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
function filterNum(x, y) {
// Declare variables
var input, filter, table, tr, td, i;
input = x;
if(input.value === "") {
filter = 0.;
}
else filter = parseFloat(input.value);
table = document.getElementById("catalogo");
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")[y];
if (td) {
if ((filter >= parseFloat(td.innerHTML)) || filter === 0) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
Hopefully this will help other people too.

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

Categories

Resources