Sunday, October 09, 2005

Tabbed Search (JavaScript)

If you look at Google or other popular search engines, you notice that they use tabs to indicate what you are searching. What they do not do though, is change the forms action without going to a new page. With this script and accompanying CSS, it changes the parent forms action page and sets focus on a tab. The pages are contained in an unordered list that is then formatted to look like tabs.

Uses W3C DOM level 1 methods and properties, so should work in any complaint browser. Tested and works in IE5+, Firefox 1.0 and Opera 8.50. If JavaScript is disabled, it simply goes to the page linked to.

The script: tabbedsearch.js

// http://simon.incutio.com/archive/2004/05/26/addLoadEvent
function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      oldonload();
      func();
    }
  }
}
// this sets up the forms for search
// tested and works in IE 5+, Firefox 1.0+, Opera 8.50
function setupForms(method) {
 // get all forms and loop through them
 var forms = document.getElementsByTagName("form");
 for(i=0; i<forms.length;i++) {
  if(forms[i].id == "") {
   forms[i].id = "form" + i;
  }
  var formid = forms[i].id;
  // get list
  var list = forms[i].getElementsByTagName("ul");
  // loop through items in list
  for(j=0; j<list.length;j++) {
   //alert(list[j].className);
   if(list[j].className == "formpages") {
    var items = list[j].getElementsByTagName("li");
    for(k=0; k<items.length;k++) {
     if (items[k].getElementsByTagName("a")[0]) {
      var link = items[k].getElementsByTagName("a")[0];
      if(link.id == "") {
       link.id = formid + "Link" + k;
      }
      // this stores the links to the search
      if(forms[i].searchlinkids) {
       forms[i].searchlinkids = forms[i].searchlinkids + "," + link.id;
      }
      else {
       forms[i].searchlinkids = link.id;
      }
      link.onclick = function() { 
       changeFormAction(formid, this.href, method);
       this.className = "active";
       return false;
      };
     }
    }
   }
  }
 }
}

function changeFormAction(form,action,method) {
 if(typeof(form) == 'string') {
  form = document.getElementById(form);
 }
 var f = form.searchlinkids.split(",");
 for (i=0; i<f.length; i++) {
  document.getElementById(f[i]).className = "";
 }
 // change action and method
 if(form.action) {
  form.action = action; 
 }
 if(form.method) {
  form.method = method;
 }
}

// use normal form method
addLoadEvent(setupForms);
// change method to 'get'
//addLoadEvent(function(){setupForms("get")});
// change method to 'post'
//addLoadEvent(function(){setupForms("post")});

The CSS: tabbedsearch.css

body {
  font: 0.8em Verdana;
}
ul.formpages {
  list-style-type: none;
  padding: 0;
  margin: 0;
  /* fix for IE 5 margin div bug */
  _display: inline;
}
ul.formpages li {
  float: left;
  display: inline;
  background-color: #C2DDFE;
  margin: 0 3px 0 0;
  border-top: 1px solid #000;
  border-right: 1px solid #000;
  border-left: 1px solid #000;
  /* fix for Opera margin div bug */
  position: relative;
  top: 1px;
}
ul.formpages a:link, ul.formpages a:visited {
  text-decoration: none;
  padding: 5px;
  color: #008;
  border-bottom: 1px solid #000;
  display: block;
}
ul.formpages a:hover {
  background: #009;
  color: #fff;
}
ul.formpages a.active:link, ul.formpages a.active:hover, ul.formpages a.active:visited {
  background: #eee;
  color: #000;
}
div.searchbox {
  background: #eee; 
  border: 1px solid #000;
  margin: 0px;
  padding: 12px;
  width: 300px;
  clear: both;
}

Demo page: tabbedsearch.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Tabbed Search</title>
<script type="text/javascript" src="tabbedsearch.js"></script>
<style type="text/css">
<!--
 @import url("tabbedsearch.css");
//-->
</style>
</head>
<body>
<form action="search1.aspx" method="post">
<p>Clicking on any of the below links will change the forms action.</p>
<ul class="formpages">
 <li><a href="search1.aspx" class="active">Search 1</a></li>
 <li><a href="search2.aspx">Search 2</a></li>
 <li><a href="search3.aspx">Search 3</a></li>
</ul>
<div class="searchbox">Search: <input type="text" name="keywords" />
<input type="submit" value="Search" />
</div>
</form>
<p>Content after</p>
</body>
</html>

Tags: , , ,

No comments: