Incremental search using JavaScript
Aside from this blog, I am also the webmaster (and one of the contributors) on two photo blogs(one in English, the other in Dutch). I wrote the software for maintaining these photo blogs myself, because nothing at the time seemed to do exactly what I wanted. The upside of writing your own software is that it does exactly what I want. The downside is that if I want any new feature, I have to write it myself.
This weekend I added a simple incremental search feature to the administrative interface of the photo blogs. Nothing fancy, but just an easy way for the contributors to check for example when the last post on diaper cakes was or when we had the theme week on chocolate.
My solution is completely client-side using this JavaScript:
var TEXT_NODE = 3;
var TIMER;
var SKIP_ROW_COUNT = 2;
var SEARCH_INPUT;
function instrument(input, skipRows) {
SEARCH_INPUT = input;
if (skipRows) {
SKIP_ROW_COUNT = skipRows;
}
// listen to changes to the input
input.onkeyup = input.onchange = startTimer;
}
function startTimer() {
// start (or re-start) the timer, only once it expires will we start the search
if (TIMER) {
clearTimeout(TIMER);
}
TIMER = setTimeout("search()", 500);
}
function search() {
var term = SEARCH_INPUT.value.toLowerCase();
var rows = document.getElementsByTagName("tr");
// skip first few rows (optional author book, commands and header)
var i;
for (i = SKIP_ROW_COUNT; i < rows.length; i++) {
var tr = rows[i];
// hide row if it doesn't contain the search term
tr.style.display = (term == "" || doesNodeContain(tr, term)) ? "" : "none";
}
}
function doesNodeContain(node, term) {
if (node.nodeType == TEXT_NODE && node.nodeValue.toLowerCase().indexOf(term) >= 0) return true;
return true;
}
var child = node.firstChild;
while (child) {
if (doesNodeContain(child, term)) {
return true;
}
child = child.nextSibling;
}
return false;
}
You hook this up in the HTML using:
<input onfocus="instrument(this, 2)" type="text">
I know that putting inline JavaScript in the HTML is not very Web 2.0 and makes the site inaccessible. But since this is the administrative interface for the contributors and not the front end of the website, I think I can live with myself for not making it accessible.
3 comments:
Hi Frank:
(Hope you're still around)
I'm using your Incremental Search js code, but can't make it work with IE7 (altho it works with FF and Chrome).
Also, I wish to search thru the 2nd column of text (rather than *each* column)
Can you help ?
I'm at syntel@cox.net
Thanks,
-Mel Smith (an old guy)
Hey Mel,
limiting the columns search can be done by modifying the doesNodeContainFunction. It'll have to cater for the various tag names you might encounter, like "td", "th", etc.
If you can point me to a sample page that you want to search, I'll see what I can do.
Frank
Hi Mel,
Just change the search function to the one below:
function search() {
var shomsg = document.getElementById("ishomsg") ;
//shomsg.style.color="red" ;
//shomsh.style.background="white" ;
var term = SEARCH_INPUT.value.toLowerCase();
var rows = document.getElementsByTagName("tr");
// skip first few rows
for (var i = SKIP_ROW_COUNT; i < rows.length; i++) {
var tr = rows[i]; // hide row if it doesn't contain the search term
var tds = tr.getElementsByTagName("td");
if (!tds || tds.length < 2) continue;
var td = tds[1];
tr.style.display = (term == "" || doesNodeContain(td, term)) ? "" : "none";
}
//alert("finished loop") ;
//shomsg.style.color = "#80ff80"
//shomsg.style.background = "#80ff80"
//alert("finished searching") ;
Let me know if it works for you.
Frank
Post a Comment