:: Forum >> Version 1 >>

Searchable Grid

Hi,
I have put togather a code which searches the grid for a keyword in a particular column. But need a lot of improvement.
Note: Please make necessary changes in the includes of css and .js to make it work
Regards,
Nilesh Manohar
Code :
<html>
<
head>
    <
title>ActiveWidgets Grid widget</title>
    <
stylebodyhtml {margin:0pxpadding0pxoverflowhidden;} </style>

    <!-- 
ActiveWidgets stylesheet and scripts -->
    <
link href="activeui.css" rel="stylesheet" type="text/css" ></link>
    <
script src="activeui.js"></script>

    <!-- 
grid format -->
    <
style>
        .
active-controls-grid {height100%; fontmenu;}

        .
active-column-{width:  80px;}
        .
active-column-{width200px;}
        .
active-column-{text-alignright;}
        .
active-column-{text-alignright;}
        .
active-column-{text-alignright;}

        .
active-grid-column {border-right1px solid threedshadow;}
        .
active-grid-row {border-bottom1px solid threedlightshadow;background-colorwhite;}
    </
style>
    <
script>
        var 
obj = new Active.Controls.Grid;
        var 
myData = [
            [
"MSFT","Microsoft Corporation""Windows"],
            [
"REDH","Red Hat Linux""Linux"],
            [
"Suse","Suse Linux""Linux"],
            [
"IBM","IBM Ltd.""Websphere"],
            [
"BEA","BEA Systems""Weblogic"],
            [
"APAC","Apache Org""Tomcat"],
            [
"MSFT","Microsoft Corporation""Windows"],
            [
"REDH","Red Hat Linux""Linux"],
            [
"Suse","Suse Linux""Linux"],
            [
"IBM","IBM Ltd.""Websphere"],
            [
"BEA","BEA Systems""Weblogic"],
            [
"APAC","Apache Org""Tomcat"],
            [
"MSFT","Microsoft Corporation""Windows"],
            [
"REDH","Red Hat Linux""Linux"],
            [
"Suse","Suse Linux""Linux"],
            [
"IBM","IBM Ltd.""Websphere"],
            [
"BEA","BEA Systems""Weblogic"],
            [
"APAC","Apache Org""Tomcat"],
            [
"MSFT","Microsoft Corporation""Windows"],
            [
"REDH","Red Hat Linux""Linux"],
            [
"Suse","Suse Linux""Linux"],
            [
"IBM","IBM Ltd.""Websphere"],
            [
"BEA","BEA Systems""Weblogic"],
            [
"APAC","Apache Org""Tomcat"],
            [
"MSFT","Microsoft Corporation""Windows"],
            [
"REDH","Red Hat Linux""Linux"],
            [
"Suse","Suse Linux""Linux"],
            [
"IBM","IBM Ltd.""Websphere"],
            [
"BEA","BEA Systems""Weblogic"],
            [
"APAC","Apache Org""Tomcat"],
            [
"MSFT","Microsoft Corporation""Windows"],
            [
"REDH","Red Hat Linux""Linux"],
            [
"Suse","Suse Linux""Linux"],
            [
"IBM","IBM Ltd.""Websphere"],
            [
"BEA","BEA Systems""Weblogic"],
            [
"APAC","Apache Org""Tomcat"],
            [
"MSFT","Microsoft Corporation""Windows"],
            [
"REDH","Red Hat Linux""Linux"],
            [
"Suse","Suse Linux""Linux"],
            [
"IBM","IBM Ltd.""Websphere"],
            [
"BEA","BEA Systems""Weblogic"],
            [
"APAC","Apache Org""Tomcat"],
            [
"MSFT","Microsoft Corporation""Windows"],
            [
"REDH","Red Hat Linux""Linux"],
            [
"Suse","Suse Linux""Linux"],
            [
"IBM","IBM Ltd.""Websphere"],
            [
"BEA","BEA Systems""Weblogic"],
            [
"APAC","Apache Org""Tomcat"]
            ];

        var 
myColumns = ["Ticker""Company Name""Products"];
            function 
drawGrid()
                    {
                        
obj.setRowCount(myData.length);
                        
obj.setColumnCount(myColumns.length);
                        
obj.setDataText(function(ij){return myData[i][j]});
                        
obj.setColumnText(function(i){return myColumns[i]});
                        
obj.setRowHeaderWidth("28px");
                        
obj.setColumnHeaderHeight("20px");
                        
obj.setProperty("selection/multiple"true);
                        
obj.setAction("click", function(src){window.status src.getProperty("item/text")});
                        
document.write(obj);
        }
        function 
populateListBox()
                {
                    for(var 
c=0c<myColumns.lengthc++)
                    {
                        
document.write("<option value="+c+">"+myColumns[c]+"</option>");
                    }
        }
        function 
searchGrid()
        {
            var 
colToBeSearched document.forms['gridSearchForm'].colSearchName.value;
            var 
toSearch document.forms['gridSearchForm'].keyword.value;
            var 
res 0;
            for(var 
x=0x<myData.lengthx++)
            {
                if((
myData[x][colToBeSearched].indexOf(toSearch)) >= 0)
                {
                    
obj.getTemplate("row"x).setStyle("color""white");
                    
obj.getTemplate("row"x).setStyle("background""blue");
                    
res++;
                }
                else
                {
                    
obj.getTemplate("row"x).setStyle("color""black");
                    
obj.getTemplate("row"x).setStyle("background""white");
                }
            }
            
document.getElementById('result').innerHTML "<b>Number of matches : "+res+"</b>";
        }
</
script>
</
head>
<
body>
<
table>
<
tr>
<
td>
<
form name=gridSearchForm id=gridSearchForm>
<
input type=text name=keyword>
<
select name=colSearchName>
<
script>
populateListBox();
</
script>
</
select><input type=button value=search onclick="javascript:searchGrid();">
</
form>
</
td>
</
tr>
<
tr>
<
td>
<
div id=result>
</
div>
<
tr>
<
td width=650 height=300>
    <
script>
    
drawGrid();
    </
script>
    </
td>
    </
tr>
    </
table>
</
body>
</
html>
 
Nilesh Manohar
Thursday, March 25, 2004
Cool! Many thanks for posting this example!
Alex (ActiveWidgets)
Sunday, March 28, 2004
Hi Alex,
I am also working on the paging of data. Hope I will be able to post that code soon as well.
Regards,
Nilesh Manohar
Nilesh Manohar
Monday, March 29, 2004
This example takes Nilesh's code a little further and sorts the table so that the items found in the search go to the top of the table. To do this, as well as changing the colors of the matching rows, it adds "<!--A--> to the cells that matched and "<!--x--> to those that did not. This allows it to sort but does not change the visable contents (because they are HTML comments). Sorry it is crude but I am a 'C' programmer and only just learning JavaScript.

<html>
<
head>
    <
title>ActiveWidgets Grid widget</title>
    <
stylebodyhtml {margin:0pxpadding0pxoverflowhidden;} </style>

    <!-- 
ActiveWidgets stylesheet and scripts -->
    <
link href="style/grid.css" rel="stylesheet" type="text/css" ></link>
    <
script src="lib/grid.js"></script>

   
    <!-- 
grid format -->
    <
style>
        .
active-controls-grid {height100%; fontmenu;}

        .
active-column-{width:  80px;}
        .
active-column-{width200px;}
        .
active-column-{text-alignright;}
        .
active-column-{text-alignright;}
        .
active-column-{text-alignright;}

        .
active-grid-column {border-right1px solid threedshadow;}
        .
active-grid-row {border-bottom1px solid threedlightshadow;background-colorwhite;}
    </
style>
    <
script>
        var 
obj = new Active.Controls.Grid;
        var 
myData = [
            [
"MSFT","Microsoft Corporation""Windows"],
            [
"REDH","Red Hat Linux""Linux"],
            [
"Suse","Suse Linux""Linux"],
            [
"IBM","IBM Ltd.""Websphere"],
            [
"BEA","BEA Systems""Weblogic"],
            [
"APAC","Apache Org""Tomcat"],
            [
"MSFT","Microsoft Corporation""Windows"],
            [
"REDH","Red Hat Linux""Linux"],
            [
"Suse","Suse Linux""Linux"],
            [
"IBM","IBM Ltd.""Websphere"],
            [
"BEA","BEA Systems""Weblogic"],
            [
"APAC","Apache Org""Tomcat"],
            [
"MSFT","Microsoft Corporation""Windows"],
            [
"REDH","Red Hat Linux""Linux"],
            [
"Suse","Suse Linux""Linux"],
            [
"IBM","IBM Ltd.""Websphere"],
            [
"BEA","BEA Systems""Weblogic"],
            [
"APAC","Apache Org""Tomcat"],
            [
"MSFT","Microsoft Corporation""Windows"],
            [
"REDH","Red Hat Linux""Linux"],
            [
"Suse","Suse Linux""Linux"],
            [
"IBM","IBM Ltd.""Websphere"],
            [
"BEA","BEA Systems""Weblogic"],
            [
"APAC","Apache Org""Tomcat"],
            [
"MSFT","Microsoft Corporation""Windows"],
            [
"REDH","Red Hat Linux""Linux"],
            [
"Suse","Suse Linux""Linux"],
            [
"IBM","IBM Ltd.""Websphere"],
            [
"BEA","BEA Systems""Weblogic"],
            [
"APAC","Apache Org""Tomcat"],
            [
"MSFT","Microsoft Corporation""Windows"],
            [
"REDH","Red Hat Linux""Linux"],
            [
"Suse","Suse Linux""Linux"],
            [
"IBM","IBM Ltd.""Websphere"],
            [
"BEA","BEA Systems""Weblogic"],
            [
"APAC","Apache Org""Tomcat"],
            [
"MSFT","Microsoft Corporation""Windows"],
            [
"REDH","Red Hat Linux""Linux"],
            [
"Suse","Suse Linux""Linux"],
            [
"IBM","IBM Ltd.""Websphere"],
            [
"BEA","BEA Systems""Weblogic"],
            [
"APAC","Apache Org""Tomcat"],
            [
"MSFT","Microsoft Corporation""Windows"],
            [
"REDH","Red Hat Linux""Linux"],
            [
"Suse","Suse Linux""Linux"],
            [
"IBM","IBM Ltd.""Websphere"],
            [
"BEA","BEA Systems""Weblogic"],
            [
"APAC","Apache Org""Tomcat"]
            ];

        var 
myColumns = ["Patient""Accession""File name"];
            function 
drawGrid()
                    {
                           
                        
obj.setRowCount(myData.length);
                        
obj.setColumnCount(myColumns.length);
                        
obj.setDataText(function(ij){return myData[i][j]});
                        
obj.setColumnText(function(i){return myColumns[i]});
                        
obj.setRowHeaderWidth("28px");
                        
obj.setColumnHeaderHeight("20px");
                        
obj.setProperty("selection/multiple"true);
                        
obj.setAction("click", function(src){window.status src.getProperty("item/text")});
                        
document.write(obj);
        }
        function 
populateListBox()
                {
                    for(var 
c=0c<myColumns.lengthc++)
                    {
                        
document.write("<option value="+c+">"+myColumns[c]+"</option>");
                    }
        }
        function 
searchGrid()
        {
            var 
colToBeSearched document.forms['gridSearchForm'].colSearchName.value;
            var 
toSearch document.forms['gridSearchForm'].keyword.value;
            var 
res 0;
           
            
// scan through the table and add an HTML comment "A" to the lines that match
            // and a "X" to the lines that do not
            
for(var x=0x<myData.lengthx++)
            {
                if((
myData[x][colToBeSearched].indexOf(toSearch)) >= 0)
                {
                    
myData[x][colToBeSearched] = "<!--A-->"+myData[x][colToBeSearched];
                    
res++;
                }
                else
                {
                    
myData[x][colToBeSearched] = "<!--x-->"+myData[x][colToBeSearched];
                }
            }
            
            
// re-srt the table so the rows with the "A" comment float to the top
            
obj.sort(colToBeSearched"ascending");
            
obj.refresh();
            
            
// now scan through the table again, changing the colors of the rows we marked
            // as matching the sort criteria
            
for(var x=0x<myData.lengthx++)
            {
                if((
myData[x][colToBeSearched].indexOf("<!--A-->")) >= 0)
                {
                    
obj.getTemplate("row"x).setStyle("color""white");
                    
obj.getTemplate("row"x).setStyle("background""blue");
                    
myData[x][colToBeSearched] = "<!--A-->"+myData[x][colToBeSearched];
                    
res++;
                }
                else
                {
                    
obj.getTemplate("row"x).setStyle("color""black");
                    
obj.getTemplate("row"x).setStyle("background""white");
                    
myData[x][colToBeSearched] = "<!--x-->"+myData[x][colToBeSearched];
                }
            }
            
document.getElementById('result').innerHTML "<b>Number of matches : "+res+"</b>";
        }
</
script>
</
head>
<
body>
<
table>
<
tr>
<
td>
<
form name=gridSearchForm id=gridSearchForm>
<
input type=text name=keyword>
<
select name=colSearchName>
<
script>
populateListBox();
</
script>
</
select><input type=button value=search onclick="javascript:searchGrid();">
</
form>
</
td>
</
tr>
<
tr>
<
td>
<
div id=result>
</
div>
<
tr>
<
td width=650 height=300>
    <
script>
    
drawGrid();  
    </
script>
    </
td>
    </
tr>
    </
table>
</
body>
</
html
 
Steve Beaver
Wednesday, February 16, 2005
That is a great idea Steve, well done
AcidRaZor
Thursday, February 17, 2005
I have found that pressing the Enter key after entering data in the search box causes the page to reload immediately after the search has been performed causing the search results to be lost.

I have tried a umber of remedies for this but without success.

<input type=text name=keyword onchange="javascript:searchGrid();">

seemed like a good idea but did not change the behavior.

Any ideas?
Steve Beaver
Thursday, February 17, 2005

Guess that input is inside some form, if yes then adding onsubmit="return false" will make you happy :-) do similar work-around if no form.

Cheers,
Sudhaker Raj
http://theJ2EE.com
Sudhaker Raj
Thursday, February 17, 2005
Thank you. That causes it to take no action when the Enter key is pressed which effectively makes the user use the proper button!

I have made a couple of other refinements to the code. If you make a second search right after the first one, you must remove the HTML comments that were poked into the data before adding new ones. I also found that the library does not sort a table if it was already sorted this way. A work around is add obj.sort(colToBeSearched, "decending"); before the line obj.sort(colToBeSearched, "ascending"); above.

I'll post the finished example if anyone wants it.
Steve Beaver
Thursday, February 17, 2005
In Steve's example, the two loops end up adding stacks of <--x--><--x--><--A--> strings in the underlying values for the selected column.

The following modified loop removes these strings after the table has been sorted, during the process of colouring rows. This helps when retrieving values to carry forward.

for(var x=0x<myData.lengthx++) {
  var 
str myData[x][colToBeSearched];
  if((
str.indexOf("<!--A-->")) >= 0) { 
    
obj.getTemplate("row"x).setStyle("color""white"); 
    
obj.getTemplate("row"x).setStyle("background""blue"); 
    
myData[x][colToBeSearched] = str.substr(8,20); 
    
res++; 
  } else {
    
obj.getTemplate("row"x).setStyle("color""black"); 
    
obj.getTemplate("row"x).setStyle("background""white");
    
myData[x][colToBeSearched] = str.substr(8,20); 
  } 
}
 
Christian (siliconbrits)
Sunday, February 27, 2005
Hmmm...

I have some wierd behaviour using this method that I can't figure out.

This behaviour occurs when I am using the Steve Beavers codebase, with or without the modified function I last posted.

The problem is that sometimes fields do not move to the top of the table. Try it with the following code/data and do a search for the string "02-26" on Date. Try it as the first search, or another search later, its entirely reproducable, and having reviewed the code, I dont think it is Steve's Algorithm - it may be something deeper in the AW code. (but then, its late, I'm tired.....)

Anyway, try it out and let me know what you think. I've added a function resetGrid(), which solves a bunch of other issues, but apart from that there's no real code modifications.

function resetGrid() {
    
obj.sort(0"ascending"); 
    
obj.refresh();
    
obj.setSelectionProperty("values", []);
    for(var 
x=0x<myData.lengthx++) {
        
obj.getTemplate("row"x).setStyle("color""white"); 
        
obj.getTemplate("row"x).setStyle("background""blue"); 
    }      
}
 
Note: There's still a bunch of formatting stuff in this code, but I dont have the time to strip it down further, and make sure it will work it you cut&paste, so please accept my apologies for the lengthy post.

Here's the code:

<html
<
head
<
title>ActiveWidgets Grid widget</title>
<
style
   
table,tr,td{border-bottom1px solid threedlightshadow;background:#ebeadb;font-size9pt;}
   :
hover input {background#fcfdffborder-color#fcc247}
   
body {overflowhidden;background:#EEEEEE;color:#000066;padding:20px;font-family:Helvetica;font-size:9pt;}
</
style

<!-- 
ActiveWidgets stylesheet and scripts --> 

<
link href="script/ActiveWidgets/runtime/styles/xp/grid.css" rel="stylesheet" type="text/css" ></link>
<
script src="script/ActiveWidgets/runtime/lib/grid.js"></script>

<!-- 
grid format --> 
<
style
   .
active-controls-grid {height100%; fontmenu;} 
   .
active-column-{width120pxtext-aligncenter;} 
   .
active-column-{width60pxtext-aligncenter;} 
   .
active-column-{width120pxtext-alignleft;} 
   .
active-column-{width60px;text-aligncenter;} 
   .
active-column-{width80px;text-alignright;} 
   .
active-column-{width80px;text-alignright;}    
   .
active-grid-column {test-alignleft;border-right1px solid threedshadow;} 
   .
active-grid-row {border-bottom1px solid threedlightshadowbackground-colorwhite;}
</
style

<
script
var 
obj = new Active.Controls.Grid;

var 
myData = [
[
"2005-02-25 04:31:04","WT-00-01","Willmotts","FR0001","10000.00","10000.00"],
[
"2005-02-25 04:31:34","WT-00-02","Parkinson Farms","FR0002","10000.00","9800.00"],
[
"2005-02-25 04:31:50","WT-00-03","Dibble & Scrubbit","FR0003","3000.00","3500.00"],
[
"2005-02-25 04:32:30","WT-00-04","Shovel and Diggitt","FR0004","4000.00","3000.00"],
[
"2005-02-25 04:32:57","WT-00-05","Not Set","FR0001","10000.00","10000.00"],
[
"2005-02-25 04:34:25","WT-00-06","Not Set","FR0002","6200.00","6000.00"],
[
"2005-02-26 09:15:54","WT-00-07","Not Set","FR0003","3000.00","2000.00"],
[
"2005-02-26 09:16:13","WT-00-08","Not Set","FR0001","3000.00","2000.00"],
[
"2005-02-27 03:30:01","WT-00-09","Not Set","FR0003","9000.00","2000.00"],
[
"2005-02-27 03:30:29","WT-88-78","Not Set","FR0001","789.00","567.00"],
[
"2005-02-27 03:30:48","WT-00-10","Stepsons","FR0005","10000.00","9000.00"],
[
"2005-02-27 03:31:12","WT-00-11","Stepsons","FR0005","5678.00","4564.00"],
[
"2005-02-27 03:31:32","WT-00-12","Stepsons","FR0006","12990.00","11922.98"],
[
"2005-02-27 03:32:05","WT-00-13","Not Set","FR0001","6578.00","4568.00"],
[
"2005-02-27 03:32:27","WT-00-14","Stepsons","FR0005","4568.00","3465.67"]];

var 
myColumns = ["Date","Ticket","Grower","Field""Loaded KG""Washed KG"];    

/**
 * Extract the value of column 'ticket' from the current selected row
 * to a form field
 *
 */
function setTicket (src) {
   var 
index=src.getProperty("item/index");
   
document.ticketSelector.ticket.value=myData[index]['1'];
}

/**
 * Reset the Grid object to its initial state, including selects and colours.
 */
function resetGrid() {
    
obj.sort(0"ascending"); 
    
obj.refresh();
    
obj.setSelectionProperty("values", []);
    for(var 
x=0x<myData.lengthx++) {
        
obj.getTemplate("row"x).setStyle("color""white"); 
        
obj.getTemplate("row"x).setStyle("background""blue"); 
    }      
}
    
function 
drawGrid() { 
    var 
row = new Active.Templates.Row;
    
row.setEvent("ondblclick", function(){this.action("myAction")});
    
obj.setTemplate("row"row);
    
obj.setAction("myAction"setTicket);
    
obj.setRowCount(myData.length); 
    
obj.setColumnCount(myColumns.length);     
    
obj.setDataText(function(ij){return myData[i][j]}); 
    
obj.setColumnText(function(i){return myColumns[i]}); 
    
obj.setRowHeaderWidth("28px"); 
    
obj.setColumnHeaderHeight("20px"); 
    
obj.setProperty("selection/multiple"true); 
    
obj.setAction("click", function(src){window.status src.getProperty("item/text")}); 
    
document.write(obj); 

   
function 
populateListBox() { 
    for(var 
c=0c<myColumns.lengthc++) { 
        
document.write("<option value="+c+">"+myColumns[c]+"</option>"); 
    } 

    
function 
searchGrid() {
    var 
colToBeSearched document.forms['gridSearchForm'].colSearchName.value;         
    var 
toSearch document.forms['gridSearchForm'].keyword.value
        
    
resetGrid();        
    var 
res 0
    
    for(var 
x=0x<myData.lengthx++) { 
      if((
myData[x][colToBeSearched].indexOf(toSearch)) >= 0) { 
    
myData[x][colToBeSearched] = "<!--A-->"+myData[x][colToBeSearched]; 
    
res++; 
      } else  { 
          
myData[x][colToBeSearched] = "<!--x-->"+