Add a filter (search box) to a table.
This function will turn one column of a table into a filter for another column. In this example my table is named "P1_Trade_Table",the search column is called "TradeSearch" and the dropdown to search is called "Trade".
//Global Vars
var elementSelected_XYZ;
var listbak;
var listenerSearchAdd;
var globaltb;
/**
* Filters a dropdown list based on a search string pattern.
* @param pattern: a string of zero or more characters by
* which to filter the list
* @param list: reference to a form object of type 'select'
*/
function filter(pattern, se) {
//search by regular expression, case-insensitive, from
//the beginning of the string
list = $(se);
bakPattern = pattern;
pattern = '' + pattern;
pattern = new RegExp(pattern,'i');
// if the dropdown list passed in hasn't already been
// backed up, do that now
if (!listbak){
// Attach an array to the select object that is a
// backup of the original dropdown list
var options = list.getElementsByTagName('option');
listbak = $A(options);
}
if (bakPattern ==''){
// Replace the dropdown list with the list of matches.
var listDelArray = $A(list.getElementsByTagName('option'));
listDelArray.each(function(node){
Element.remove(node);
});
listbak.each(function(node) {
Element.insert(list, node);
});
}
else
{
// Iterate through the backed up dropdown list and create
// a list of matches.
var matchOptions = listbak.findAll( function(node){
return pattern.test(node.value);
});
// Replace the dropdown list with the list of matches.
//var listDelArray = $(list.getElementsByTagName('option'));
//listDelArray.each(function(node){
// Element.remove(node);
//});
list.options.length=0;
matchOptions.each(function(node) {
Element.insert(list, node);
});
}
//Select the first item so the new options are apparent
list.selectedIndex=0;
}
There is a small problem with this at the moment where multiple entries in a table alter other rows but this will be sorted out shortly and the fix posted here. If anyone else has any idea what is causing this I would love to hear.
Cheers.
Mark
-
Revised code below. Now allows searches for any number of rows in a table in any order without interference with other rows. Now working on revised code which will allow the functions to apply automatically to any fields within a question set which contain specific id's. This will make maintenance a lot easier.
If anyone has other ideas on what they would like included in this function please let me know and I'll see what I can do.
Cheers.
Mark.
//Global Vars
var elementSelected_XYZ;
var listbak;
var listenerSearchAdd;
var globaltb;var listbakarray=new Array();
/**
* Filters a dropdown list based on a search string pattern.
* @param pattern: a string of zero or more characters by
* which to filter the list
* @param list: reference to a form object of type 'select'
*/
function filter(pattern, se) {//check for a row count
var listindex = 0;
var splitResult = se.split("_");
if(splitResult.length >1) {
if(!isNaN(splitResult[splitResult.length-1])){
listindex = parseInt(splitResult[splitResult.length-1]);
}
}//search by regular expression, case-insensitive, from
//the beginning of the string
list = $(se);
bakPattern = pattern;
pattern = '' + pattern;
pattern = new RegExp(pattern,'i');
// if the dropdown list passed in hasn't already been
// backed up, do that now
if (!listbakarray[listindex] ){
// Attach an array to the select object that is a
// backup of the original dropdown list
var options = list.getElementsByTagName('option');
listbakarray[listindex] = $A(options);
}if (bakPattern ==''){
// Replace the dropdown list with the list of matches.
var listDelArray = $A(list.getElementsByTagName('option'));
listDelArray.each(function(node){
Element.remove(node);
});listbakarray[listindex].each(function(node) {
Element.insert(list, node);
});
}
else
{
// Iterate through the backed up dropdown list and create
// a list of matches.
var matchOptions = listbakarray[listindex].findAll( function(node){
return pattern.test(node.value);
});
list.options.length=0;
matchOptions.each(function(node) {
Element.insert(list, node);
});
}
//Select the first item so the new options are apparent
list.selectedIndex=0;
}function addTradeSearch(tb){
var tr;
var td;
var inp;
var sel;
var element;
var counter = 0;
var addclick;
if(!listenerSearchAdd)
{
globaltb = tb;
document.addEventListener ('DOMNodeInserted', whatAdded, false);
listenerSearchAdd = true;
}td = tb.getElementsByTagName('td');
inp = tb.getElementsByTagName('input');
tr = tb.getElementsByTagName('tr');;for(i = 0; i < inp.length; i++){
inp[i].value = '';
if(! inp[i].onclick){
sel = inp[i].parentNode.parentNode.getElementsByTagName('select');
sel[0].id = sel[0].id + '_' + i;
if(sel){
var addclick = 'elementSelected_XYZ = "' + sel[0].id +'";';
inp[i].setAttribute('onclick', addclick )addclick = 'filter(this.value,elementSelected_XYZ);';
inp[i].setAttribute('onkeyup', addclick )
}
}
}
}
function whatAdded() {
var x= $(event.target);
if (x.getElementsByTagName) {
var y= x.getElementsByTagName('input')
if(!y){return;}
if(y.length == 0){return;}
if(y[0].id)
{
if (y[0].id.indexOf("Trade_Table_TradeSearch") >-1){
addTradeSearch(globaltb);
}
}
}
}
Please sign in to leave a comment.
Comments
2 comments