Pages

HTML table search using JavaScript

Its a common practice to display large data using table elements. Moreover, many a times its obvious to provide facility to search through the displayed data especially when there are hundreds or thousands of rows and columns. One cannot expect users to keep scrolling vertically/horizontally for finding information of their interest.

Update: Improved version of this is now available here. This highlights search results and shows message if no results are found.

Today I am going to show you an easiest way to search through a html table using JavaScript. You can view demo here. Lets understand how this is done!
Consider a table with id 'dataTable' having 3 columns (column count and column names do not matter, they can be anything) and a textbox 'searchTerm' for entering search keyword/s. Something like this:
<input type="text" id="searchTerm" class="search_box" onkeyup="doSearch()" />
<table id="dataTable" border="1" width="100%" cellspacing="0" cellpadding="5">
     <thead>
         <tr>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Email Address</th>
         </tr>
     </thead>
     <tbody>     
         <tr>
            <td>Nikhil</td>
            <td>Vartak</td>
            <td>nikhil.vartak@hotmail.co.in</td>
         </tr>
         <tr>
            <td>Peter</td>
            <td>James</td>
            <td>james_peter@hotmail.com</td>
         </tr>
         <tr>
            <td>Nikhil</td>
            <td>Vartak</td>
            <td>nikhilvartak@yahoo.com</td>
         </tr>
     </tbody>
</table>
You can view complete code (demo link above) by right click > view source in browser window.

doSearch() function:
function doSearch() {
    var searchText = document.getElementById('searchTerm').value;
    var targetTable = document.getElementById('dataTable');
    var targetTableColCount;
            
    //Loop through table rows
    for (var rowIndex = 0; rowIndex < targetTable.rows.length; rowIndex++) {
        var rowData = '';

        //Get column count from header row
        if (rowIndex == 0) {
           targetTableColCount = targetTable.rows.item(rowIndex).cells.length;
           continue; //do not execute further code for header row.
        }
                
        //Process data rows. (rowIndex >= 1)
        for (var colIndex = 0; colIndex < targetTableColCount; colIndex++) {
            rowData += targetTable.rows.item(rowIndex).cells.item(colIndex).textContent;
        }

        //If search term is not found in row data
        //then hide the row, else show
        if (rowData.indexOf(searchText) == -1)
            targetTable.rows.item(rowIndex).style.display = 'none';
        else
            targetTable.rows.item(rowIndex).style.display = 'table-row';
    }
}

Logic:
  1. Get text entered in search textbox (searchText variable) and reference to the html table (targetTable variable)
  2. Loop through table rows (outer loop). For each row, loop through its columns (inner loop) and get the cell values. Concatenate these values and store in a variable (rowData).
  3. If rowData does not contain searchText then hide the row by setting css display property to 'none'. Else set display to 'table-row'. This else condition is needed because when user searches with new keyword we need to re-display the matching row if it was hidden during previous search.

106 comments:

  1. Its working in mozilla browser but in IE8 & IE9 browsers the script is not working.
    do you think any modifications required in script for IE

    ReplyDelete
    Replies
    1. All I did was replace this line:

      rowData += targetTable.rows.item(rowIndex).cells.item(colIndex).textContent;
      ==|>
      rowData += targetTable.rows.item(rowIndex).cells.item(colIndex).innerText;

      Delete
    2. Refer the script from demo URL. It's already updated in which it checks the browser version and uses text property accordingly.

      Delete
  2. Hi Abdul,

    Thanks for pointing out IE8/9 issue.

    Cause: textContent works in Firefox, Chrome and Opera but not IE though textContent is recommended by W3C.

    Solution: Check if browser is IE family, if so use innerText, else textContent. I have updated the code on demo url. It now works well in IE too.

    Please check and do let me know. :)

    ReplyDelete
  3. Thanks Nikhil for giving solution for IE. I used the fix what you have given.Its wonderful.Now script is working in all major browser.
    Thanks a lot :).

    ReplyDelete
  4. Hi this is really cool. Is there a way to have the table elements hidden (except thead) and results appear as they are typed into search box? So everything is hidden initially and results appear as user types..

    ReplyDelete
    Replies
    1. This is not Impossible, however, I really wonder when and why would someone want to display search results in tabular format like grid. If you just want to display suggestions as user types, I suggest you have a look at auto completer: http://dotnetprof.blogspot.in/2012/12/auto-complete-textbox-using-jquery.html.

      Delete
  5. Really nice - lovely to play around with! Just a quick one - I've noticed that, when searching, it takes in to consideration capitalization of letters and won't find a piece of information that is lower case. E.g in the table it says "Monday" but if you search for "monday" then it won't get it...is there a fix for this?

    ReplyDelete
    Replies
    1. Thanks Dave for pointing that out! Well, there was a quick fix for making search case insensitive. You can check the new code now.

      Delete
    2. This comment has been removed by the author.

      Delete
    3. Hi Nikhil i want to know that how to get case insensitive code of this

      Delete
  6. i have a table with header each column . how can i display the headers in the target table?

    ReplyDelete
    Replies
    1. The script above already ignores header row from search. So your headers will always be visible.

      Delete
  7. I have 5 table headers in my table. I noticed that the code is only reading content from the last column in the table, which is labeled email. If I search for a content that does not have an email address load in the email column then no content is displayed. How can I change the code to pull content from a different column?

    ReplyDelete
    Replies
    1. It searches all the columns of the table. In demo it does not show results because each row has similar words. Remove email address column from html source code and run the page and try!

      Delete
    2. I have to many rows with email address to remove the email address column. Here is my contact page that I am using your source code on:
      http://www.waycrossga.com/phone_dir_name.htm

      Delete
    3. If you search for the third person on my contact list, the search result is blank, because the email field is blank. I would like the search result to utilize the last name column. Since it will return a morn accurate search.

      Delete
    4. Here is my contact list I am working with your source code:
      http://www.waycrossga.com/phone_dir_name.htm

      Delete
    5. I have too much content in my table to remove the email column from the table.
      Here is my contact list I am working with your source code:
      http://www.waycrossga.com/phone_dir_name.htm
      If you search the contact list by last name you will notice that the third row will not display, since the email field is blank. I would like to search the last name field, since the content in the field is more accurate.

      Delete
    6. I got it! You are not using updated script. I had updated it for case-insensitivity when Dave pointed out. Check the comments above. The script you are using is case sensitive hence when you search with j it removes James (3rd row) as J there is capital.

      Delete
    7. Thanks Nikhil, the update script worked.

      Delete
    8. Can You please comment the updated code once again now.. i need it..

      Delete
  8. a jsfiddle would be appreciated for fast surfers...

    ReplyDelete
  9. if only to search from first column than?

    ReplyDelete
    Replies
    1. This is very simple, you could do it easily friend, if you understood the script! :) No problem, here's the change you need to do:

      //Process data rows. (rowIndex >= 1)
      //for (var colIndex = 0; colIndex < targetTableColCount; colIndex++) {
      rowData += targetTable.rows.item(rowIndex).cells.item(0).textContent;
      //}

      Remove for loop and hard code column index as 0.

      Delete
    2. First of all I want to thank you for this great tutorial. I would like to ask you which line of code we have to change in order to search only data on 2 column or in 3 column and so on. Because I have 5 column table and I need to build 5 different searches? You would save my life it do you find time to reply to my request. Tori

      Delete
    3. or u can just replace "targetTableColCount" with "2" / "3"...depend on how many column you want..

      *noted that the count start with "0"...

      Delete
  10. and how to remove case senitivity

    ReplyDelete
  11. If there is none of the search criteria found is there a way that I can say "No Search Results Found!"

    ReplyDelete
    Replies
    1. Yes that's easy. Just check if results are found else create a row with one td having colspan equal to no of columns and append it with 'no results found'. Add this row to table.

      Delete
    2. I can't manage this? could you provide a code snippet based on your example please?

      Delete
    3. same i didnt manage this can u please provide me the code

      Delete
  12. Simple And Nice..But If you search with is we don't get exact name OR Email.

    For ex search criteria is based on Name

    how we have to get.

    ReplyDelete
    Replies
    1. Hi Peter,

      I didn't get you. Can you elaborate?

      Delete
    2. For Eg (Consider Above give table). If user search by (T first letter)It will Display all Three Record From The Above Given Scenario .Moreover Search Criteria is Based on Index(it returns Position of First Occurrence).we have to Use Match to get Exact Names or Email.

      Delete
  13. very nice code Nikhil! How would you search for two specific columns. say column 2 and 3?

    ReplyDelete
    Replies
    1. Add a condition in columns' loop.

      for (var colIndex = 0; colIndex < targetTableColCount; colIndex++) {
      if(colIndex == 1 || colIndex == 2) {
      rowData += targetTable.rows.item(rowIndex).cells.item(colIndex).textContent;
      }
      }

      Or you can remove for loop altogether and just hardcode column indexes.

      Delete
  14. IF i give the data in the table at the search box, with replacing first letter of data to UPPER CASE, the search result throws none. can u give me code for avoiding that case sensitive issue.

    ReplyDelete
  15. @Nikhi ...works fine.....tnx

    ReplyDelete
  16. Hi Nikhil, firstly love the work. Could this work for mutiple tables i.e 3 tables on a single page?

    ReplyDelete
    Replies
    1. Technically yes but practically you should avoid that. It will involve looping 3 tables, their rows (can be large no) and columns (again can be large in no) on each key press. If requirement is must, you need to optimize script more. One possible thing would be to remove looping through columns, pick a row and use regex to strip td tags and match text. Don't use the script as is. It will work for sure but think about performance.

      Delete
    2. hi nikil..form is not working besacuse of "thead and tboby"..plz say any suugesstion instead of "tbody and thead" tags

      Delete
    3. it's working fine nikil...thanks

      Delete
  17. Hi, suppose in search if i gave "Nikhil" means it has to return only the value "Nikhil" not the complete row(like "Nikhil", "Vartak","nikhil.vartak@hotmail.co.in").

    ReplyDelete
    Replies
    1. Search would be useless feature in that case. It's a table search, one enters keywords and script returns matching rows. If you enter Nikhil and expect to get only 'Nikhil' values, you would not need to search even as you already know What u want. On the other hand, you might only remember first-name as Nikhil and want to know email address for example, returning row seems practical.

      Delete
    2. Searching exact word is required because by doing so we can get more accurate results as we don't need all results containing the word but only the exact one.

      Delete
  18. very nice and fast functionality, easy to implement.

    Thanks for such a nice post.

    ReplyDelete
  19. This comment has been removed by a blog administrator.

    ReplyDelete
  20. Great and easy tutorial!

    Thanks mate!

    ReplyDelete
  21. Very nice post ! Its possible to highlight the search text in table?

    ReplyDelete
  22. Hy, Great work, works like a charm! One question...i have 1 html file with multiple tables, each with there own searchbox. What is the best aproach, "copy" the dosearch script for each tabel and change the tableID's? Or is it posible to use 1 script in the header that only uses the table from the ID given in the searchbox code?

    ReplyDelete
  23. Please advise me how to display if search term is not found in row data, as
    "Nothing Found
    Sorry, but nothing matched your search criteria"
    thanks

    ReplyDelete
    Replies
    1. Check comments at the beginning. I have mentioned about adding extra row for 'no results found'.

      Delete
  24. Hello Nikhil, Awesome script, though it is case sensitive. how Can we have it case insensitive

    ReplyDelete
    Replies
    1. view the page source of the demo ...
      It's there...

      Delete
  25. is there a limitation on the size of the table as far as the number of rows?

    ReplyDelete
    Replies
    1. No limitation, however if table is too large you should consider using search + pagination.

      Delete
  26. Hi Nikhil,

    Great work !!
    I have lots and lota of rows in my table which is why i have limited the display to be 15 rows per page and provided with next and previous buttons so wen im searching it is searching within those 15 entries in the current page how to make it search through all the rows in the table irrespective of the page in which they are displayed.

    Thanks

    ReplyDelete
    Replies
    1. Perhaps, I shall write a separate post for this! It is not going to be small code as we must restore pager state if search is reset.

      Delete
  27. hello, thanks a lot!! but i cannot read the code properly, what if i dont want the header and what to search all rows and collums?

    ReplyDelete
  28. Holy Hell.
    I don't know Javascript at all, but was able to implement your code to search my table no problems.
    This worked perfectly for my purposes and you saved me oodles of time and effort.
    My thanks!

    ReplyDelete
  29. HI ,the data in my table is from the database,
    Can u plz help me how i can add search field for this table?

    ReplyDelete
    Replies
    1. How does it make difference? Script will work even after you pull data from database and display in table.

      Delete
  30. My thead only contained two cells, I have updated the if check to check if rowIndex is 1 instead of 0.

    if (rowIndex == 1) { // 1 because 0 is the theader row
    targetTableColCount = targetTable.rows[rowIndex].cells.length;
    continue;
    }

    ReplyDelete
  31. I have added a clear button like this:
    http://jsfiddle.net/gdWNZ/1/show/

    ReplyDelete
  32. HI, I tried this. On Enter the value into the field and i pressed enter button. nothing is happening.. Below i pasted the code.

    ReplyDelete
  33. $(document).ready(function () {
    $("#searchInput").keyup(function () {
    var val = $(this).val();
    val = val.toLowerCase();
    $("#searchTable tr:first th").hide();
    $("#searchTable tr td").each(function (i) {
    var content = $(this).text();
    if (content.toLowerCase().indexOf(val) == -1) {
    $(this).hide();
    } else {
    var l = $(this).index();
    $(this).show();
    $(this).parents("table").find("tr:first th:eq(" + l + ")").show();

    }
    });
    });
    });

    ReplyDelete
    Replies
    1. Yup JQuery code will always be smaller :)

      Delete
  34. Hi Nikhil Vartak, I'm very grateful to you. I've been looking for this ways long. Once again, I'm very grateful. Hopefully your knowledge increase. ^_^

    ReplyDelete
  35. Did you take down your demo? I am unable to get the link to open it.

    ReplyDelete
    Replies
    1. It is working (as always!) https://dl.dropboxusercontent.com/u/30067641/Host/SearchHtmlTableUsingJavascript.htm

      Delete
  36. Hello Nikhil

    I am using this script on smaller screens where the tags, table, tr, and td's have been given a CSS width:100%; in order to cover the whole screen.

    but this (excellent) script truncates the 'found' entries. They only extend to text width and the screen is left uncovered for short entries.


    I added som CSS the the last line of the script as below.


    >>>>targetTable.rows.item(rowIndex).style.display = 'table-row, width="100%"';

    The problem is, it only works for the first search and shows the result 100% across the screen.
    But any further seaches will not work.
    If I take my addition - width="100%" out of your code then the whole thing worls OK except that the results are truncated in width to the text length of the entries.

    Is the any way this can be corrected please?

    John Guise - Kaweru, New Zealand

    ReplyDelete
  37. Hi Nikhil, if i want to highlight the searched text in datatable after searching.

    ReplyDelete
  38. hi!

    nice script,.. the only working for me.. but... how can i.. let say.. ignore some rows? kind of multiple headers...

    thanks in advance!

    ReplyDelete
  39. how can define result is empty or nor

    ReplyDelete
  40. Hi,
    What if i prefer to save my table separately in a file or hidden from user?

    ReplyDelete
  41. Hi, great bit of code however I am ahving trouble with my pagination as it will only search my first page rather than all the other pages, is there anyway to fix this?

    ReplyDelete
    Replies
    1. It will not search only 1st page but whichever page you are on. In pagination we do not load records for all the pages, only for the active one. Script will search only through records which are currently loaded into the table.

      Delete
    2. Is there anyway to circumvent this? Load all data when the search starts?

      Delete
    3. "Load all data when the search starts" - I would never do that, at least not on each key stroke. That will work at the cost of performance. Anyways if you want to go that way, this code won't work as is. You have to change it to make ajax/database/service calls, parse results, bind grid through JS and so on. Lot of stuff. Pagination is a good feature. Keep it. :)

      Delete
  42. Is it possible to use if my search bar is in a different div so as the table itself ? How ?

    ReplyDelete
    Replies
    1. That won't make any difference as long as our code is able to get reference (find) the table on page.

      Delete
  43. Is there a way to make it only search for an exact match? For example, I have three rows, two that contain A-250 and one that has A-250A. I only want it to show the first two because they match the query and have to additional characters before or after.

    ReplyDelete
  44. tons of thanks to you bro.... it works perfect for me and lot of time

    ReplyDelete
  45. Thank u Nikhil Vartak u made my day

    ReplyDelete
  46. Thank u Nikhil Vartak u made my day

    ReplyDelete
  47. Hi,

    When I search once, everything works. I then hold backspace to clear the search, and the table doesn't revert back to normal (with all records). I then press the space button and it then reverts back to normal!

    Any thoughts why this is, and how to perhaps change it?

    ReplyDelete
    Replies
    1. Difficult to guess from here without looking what you have done. It works in demo, however. Type 'ni' gives 2 rows > backspace ('n' remaining) gives 5 > backspace (empty) gives all 6.

      Delete
  48. Thanks and God bless you for the post. Nice, fast and easy to implement. Solved my live search problem.

    ReplyDelete
  49. Hello,
    I want differnt search box for differnt column
    for exampel
    GRNo Name

    ReplyDelete
  50. Thank you for you efforts and for sharing it is much appreaciated

    ReplyDelete
  51. Thank you for your code

    I have also written short jquery code to search the table data
    http://seowebsitedesigning.com/live-text-search-in-html-table-using-jquery/

    ReplyDelete
  52. Hi

    How do we implement pagination like Next and prev buttons if the table input is dynamic and search through it

    ReplyDelete
  53. i have a code of jquery i need to fetch data ie to search data which is in html table format and to fetch data which is in next page link also i need to retrieve data can anyone help me out

    ReplyDelete
  54. Thanks for your code but i want another one.. When we search what ever we want its showing empty i want to display like no data available onthis

    ReplyDelete
    Replies
    1. Improved version: https://github.com/niksoft3ng/html-table-search-js

      Delete
  55. Thank you Nikhil for the coding you have gave.. it works!!! i am happy now..

    ReplyDelete