Search A Table With JavaScript

Tuesday, March 10, 2009 - 11:33

Using server side scripts to search for things can be as complex or as simple as the situation requires. However, if you have a table of results and you just want to enable a simple JavaScript search on that table then this might be the script for you.

To search a table using JavaScript you need to split the table into bits, this can be done using the getElementsByTagName() function, which takes the name of the element that you want to capture. So to grab all of the rows of a table as an array you need to pass the value of tr.

var rows = document.getElementsByTagName("tr");

We can then iterate through these rows, grabbing the column that you want to search on, with the following code.

1
2
3
4
for ( var i = 0; i < rows.length; i++ ) {
  var fullname = rows[i].getElementsByTagName("td");
  fullname = fullname[0].innerHTML.toLowerCase();
}

Before we can go any further we need a form so that the user can enter information and a table that can be used to search. First the form, the action of the input box will cause a function called doSearch() to be run, this will contain our search code.

1
2
3
<form action="#" method="get" onsubmit="return false;">
<input type="text" size="30" name="q" id="q" value="" onkeyup="doSearch();" />
</form>

Next, the table. Note that I have added an additional row to the end of this table. This will be used to display a note to the user if they have entered a query that isn't found.

1
2
3
4
5
6
7
8
9
10
11
12
13
<table>
<tr><td>One</td></tr>
<tr><td>Two</td></tr>
<tr><td>Three</td></tr>
<tr><td>Four</td></tr>
<tr><td>Five</td></tr>
<tr><td>Six</td></tr>
<tr><td>Seven</td></tr>
<tr><td>Eight</td></tr>
<tr style="display:none;" id="noresults"> 
 <td>(no listings that start with "<span id="qt"></span>")</td> 
</tr>
</table>

The first thing we need to do in our search function is to prepare the search term. This turns the query string to lowercase, which we can then match to the table column.

1
2
var q = document.getElementById("q");
var v = q.value.toLowerCase();

Now we can go through each row value and try to match it to the value in the query string. If it matches then we display the row, if not then we hide it.

1
2
3
4
5
6
7
8
9
10
11
  for ( var i = 0; i < rows.length; i++ ) {
    var fullname = rows[i].getElementsByTagName("td");
    fullname = fullname[0].innerHTML.toLowerCase();
    if ( fullname ) {
        if ( v.length == 0 || (v.length < 3 && fullname.indexOf(v) == 0) || (v.length >= 3 && fullname.indexOf(v) > -1 ) ) {
        rows[i].style.display = "";
      } else {
        rows[i].style.display = "none";
      }
    }
  }

Here is the full function, including the code to implement the no results note.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<script type="text/javascript">
//<!--
function doSearch() {
  var q = document.getElementById("q");
  var v = q.value.toLowerCase();
  var rows = document.getElementsByTagName("tr");
  var on = 0;
  for ( var i = 0; i < rows.length; i++ ) {
    var fullname = rows[i].getElementsByTagName("td");
    fullname = fullname[0].innerHTML.toLowerCase();
    if ( fullname ) {
        if ( v.length == 0 || (v.length < 3 && fullname.indexOf(v) == 0) || (v.length >= 3 && fullname.indexOf(v) > -1 ) ) {
        rows[i].style.display = "";
        on++;
      } else {
        rows[i].style.display = "none";
      }
    }
  }
  var n = document.getElementById("noresults");
  if ( on == 0 && n ) {
    n.style.display = "";
    document.getElementById("qt").innerHTML = q.value;
  } else {
    n.style.display = "none";
  }
}
//-->
</script>

Here is a working example of the code, with valid HTML.

Category: 
philipnorton42's picture

Philip Norton

Phil is the founder and administrator of #! code and is an IT professional working in the North West of the UK.
Google+ | Twitter

Comments

philipnorton42's picture
Submitted by philipnorton42 on Fri, 04/17/2009 - 08:52

Sure, doing that is quite easy, and doesn't require much change. Just after the for loop that searches each column add the following code: rows[0].style.display = &quot;&quot;; This will force the first row of the table to be displayed.
Is there a way to exclude certain rows. What If I had a header row above "One, Two, Three" that was called "Category". Can I exclude that and have it always appear?

I just improve slightly of the code

The function doSearch will require two parameter which is tableId and queryId

1
2
3
4
5
6
7
   function doSearch( tableId, queryId) {
       var q       = document.getElementById(queryId);
       var v       = q.value.toLowerCase();
 
       var t       = document.getElementById(tableId);
       var rows    = t.getElementsByTagName("tr");
       var on      = 0;

...rest will be the same

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
<?php
                                      
                        
//initialize the session
if (!isset($_SESSION)) {
  session_start();
}
 
// ** Logout the current user. **
$logoutAction = $_SERVER['PHP_SELF']."?doLogout=true";
if ((isset($_SERVER['QUERY_STRING'])) && ($_SERVER['QUERY_STRING'] != "")){
  $logoutAction .="&". htmlentities($_SERVER['QUERY_STRING']);
}
 
if ((isset($_GET['doLogout'])) &&($_GET['doLogout']=="true")){
  //to fully log out a visitor we need to clear the session varialbles
  $_SESSION['MM_Username'] = NULL;
  $_SESSION['MM_UserGroup'] = NULL;
  $_SESSION['PrevUrl'] = NULL;
  unset($_SESSION['MM_Username']);
  unset($_SESSION['MM_UserGroup']);
  unset($_SESSION['PrevUrl']);
        
  $logoutGoTo = "logout.php";
  if ($logoutGoTo) {
    header("Location: $logoutGoTo");
    exit;
  }
}
?>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>directoryTable</title>
<link rel="stylesheet" href="style.css" />
<style type="text/css">
#thead {
        color: #BBC2C6;
}
</style>
 
<script type='text/javascript'>
var $rows = $('#table tr');
 
function doSearch() {
    var q = document.getElementById("q");
    var v = q.value.toLowerCase();
    var rows = document.getElementsByTagName("tr");
    var on = 0;
    for ( var i = 0; i < rows.length; i++ ) {
        var fullname = rows[i].getElementsByTagName("td");
        fullname = fullname[0].innerHTML.toLowerCase();
        if ( fullname ) {
            if ( v.length == 0 || (v.length < 3 && fullname.indexOf(v) == 0) || (v.length >= 3 && fullname.indexOf(v) > -1 ) ) {
                rows[i].style.display = "";
                on++;
            } else {
                rows[i].style.display = "none";
            }
        }
    }
    var n = document.getElementById("noresults");
    if ( on == 0 && n ) {
        n.style.display = "";
        document.getElementById("qt").innerHTML = q.value;
    } else {
        n.style.display = "none";
    }
}
</script>
</head>
<body>
 
<div align="justify">
<div align="right"><a href="<?php echo $logoutAction ?>"> Log out</a>
</div>
<div id="container">
</div>
<div id="header">
 
  <h1> <a href="http://www.skylinerestoration.com/"><img src="http://www.skylinerestoration.com/Skyline_Restoration/home_files/shapeimage_15.png" alt=""/></a> </h1>
  <h2>&nbsp;</h2>
  <h2><span style="font-weight: normal;">11-20 37th Avenue, Long Island City, NY 11101</span></h2>
        <h2 style="font-weight: normal;"><span style="font-weight: bold;">T</span>:  &nbsp; <span style="font-weight: bold;">F</span>:
          </h2>
          
</div>
 
<form action="#" method="get" onsubmit="return false;">
<input type="text" size="30" name="q" id="q" value="" onkeyup="doSearch();" />
</form></br>
 
        <table cellpadding="0" cellspacing="0" border="0" id="table" class="sortable">
                <thead>
                        <tr>
                                <th width="46"><h3>ID</h3></th>
                          <th width="185" class="nosort"><h3>Name</h3></th>
                                <th width="58"  class="nosort"><h3>Ext.</h3></th>
                                <th width="142" class="nosort"><h3>Phone</h3></th>
                                <th width="281" class="nosort"><h3>Email</h3></th>
                        </tr>
                </thead>
    
          <tbody id="data">
                        <tr>
                                <td>1</td>
                                <td><strong></strong></td>
                                <td><strong></strong></td>
                                <td></td>
                                <td></td>
                        </tr>
                        <tr>
                                <td>2</td>
                                <td><strong></strong></td>
                                <td></strong></td>
                                <td></td>
                                <td></td>
 
                  </tr>
                </tbody>
  </table>
<thead>
<table height="62" border="0" cellpadding="0" cellspacing="0" class="sortable" id="table">
  <tr>
            <td width="321"><div align="center">
              <h3><strong>IT Support</strong></h3>
            </div></td>
            <td width="273"><h3 align="center"><strong>24/7 Emergency Helpline: </strong></h3>
        <h3 align="center"><strong></strong></h3></td>
            <td width="385"><h3></h3></td>
  </tr>
      </table>
     </thead>           
     
     <div id="controls">
                <div id="perpage">
                        <select onchange="sorter.size(this.value)">
                        <option value="5">5</option>
                                <option value="10" selected="selected">10</option>
                                <option value="20">20</option>
                                <option value="50">50</option>
                                <option value="100">100</option>
                        </select>
                        <span>Entries Per Page</span>
          </div>
                <div id="navigation">
                        <img src="images/first.gif" width="16" height="16" alt="First Page" onclick="sorter.move(-1,true)" />
                        <img src="images/previous.gif" width="16" height="16" alt="First Page" onclick="sorter.move(-1)" />
                        <img src="images/next.gif" width="16" height="16" alt="First Page" onclick="sorter.move(1)" />
                        <img src="images/last.gif" width="16" height="16" alt="Last Page" onclick="sorter.move(1,true)" />
                </div>
                <div id="text">Displaying Page <span id="currentpage"></span> of <span id="pagelimit"></span></div>
        
</div>
<!-- <script type="text/javascript" src="_script.js"></script>
<script type="text/javascript">
  var sorter = new directory.table.sorter("sorter");
        sorter.head = "head";
        sorter.asc = "asc";
        sorter.desc = "desc";
        sorter.even = "evenrow";
        sorter.odd = "oddrow";
        sorter.evensel = "evenselected";
        sorter.oddsel = "oddselected";
        sorter.paginate = true;
        sorter.currentid = "currentpage";
        sorter.limitid = "pagelimit";
        sorter.init("table",1);
  </script>-->
  
 
<div id="footer"><a href="" target="_blank"><img src="images/footer.png" alt="" width="983" height="209" onclick="" /></a> </div>  
</body>
</html>

in the example, when i type "a,s,d" quickly, the (no listings that start with "asd") dissapears and the table becomes empty. why does this happen and how do i fix this?

philipnorton42's picture
Submitted by philipnorton42 on Fri, 01/18/2013 - 10:04

The code is designed to hide anything that doesn't match the required criteria. So if you enter a term that it's in the table the table will be hidden.

Hi ... Is there a way to search only coloum 2?
It search in coloum 1 and i need coloum 2.

Thanks

Hi @ philipnorton42 the above code implements search only for the First element of the ROW if the row has more than one column it does not search the other values

Add new comment