Jul
08

Filtering a cfgrid as you type -revisited-

49 comments Posted by: Nahuel

Editable Grid
Some time ago I made a post where I showed how to filter a cfgrid by typing in a input field. I received a lot of comments requesting to do the same but using an editable cfgrid. The result in this code:

<cfsavecontent variable="actionInsert">
   GridData.insertRow(myGrid);
   _global.backupDP.push(myGrid.getItemAt(myGrid.length -1));
</cfsavecontent>
<cfsavecontent variable="actionDelete">
   var item = myGrid.selectedItem;
   if(_global.backupDP != undefined)
   {
      for(var i = 0; i < _global.backupDP.length; i++)
      {
         if(_global.backupDP[i] == item)
         {
            _global.backupDP.removeItemAt(i);
         }
      }
   }
   GridData.deleteRow(myGrid);
</cfsavecontent>
<cfsavecontent variable="actionFilter">
if(_global.backupDP == undefined)
   {
       _global.backupDP = myGrid.dataProvider.slice(0);
   }
   var backupDP = _global.backupDP;
   var fortext = forInput.text.toLowerCase();
   var selected = column.selectedItem.data;
   myGrid.dataProvider.removeAll();
   
   for(var i =0; i < backupDP.length;i++)
   {
      var item = backupDP[i];
      if(item[selected].toString().substr(0,fortext.length).toLowerCase() == fortext)
      {
         myGrid.dataProvider.addItem(item);
      }
   }
</cfsavecontent>
<cfform name="myForm" format="flash" width="400" height="370">
   <cfformgroup type="panel" label="Search our Members">
      <cfformgroup type="horizontal">
         <cfinput type="text" name="forInput" width="120" onchange="#actionFilter#" label="Filter by:">
            <cfselect name="column" label="in:" onchange="forInput.text=''" width="90">
               <option value="name">Name</option>
               <option value="gender">Gender</option>               
               <option value="age">Age</option>
            </cfselect>
      </cfformgroup>
      <cfgrid name= "myGrid" query="memberList" height="200" selectmode="edit" >
               <cfgridcolumn name="name" header="Name">
               <cfgridcolumn name="gender" header="Gender">
               <cfgridcolumn name="age" header="Age">
            </cfgrid>
   </cfformgroup>
   <cfformgroup type="horizontal">
      <cfinput type="submit" name="submit" value="Submit"/>
      <cfinput type="button" name="inser" value="Insert" onclick="#actionInsert#"/>
      <cfinput type="button" name="remove" value="Delete" onclick="#actionDelete# "/>
   </cfformgroup>
</cfform>

Live Example
Download the source

Related Posts
Filtering a grid as you type in a cfform
Filtering a list as you type in a ColFusion Flash Form

Category: CFForm | ColdFusion |

49 Comments so far

Write yours
Steven Ross
this line fails when there are spaces in items in your grid (also on a number):

if(item[selected].substr(0,fortext.length).toLowerCase() == fortext)

if you replace it with this it works:

if(_global.arrMembers == undefined) _global.arrMembers = FileGrid.dataProvider.slice(0);
    var arrMembers = _global.arrMembers;
    var arrDisplay:Array = [];
    var fortext = forInput.text;
    var selected = column.selectedItem.data;
   
    for(var i = 0; i &lt; arrMembers.length; i++)
    {
      
       if(selected == 'NumberColumn')
       {
          if(arrMembers[i][selected].toString().indexOf(fortext) != -1)
          {
             arrDisplay.push(arrMembers[i]);
          }
       }
       else{
      
          if(arrMembers[i][selected].toLowerCase().indexOf(fortext.toLowerCase()) != -1)
          {
             arrDisplay.push(arrMembers[i]);
          }
       }
      
    }
    FileGrid.dataProvider = arrDisplay;

Felipe
2. Felipe wrote on July 08, 2005 at 10:53 AM
How do I do to make it search in every part of the filed, not only in the first letter? As you did in the other post?
Steven Ross
change this line:

if(item[selected].substr(0,fortext.length).toLowerCase() == fortext)

to:

if(arrMembers[i][selected].toLowerCase().indexOf(fortext) != -1)
John Farrar
4. John Farrar wrote on July 20, 2005 at 9:55 AM
I also found this works to resolve issues with numbers. Just run the table through a Query of Queries...

CAST([year] AS VARCHAR) as years

That fixed the issue I was having and should work all around if you need the functionality.
dMan
5. dMan wrote on August 04, 2005 at 10:14 AM
How do you validate data in cfgrid, ie. dates, expressions etc.
Troy Montour
I'm using the filter grid so a person can search for a customer.
now I need to pass back what customer they clicked on so I can pass this back to the Database to find this customers Orders.

Is there a way to do this?
Michael White
I would like to maintain the Flash Form look and feel throughout my ColdFusion Application and give users some cool features too. I would like to use CFGRID to allow a user to preview report data (say a list of orders) and either Export the list to excel/plain text or jump the the record details edit page (if they have rights). to make a long story short, what's the easiest way to link to another form from a data grid?
mafdoc
8. mafdoc wrote on September 14, 2005 at 1:10 PM
Steve Ross - I am trying to filter on a number column. I used your code and it did work but it filtered on every column of my grid not just the selected &quot;in&quot; column. Would you let me know how to filter only on the &quot;in&quot; column.
I tried to adjust your code with the original code but when I enter a number to be filtered all my data disappears. Although, I can still filter on the other columns (which are listed in the &quot;in&quot; select list) The adjusted code:

&lt;cfsavecontent variable=&quot;actionFilter&quot;&gt;
   if(_global.arrMembers == undefined) _global.arrMembers = data.dataProvider.slice(0);
   var arrMembers = _global.arrMembers;
   var arrDisplay:Array = [];
   var fortext = forInput.text.toLowerCase();
   var selected = column.selectedItem.data;
   
   for(var i = 0; i &lt; arrMembers.length; i++)
{
if(selected == 'NumberColumn')
{
if(arrMembers[i][selected].toString().indexOf(fortext)!=-1)
   {arrDisplay.push(arrMembers[i]);
}
}
   else
   
{
if(arrMembers[i][selected].substr(0,fortext.length).toLowerCase() == fortext)
{
arrDisplay.push(arrMembers[i]);
}
}
}
   data.dataProvider = arrDisplay;
&lt;/cfsavecontent&gt;

I'll keep trying but I would appreciate any help.
mafdoc
9. mafdoc wrote on September 15, 2005 at 8:47 AM
I got the answer from Laura on the original posting of Filter as you type http://www.asfusion.com/blog/entry/filtering-a-list-as-you-type-cfform-flash.
added .toString() between the ...[selected] and .substr...
Thanks so much.
Gary Rennilson
10. Gary Rennilson wrote on September 21, 2005 at 2:29 PM
I am new to this and trying to get this filtering to work. I applied this code to my existing grid using my SQL data. The actionInsert and actionDelete works as provided, but when I try and apply any filter it removes all entries in the grid. Should this be filtering off the local data in the grid or does it need to be bound to my database somehow?
Laura
Gary,
perhaps you have the same problem described by mafdoc (when data contained numeric fields). I updated the source to contain the change.
Otherwise it should work as is.
Michael White
Flash forms are case sensitive so if you type a form control name in lower case and the actual control name is in mixed case it won't work
Gary Rennilson
13. Gary Rennilson wrote on September 21, 2005 at 4:04 PM
Laura, using the added .toString() worked! Thanks so much.
John
14. John wrote on September 26, 2005 at 1:19 PM
I wanted to ask you a quick question. I thought in a post which I can’t find right now someone said that can get more data when you switch tabs.

I am talking about using tab navigator in cfform with format flash.

Lets say what show up in tab2 depends on what you select in tab 1.

So I need to refesh what tab2 is showing when someone click on tab2 based on what record the user choose in tab1.

Is this possible?

Basicaly whenever someone clicks on tab2 I want to refresh the cfgrid with new data without refreshing the entire page.


What I wish I could do is put a cfquery inside of the second cfformgroup (the one named tab2). Have that run each time some one click on tab 2.


The other thing I have recently heard about about is CF.Query() function.

Can I do this on tab change inside of my coldfusion file. If so can you send me an example of how to do this.

If I don't hear from you I am going to use this filtering code to get all the data when the page first loads and then filter what I show based on what was chosen in tab1. The problem with this is that as amont of data get huge this will become impossible.

Thanks for any help you can give me.

John
Nahuel
John,
You have different options. You can do that with remoting and ask for a small amount of data each time like in this example:
http://www.asfusion.com/blog/entry/populating-a-cfgrid-with-flash-remoting

Or you can download everything to the client like in this example:
http://www.asfusion.com/blog/entry/quick-grid-bindings
John
16. John wrote on October 01, 2005 at 11:46 AM
I have 3 questions about how to controlthe tabs.
1. Is there any event that get triggered when a new tab is selected.

2. Can I change the tab selected manually.

3. Is there a way to hide or disable certain tabs depending on choices the user make outside of the tabnavigator.

Thanks in advance

Kourosh
Nahuel
John
1. onchange
2. myTab.selectedIndex = 0; // 1,2,3,4
3. try with bindings, or use the visible property
John
18. John wrote on October 04, 2005 at 1:55 PM
Thanks Nahuel.

I ended up having to use enabled = false
for hiding the tabs.

the visible property doesn't do anything for individual tabs. Even when you hard code set at the very start it still shows it.
Like this:
&lt;cfformgroup label=&quot;Documents&quot; type=&quot;page&quot; visible=&quot;no&quot;&gt;



mafdoc
19. mafdoc wrote on October 07, 2005 at 9:45 AM
I am currently using the filter grid with the query getArtists (shown below).
Now I want to get more data from another datasource and table.
I can not get query of query to work. This cfoutput shows all the data I need.
Can someone help me put this into a cfquery so I can use that query in the filter?

&lt;cfquery name=&quot;getArtists&quot; datasource=&quot;docpers&quot;&gt;
SELECT UserName, FirstName, LastName, WorkPhone, Division, Status
FROM tblmaster
WHERE status &lt;&gt; 'I'
ORDER BY UserName
&lt;/cfquery&gt;

&lt;cfoutput query=&quot;getArtists&quot;&gt;
&lt;cfquery name=&quot;getsiteinfo&quot; datasource=&quot;Site&quot;&gt;
SELECT *
FROM site
Where username = '#getArtists.UserName#'

&lt;/cfquery&gt;
#getArtists.UserName#, #getArtists.FirstName#, #getArtists.LastName#, #getArtists.Division#, #getsiteinfo.site#, #getsiteinfo.location#&lt;&lt;br&gt;
&lt;/cfoutput&gt;

Thanks for any help.
mafdoc
20. mafdoc wrote on October 07, 2005 at 10:25 AM
This query throws an error
&quot;Element USERNAME is undefined in TBLMASTER.&quot;

&lt;cfquery name=&quot;getArtists&quot; datasource=&quot;docpers&quot;&gt;
SELECT UserName, FirstName, LastName, WorkPhone, Division, Status
FROM tblmaster,
Site.site
WHERE status &lt;&gt; 'I'
AND username = '#tblintranetmaster.UserName#'
ORDER BY UserName
&lt;/cfquery&gt;

David
21. David wrote on November 15, 2005 at 1:38 PM
is there a way to do this with FLEX
Laura
David,
Of course there is! All the examples with cfform use the Flex engine. In fact, it should be pretty straight forward to do it, although you will need to get the data manually (either with remoting, xml, web service, etc)
david
23. david wrote on November 16, 2005 at 8:11 PM
thanks Laura, I modified the example today and got it to work using remoting like you suggested. I will try and post my actionscript tomorrow. thanks for the help :)

David
David
24. David wrote on November 17, 2005 at 9:53 AM
function doFilter(myFilter)
{
var filteredRecords = new Array();
var filterText:String = myFilter;
   
   for(var i = 0; i &lt; RemoteObjectName.ModelName.result.length; i++ )
   {
   var curRecord = RemoteObjectName.ModelName.result[i];
      var name = RemoteObjectName.ModelName.result[i].DataGridColumnName;
            
      if(name.substring(0,filterText.length).toLowerCase() == filterText.toLowerCase())
      {
         filteredRecords.push(curRecord);

      }
   }

   DataGridName.dataProvider = filteredRecords;
}
Mike
25. Mike wrote on December 16, 2005 at 12:01 PM
I haven't been able to get cfgridupdate to work with anything. Since you have an editable grid with a flashremoting link, how would I use cfgridupdate with this?

Thanks
Laura
Mike,
I never use cfgridupdate so I can't really help you with that. The code of the post should work with cfgridupdate if you submit the form though, but I have not tested it. Flash remoting is a different animal. cfgridupdate requires a form post, and you do not post a form post when you use remoting.
Brad Wood
27. Brad Wood wrote on January 09, 2006 at 10:11 AM
When I populate with flash remoting this stops working.

Specifically this line right here:
_global.backupDP = myGrid.dataProvider.slice(0);

doesn't work when the dataProvider was populated with remoting.

Why does life hate me?
Pleas tell me there is another way around this. If I get rid of the slice(0) it copies the list over but it copies by REFERENCE not by VALUE. I can't find anywhere a source that tells me what syntax would force AS to make a backup of the dataProvider by duplicating the list in memory.
Michael White
can you show/hide tabs (an entire page of a tab navigator) based on a control outside the tab navigator... like a CFGRID. I want a tab to be invisible until a selection is made in the grid.
Joseph
29. Joseph wrote on February 08, 2006 at 8:33 AM
Laura -

This is some great stuff. I'm using this to try to put together a three-level filtering system. There are three cfgrids. Selecting an item in the first one filters the second cfgrid, selecting an item in the second cfgrid filters the third cfgrid.

I was able to modify an 'actionFilter' and an 'actionFilter2' with little problem. Change all the appropriate cfgrid references, and use _global.backupDP2 instead of _global.backupDP.

In addition, however, there are SO MANY items in the third cfgrid, and they don't really make sense unless you've selected something from the second cfgrid, that it really needs to be hidden until something is chosen in actionFilter2.

My solution (I thought) was simple. Give the following propety to the cfformgroup that holds the third cfgrid.

visible=&quot;{((_global.myShowbox)?true:false)}&quot;

In addition, make a cfsavecontent called 'actionLoad' which loads upon onLoad which looks like this:

_global.myShowbox = 0;

In actionFilter, which is called when clicking on the first cfgrid, add the same line before any of the rest of the code. In actionFilter2, which is called when clicking on the second cfgrid, use this code before anything else:

_global.myShowbox = 1;

Theoretically, this would make a variable that would toggle the visibility of the third cfgrid and its assorted controls. It would be invisible when first loading, or when selecting something from the first cfgrid, and it would become visible when making a selection from the second cfgrid.

It didn't work.

Not only does it not toggle visibility states, but it also stops ActionFilter from working at all. ActionFilter now removes everything from the second cfgrid, but does not repopulate it with any data.

What did I do wrong?

Thank you in advance for your help. Your site is one of my favorite coldfusion sites, right after the livedocs themselves.
The ScareCrow
When I populate with flash remoting this stops working.

Specifically this line right here:
_global.backupDP = myGrid.dataProvider.slice(0);


I also ran into this. You could actually get the length of the data provider, but it would not assing to the global var.

This is how I fixed it.

In the response handler onResult

//create array to hold results
var myDP:Array = [];
//loop through result set
for(var x=0; x &lt; results.length; x++){
//add items to the array in the form
column name:column value
myDP.addItem({fld_Column1:results.getItemAt(x).fld_Column1, fld_Column2:results.getItemAt(x).fld_Column2});
}
//assign the array to the grid data provider.
myGrid.dataProvider = myDP;

The filter then works when the grid is populated by remoting

Ken
Laura
ScareCrow,
Actually, the simplest way to make it work with remoting is doing:
myGrid.dataProvider = results.items;
instead of simply:
myGrid.dataProvider = results;

This avoids having to loop over the data which might be slow for large sets.
The problem is that slice() is for arrays, not recordsets and the variables &quot;results&quot; holds a recordset, not an array when the component returns a query.
ramzi Chekkath
32. ramzi Chekkath wrote on March 11, 2006 at 5:10 PM
Hi,

i like the look in function but i want one of the two

1 - either one input box and it searches in any given colum name (with out the user changing it in a list)

2 - or multiple input boxes each one filtering a certain colum


i personally preffer the second option but to start with first option is fine.


eg. second option.
insert 1 = ra
insert 2 = c


so it returns to me
c1 c2
--- ---
ramzi chekkath
rasberry cherry
Thomary
33. Thomary wrote on March 13, 2006 at 12:50 PM
Macromedia LiveDocs system says you can use:
&lt;cfgridcolumn name = &quot;FirstName&quot; textColor = &quot;(CX EQ Peter ? blue : black)&quot;&gt;

I can not get this to work. Has anyone tried this? I would like combine two grids if possible but I really need to identify which listing is vendor and which are employees. I thought this would be very useful. Thanks for all your help.

candlelight
34. candlelight wrote on March 20, 2006 at 1:43 AM
Refering to David's solution to filtering with grid populated with flash remoting,

As I am quite new to actionscript, what is
&quot;RemoteObjectName.ModelName&quot;?

Anyone has some great example(s) of how enable filtering with grid populated with flash remoting?

Stucked..

Thanks
Laura
candlelight,
See my reply to ScareCrow 3 comments above. That's all what you need to make it work with remoting. Use the code explained at http://www.asfusion.com/blog/entry/populating-a-cfgrid-with-flash-remoting
Gary
36. Gary wrote on March 22, 2006 at 1:00 PM
Referring to Thomary's comment about using an expression in the textColor attribute to change the text color in a cfgridcolumn.

------

I've tried this too and have been unable to get it to work. I get no errors, but I also get no output, just a blank page.

Very frustrating ...
Neill
37. Neill wrote on March 28, 2006 at 1:52 AM
I have changed the filter code to that of the revisted. However, I still get an empty grid when the form arrives at the processing page. Any help greatly appreciated.
Joe Gutierrez
38. Joe Gutierrez wrote on June 19, 2006 at 2:20 PM
This was an excellent article, thanks! I used it to filter the grid based on multiple input fields for an address book. Here's my function.

// this function removes records from the grid based on the input fields
function applyFilter():Void {
var grid:mx.controls.DataGrid = myGrid;
var filterTerm:Array = [];
var columns: Array = [];
var value:Array = [];

// array of columns that correspond to datagrid col names
columns[0] = 'lastname';
columns[1] = 'firstname';
columns[2] = 'city';
columns[3] = 'state';
columns[4] = 'phone';

// array of values from input fields where to get filter terms
filterTerm[0] = frmClient.lastname.toString().toLowerCase();
filterTerm[1] = frmClient.firstname.toString().toLowerCase();
filterTerm[2] = frmClient.city.toString().toLowerCase();
filterTerm[3] = frmClient.state.toString().toLowerCase();
filterTerm[4] = frmClient.phone.toString().toLowerCase();

if(filterTerm.length > 0) {
    if(_global.unfilteredData[grid.id] == undefined){
       if (_global.unfilteredData == undefined){
         _global.unfilteredData = {};
       }
       _global.unfilteredData[grid.id] = grid.dataProvider.slice(0);
    }
   
    var filteredData:Array = [];

    for(var i = 0; i< _global.unfilteredData[grid.id].length; i++) {
       var item:Object = _global.unfilteredData[grid.id][i];
       var added:Boolean = false;
       var pushit:Boolean = true;
      
      for (var x = 0; x < columns.length; x++) {
         value[x] = item[columns[x]].toString().toLowerCase();
         if (filterTerm[x] != '' && filterTerm[x] != undefined)
         {
            if (value[x].substr(0,filterTerm[x].length).toLowerCase() != filterTerm[x])
            {
               pushit = false;
            }
         }
      }
      if ( pushit == true){
         filteredData.push(item);
          added = true;
      }
    }

grid.dataProvider = filteredData;

}
else {
    if(_global.unfilteredData[grid.id] != undefined) grid.dataProvider = _global.unfilteredData[grid.id];
}
}
Andy W.
39. Andy W. wrote on June 21, 2006 at 7:30 AM
I have a cfgrid where the filtering works. One of the columns on the grid is a check box. After the user submits the form I process the rows for which the check box was changed by looping through the array form.mygrid.rowstatus.action. This array is the proper size and the code works when I do not type anything to filter the grid. If I filter the grid and change one or more rows the array form.mygrid.rowstatus.action contains 0 elements.

I'm wondering if it has something to do with pass by value/reference situation.

Here is the code that I used for filtering the grid.

function applyFilter(grid:mx.controls.DataGrid):Void{
    var arrDisplay:Array = [];
   
    var fortext = name.text.toLowerCase();
    var isApplicable:Boolean = true;
   
      
   if(_global.arrMembers == undefined) _global.arrMembers = userGrd.dataProvider.slice(0);
       var arrMembers = _global.arrMembers;
   
    for(var i = 0; i < arrMembers.length; i++){
         
         //Filter on the text
         if (fortext.length > 0){
            isApplicable = filterText(fortext,i,arrMembers[i].first_nm.toString(),arrMembers[i].last_nm.toString(),arrMembers[i].org_nm.toString(),arrMembers[i].user_nm.toString());
         }
         else{
            isApplicable = true;
         }
      
         
         
      
         if (isApplicable == true){
      
            arrDisplay.push(arrMembers[i]);
            isApplicable = true;
         }
         
      }
      
      userGrd.dataProvider = arrDisplay;
}
   
///filter for text
function filterText(fortext:String, i:Number, first:String, last:String,org:String, user:String):Boolean{
      var isApplicable:Boolean;
      
      if ((first.substr(0,fortext.length).toLowerCase() == fortext || last.substr(0,fortext.length).toLowerCase() == fortext || org.substr(0,fortext.length).toLowerCase() == fortext|| user.substr(0,fortext.length).toLowerCase() == fortext) ){
         isApplicable = true;
      }
      return isApplicable;
   }
Andy W.
40. Andy W. wrote on June 21, 2006 at 7:39 AM
I have a cfgrid where the filtering works. One of the columns on the grid is a check box. After the user submits the form I process the rows for which the check box was changed by looping through the array form.mygrid.rowstatus.action. This array is the proper size and the code works when I do not type anything to filter the grid. If I filter the grid and change one or more rows the array form.mygrid.rowstatus.action contains 0 elements.

I'm wondering if it has something to do with pass by value/reference situation.

Here is the code that I used for filtering the grid.

function applyFilter(grid:mx.controls.DataGrid):Void{
    var arrDisplay:Array = [];
   
    var fortext = name.text.toLowerCase();
    var isApplicable:Boolean = true;
   
      
   if(_global.arrMembers == undefined) _global.arrMembers = userGrd.dataProvider.slice(0);
       var arrMembers = _global.arrMembers;
   
    for(var i = 0; i < arrMembers.length; i++){
         
         //Filter on the text
         if (fortext.length > 0){
            isApplicable = filterText(fortext,i,arrMembers[i].first_nm.toString(),arrMembers[i].last_nm.toString(),arrMembers[i].org_nm.toString(),arrMembers[i].user_nm.toString());
         }
         else{
            isApplicable = true;
         }
      
         
         
      
         if (isApplicable == true){
      
            arrDisplay.push(arrMembers[i]);
            isApplicable = true;
         }
         
      }
      
      userGrd.dataProvider = arrDisplay;
}
   
///filter for text
function filterText(fortext:String, i:Number, first:String, last:String,org:String, user:String):Boolean{
      var isApplicable:Boolean;
      
      if ((first.substr(0,fortext.length).toLowerCase() == fortext || last.substr(0,fortext.length).toLowerCase() == fortext || org.substr(0,fortext.length).toLowerCase() == fortext|| user.substr(0,fortext.length).toLowerCase() == fortext) ){
         isApplicable = true;
      }
      return isApplicable;
   }
Mark Cadle
41. Mark Cadle wrote on June 21, 2006 at 10:29 AM
I will post this in the other sections as well involving filtering a grid. If you are not using remoting and do not have an editable grid so to speak, if you run a cfgridupdate it will fail saying that it can not find the grid named XXXX.

This is only once you have filtered the grid. If you do not filter the grid then it will work. So at what point does this rename the grid? How can you keep the same grid name?

I update the grid via a cfinput that is bound to the selectedIndex of the grid and then have a button with onclick to:
gridname.dataProvider.editField(gridname.selectedIndex, 'COLUMN', textname.text);

This works great and the cfgridupdate works great even when you filter the grid, but once you filter the grid, you can not run the cfgridupdate.

I hope this makes sense.
Joel Watson
I am desperately trying to enable a filter between two grids AND being able to insert, update and delete records when a filter is applied.

Currently, I can insert, update and delete when no filter is applied no problem (not an ideal solution), but when I try to filter, the functionality disappears and the submission sends a blank entry.

Any ideas on this? I have read through the comments here and I cannot find anything that solves my dilemma. I really appreciate the help!

Joel
Dysfunction erectile pills
Very good site. You are doing a great job. Please keep it up!
Sexual Stimulant
hello every body i really like what you do continu i'm here to help me too
good luck all
Ryan - Smurf
This is a more efficient and much quicker way of filtering while you type. You can basically use the old school remoting tactics. Well here goes….

file: filter.cfm

<cfsilent>
<cfsavecontent variable="onLoad">
   _global.loaded = true;
   <cfoutput>
      <!---create connection--->
      var connection:mx.remoting.Connection = mx.remoting.NetServices.createGatewayConnection("http://#cgi.HTTP_HOST#/flashservices/gateway";);
      <!---declare service--->
      var netService:mx.remoting.NetServiceProxy;
      <!---declare component--->
      var epmComp = "xEPM.authenticated.components.empCFC";
   </cfoutput>

   <!--- includes actionscript file for form --->
   #include "actionscript/as_dataManagement.as"
</cfsavecontent>
</cfsilent>


<cfform format="flash" name="empForm" wmode="transparent" onload="#onLoad#" style="#formStyle#" preservedata="yes" >
<cfformgroup type="horizontal" style="marginTop:0; horizontalGap:15;marginRight:15;horizontalAlign:right">
                  <cfinput type="text" name="filterProjectInput" size="12" label="Filter: " onChange="_global.findProject({})" enabled="{gridCustomer.selectedItem != undefined}"/>
               </cfformgroup>
</cfform>

file: as_dataManagement.as

_global.findProject = function():Void {
   //fields are passed to component as a variable
   var Parameter = {};
   Parameter.filterText = _root.filterProjectInput.text.toLowerCase();
   mx.managers.CursorManager.setBusyCursor();
   Parameter.onStatus = function( stat: Object ):Void {
      //if there is any error, show an alert
      alert("Error while calling cfc:" + stat.description);
   }
   
   //get service
   netService = connection.getService(epmComp, Parameter);
   
   //find data with remoting
   netService.findProject(Parameter);
   
   //put the controls in scope to avoid calling _root
   var gridProject = _root.gridProject;
   
   Parameter.onResult = function( results: Object ):Void {
      //when results are back, populate the cfgrid
      gridProject.dataProvider = results;
      mx.managers.CursorManager.removeAllCursors();
   }
}

file: epmCFC.cfc

<cffunction access="remote" name="findProject" output="false" returntype="Any">
      <cfargument name="filterText" type="Any" required="yes">
      
         <cfquery name="findProject" datasource="#session.datasource#">
            SELECT *
            FROM PROJECTS
            WHERE projectName LIKE <cfqueryparam cfsqltype="cf_sql_varchar" value="%#lcase(arguments.filterText)#%">
         </cfquery>
         <cfreturn findProject/>
   </cffunction>
Michael White
46. Michael White wrote on September 07, 2007 at 9:30 AM
I am curious about the "#formStyle#" variable. I assume it is a structure. would you share that too?
Mark Cadle
Not to crack on the post there, but remoting for filtering is a poor idea. Every letter typed is making a call to the database....why??? All of the data has already been stored in the grid. Making a copy of that data and placing it in an array is much faster, convenient, less network traffic, as well as better performance on the page by memory management. I would highly NOT recommend do a remoting call just to filter a grid.
Nahuel
I agree 100% with Mark. It is not good to call the server each time a user enters a letter. You can kill the server if you have a lot of records :)
Kevin Hunkovic
49. Kevin Hunkovic wrote on October 10, 2007 at 3:33 PM
Is there any way to the above example with an xml form instead of a flash form. I have gotten the above example to work perfectly however when you are dealing with large datasets say over 200 records the form takes 25 seconds to load. If I change the format of the form to xml instead of flash it the grid loads in 2 seconds. The filter functions no longer work of course.

Leave your comment

Comment etiquette: As a gesture to those subscribed to this post, please keep your comments relevant to the post.

Your email address will never be displayed.
Email is gravatar enabled.Gravatar are the pictures you see next to the comments. If you like to have one, visit gravatar



Allowed tags:

<code>
All other tags will be shown as such, when in doubt, use the preview.




Preview:

Refresh Preview
1. You wrote on