Filtering records on a cfform grid
49 comments Posted by: NahuelAfter reading what Simeon from Simfluence wrote today, I started playing with his example and I modified a little bit his code. Some of the changes I made are that I keep the data in the global scope instead of the shared object and maintain the row numbers on the grid.
Here is the result.
And the code:
<cfscript>
rs = queryNew("id,fname,lname,dept,email");
addRow(rs, 'simeon','bateman','IT','simeon@eee.net');
addRow(rs, 'Mr','Man','HR','theMan@eee.com');
addRow(rs, 'Cool','Guy','HR','coolGuy@eee.com');
addRow(rs, 'Another','test','Customer Service','another@teeeest.com');
function addRow( qry, fname, lname, dept, email){
queryAddRow(rs);
querySetCell(rs,'fname',fname);
querySetCell(rs,'lname',lname);
querySetCell(rs,'dept',dept);
querySetCell(rs,'email',email);
}
</cfscript>
<cfquery dbtype="query" name="getDepts">
SELECT distinct dept
FROM rs
ORDER BY dept
</cfquery>
<cfquery dbtype="query" name="MemberList">
SELECT * from rs
ORDER BY dept
</cfquery>
<cfsavecontent variable="astest">
if(_global.arrMembers == undefined) _global.arrMembers = data.dataProvider.slice(0);
var arrMembers = _global.arrMembers;
var arrDisplay:Array = [];
for(var i = 0; i < arrMembers.length; i++)
{
if(arrMembers[i].dept == myselect1.value || myselect1.value == 'All')
{
arrDisplay.push(arrMembers[i]);
}
}
data.dataProvider = arrDisplay;
</cfsavecontent>
<cfform name="myForm" format="flash" width="400" height="300">
<cfformgroup type="panel" label="Search our Members">
<cfselect query="getDepts" queryposition="below" label="Parent category" name="myselect1" value="dept" display="dept" width="200" onChange="#astest#">
<option value="All">All</option>
</cfselect>
<cfgrid name="data" query="MemberList" >
<cfgridcolumn header="First Name" name="fname" />
<cfgridcolumn header="Last Name" name="lname" />
<cfgridcolumn header="email" name="email" />
<cfgridcolumn header="Department" name="dept" display="false" />
</cfgrid>
</cfformgroup>
</cfform>
View the example.
Download the source.
49 Comments so far
Write yours1) cfset a variable to - - - department selected
2) can we do any code in the cfsavecontent.. a new cfquery to collect the data for the department selected.
TIA for your help.
I was also wondering about a way to edit, add, delete rows from the grid. I think that filling text inputs would be the best way to do it. I tried to do it with an editable grid, but encountered some problems. If you do the filter, then edit (or delete) a record, and click submit, the information is not passed through.
Still working on it though. Might have to give up and just populate text boxes.
Thanks again.
Adding the charts would be possible but it's not an easy task. The problem is that you can not add a chart to a cfform (Macromedia didn't implement that feature). The only way would be saving the charts as jpg and then loading them from the form. In that case, however, the chart won't be dynamic and will have to be created before showing the form.
I wonder what data is received when you submit the form. What may be happening is that you only receive the filtered data (what you are seeing in the grid) but not all the records. You could make a custom submit button to inject all the data in the grid and them submit it.
You can check my next post about how to make an onLoad event. But the data that is loaded in the datagrid comes via Remoting and takes a few seconds to load. So you may need to do some kind of delay if you want to select a row. Otherwise, when the data comes it overwrite your selection. What you are trying to achieve is not easy but is possible.
just do something like this:
<cfsavecontent variable="sortbypage">
if(_global.arrMembers == undefined) _global.arrMembers = data.dataProvider.slice(0);
var arrMembers = _global.arrMembers;
var arrDisplay:Array = [];
for(var i = 0; i < arrMembers.length; i++)
{
if(arrMembers[i].ContentPath == myselect1.value || myselect1.value == 'All')
{
if(arrMembers[i].ContentLanguage == myselect2.value || myselect2.value == 'All')
{
arrDisplay.push(arrMembers[i]);
}
}
}
data.dataProvider = arrDisplay;
</cfsavecontent>
<cfsavecontent variable="sortbylanguage">
if(_global.arrMembers == undefined) _global.arrMembers = data.dataProvider.slice(0);
var arrMembers = _global.arrMembers;
var arrDisplay:Array = [];
for(var i = 0; i < arrMembers.length; i++)
{
if(arrMembers[i].ContentLanguage == myselect2.value || myselect2.value == 'All')
{
if(arrMembers[i].ContentPath == myselect1.value || myselect1.value == 'All')
{
arrDisplay.push(arrMembers[i]);
}
}
}
data.dataProvider = arrDisplay;
</cfsavecontent>
for(var i = 0; i < arrMembers.length; i++)
{
alert(arrMembers[i].department,'Routine',mx.controls.Alert.OK);
if(arrMembers[i].department == myselect1.value || myselect1.value == 'All')
{
arrDisplay.push(arrMembers[i]);
}
}
<cfquery name="getPositions" datasource="erpd">
select department, job_title
from xxhr_job_postings_v
order by department, job_title
</cfquery>
But fieldnames returned are in uppercase. Therefore ActionScript code must be:
if(arrMembers[i].DEPARTMENT == myselect1.value || myselect1.value == 'All')
You can sort the data in your query and that is the sorting it will get when the grid is loaded.
I have the same problem. Information is not passed to the action page after you do grid filtering.
Have you solve this problem?. Does anybody have solution?
Thanks.
I know what the problem is. We would need to change the code to address that. I will made a new post in the future that may help you.
Thanks.
I cannot see the Datagrid on POST, so my idea to enumerate by hand failed!
<cfif IsDefined('form.data.rowstatus.action')>
<cfloop index="i" from="1" to="#ArrayLen(form.data.rowstatus.action)#">
<!--- insert statement--->
<cfif form.data.rowstatus.action[i] IS "I">
Do an Insert blah blah
<!--- delete statement--->
<cfelseif form.data.rowstatus.action[i] IS "D">
Do an Delete
</cfif>
</cfloop>
</cfif>
Line: 1
Char: 1
Error: Object Expected
Code: 0
Here's the code for this example:
<script language="JavaScript" type="text/javascript">var lc_id = Math.floor(Math.random() * 100000).toString(16);</script>
<cfquery name="updates" datasource="#application.dsn.oiws#">
SELECT *
FROM tbl_List360
ORDER BY lastName
</cfquery>
<cfform name="myForm" format="flash" width="450" height="350" action="handle_grid.cfm">
<cfgrid name= "myGrid" query="updates" height="150" rowheaders="yes" insert="yes" InsertButton="Insert New Record" selectmode="edit">
<cfgridcolumn name="racf" header="RACF ID" select="true">
<cfgridcolumn name="lastName" header="Last Name" select="true">
<cfgridcolumn name="firstName" header="First Name" select="true">
<cfgridcolumn name="active" header="Active 0 or 1" select="true" dataalign="center">
</cfgrid>
<cfinput type="submit" name="submit" value="Update Records" action="handle_grid.cfm">
</cfform>
Here's the handle_grid:
<html>
<head>
<title>Catch submitted grid values</title>
</head>
<body>
<h3>Grid values for Form.myGrid row updates</h3>
<cfif isdefined("Form.myGrid.rowstatus.action")>
<cfloop index = "Counter" from = "1" to =
#arraylen(Form.myGrid.rowstatus.action)#>
<cfoutput>
The row action for #Counter# is:
#Form.myGrid.rowstatus.action[Counter]#
<br>
</cfoutput>
<cfif Form.myGrid.rowstatus.action[counter] is "D">
<cfquery name="DeleteExistingEmployee"
datasource="#application.dsn.oiws#">
DELETE FROM tbl_List360
WHERE
racf='#Form.myGrid.original.racf[Counter]#'
</cfquery>
<cfelseif Form.myGrid.rowstatus.action[counter] is "U">
<cfquery name="UpdateExistingEmployee"
datasource="#application.dsn.oiws#">
UPDATE tbl_List360
SET
racf='#Form.myGrid.racf[Counter]#',
lastName='#Form.myGrid.lastName[Counter]#',
firstName='#Form.myGrid.firstName[Counter]#',
active='#Form.myGrid.active[Counter]#'
WHERE
racf='#Form.myGrid.original.racf[Counter]#'
</cfquery>
<cfelseif Form.myGrid.rowstatus.action[counter] is "I">
<cfquery name="InsertNewEmployee"
datasource="#application.dsn.oiws#">
INSERT into tbl_List360
(racf, lastName, firstName, active)
VALUES ('#Form.myGrid.racf[Counter]#', '#Form.myGrid.lastName[Counter]#', '#Form.myGrid.firstName[Counter]#', #Form.myGrid.active[Counter]#)
</cfquery>
</cfif>
</cfloop>
</cfif>
</body>
</html>
Where do you get that error?
Sorry for the delayed response. Everything is working fine now, to resolve this issue I refreshed a few of the files in the CFIDE directory in our 'live' environment and it worked just fine! Go figure.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Two DataGrids</title>
</head>
<cfset myQuery1 = querynew("departmentid, departmentname")>
<cfset myQuery2 = querynew("departid, name")>
<!--- make some rows in the query --->
<cfset newRow1 = QueryAddRow(MyQuery1, 2)>
<cfset newRow2 = QueryAddRow(MyQuery2, 4)>
<!--- set the cells in the query --->
<cfset temp1 = QuerySetCell(myQuery1, "departmentid", "1", 1)>
<cfset temp1 = QuerySetCell(myQuery1, "departmentname", "Department 1", 1)>
<cfset temp1 = QuerySetCell(myQuery1, "departmentid", "2", 2)>
<cfset temp1 = QuerySetCell(myQuery1, "departmentname", "Department 2", 2)>
<cfset temp2 = QuerySetCell(myQuery2, "departid", "1", 1)>
<cfset temp2 = QuerySetCell(myQuery2, "name", "Fred", 1)>
<cfset temp2 = QuerySetCell(myQuery2, "departid", "1", 2)>
<cfset temp2 = QuerySetCell(myQuery2, "name", "Jane", 2)>
<cfset temp2 = QuerySetCell(myQuery2, "departid", "2", 3)>
<cfset temp2 = QuerySetCell(myQuery2, "name", "John", 3)>
<cfset temp2 = QuerySetCell(myQuery2, "departid", "2", 4)>
<cfset temp2 = QuerySetCell(myQuery2, "name", "Jane", 4)>
<cfsavecontent variable="actionFilter">
if(_global.arrMembers == undefined) _global.arrMembers = data1.dataProvider.slice(0);
var arrMembers = _global.arrMembers;
var arrDisplay:Array = [];
var selected = data.selectedItem.departmentid;
for(var i = 0; i < arrMembers.length; i++)
{
if(arrMembers[ i ]["departid"] == selected)
{
arrDisplay.push(arrMembers[ i ]);
}
}
data1.dataProvider = arrDisplay;
</cfsavecontent>
<body>
<cfform
action=""
method="POST"
name="myForm"
format="Flash"
timeout="300"
preservedata="Yes">
<cfformgroup type="HORIZONTAL">
<cfgrid name="data"
width="300"
format="FLASH"
query="myQuery1"
insert="No"
delete="No"
sort="Yes"
bold="No"
italic="No"
autowidth="true"
appendkey="No"
highlighthref="No"
enabled="Yes"
visible="Yes"
griddataalign="LEFT"
gridlines="Yes"
rowheaders="Yes"
rowheaderalign="LEFT"
rowheaderitalic="No"
rowheaderbold="No"
colheaders="Yes"
colheaderalign="LEFT"
colheaderitalic="No"
colheaderbold="No"
selectmode="BROWSE"
picturebar="No"
onchange="#actionFilter#">
<cfgridcolumn name="departmentid">
<cfgridcolumn name="departmentname">
</cfgrid>
<cfgrid name="data1"
width="200"
format="FLASH"
query="myQuery2"
insert="No"
delete="No"
sort="Yes"
bold="No"
italic="No"
autowidth="true"
appendkey="No"
highlighthref="No"
enabled="Yes"
visible="Yes"
griddataalign="LEFT"
gridlines="Yes"
rowheaders="Yes"
rowheaderalign="LEFT"
rowheaderitalic="No"
rowheaderbold="No"
colheaders="Yes"
colheaderalign="LEFT"
colheaderitalic="No"
colheaderbold="No"
selectmode="BROWSE"
picturebar="No">
<cfgridcolumn name="departid">
<cfgridcolumn name="name">
</cfgrid>
</cfformgroup>
</cfform>
</body>
</html>
my oo.cfm has that turned on during execution to ensure clean output. and since the code within had no <cfoutout> around it the cfsavecontent was ...empty. Once i surrounded the cfsavecontent tags with a cfoutput all was well....somthing for the records!
that issue has been addressed at: http://www.asfusion.com/blog/entry/filtering-a-cfgrid-as-you-type--revisited-
Eg. If date1 is greater then date2 show red otherwise black.
You will have to write some actionScript for that in a separate function that checks whatever you want. It might be slow though if you have many records. Check this post:
http://www.asfusion.com/blog/entry/looping-over-the-records-of-a-large-cfgrid
And by the way, if you have a question, please post it *once* in a post related to the question and we will try to answer as quickly as possible. Thanks
I am new to actionscripting but I tried using the expression:
textColor="(date1 LT date2 ? red : black)" without success. Any ideas?
Thanks
I haven't seen a response, but I have a similar, odd situation where a cfform (flash)/cfgrid works just fine on my CF dev server (running atop the built in web server), but when I move the template to the production server (CF atop Apache 2.0) the grid comes up but no data. When I cfdump the same query that is used by the cfgrid, the data is all there (on the production server), but the flash form continues to show nothing. Any clues why this might be happening? Grateful for any suggestions....
http://livedocs.macromedia.com/coldfusion/6/CFML_Reference/Tags-pt149.htm
Shows an expression on gridcolumn.
<cfgridcolumn name = "FirstName" textColor = "(CX EQ Pam ? blue : black)">
I would really like to know how to use this. I have a MySql Query and the ASFusion ActionFilter Grid. The Grid has a varchar field Division. I want the Division to turn blue if it EQ 98. I can not get this to work. Is there a required setting to get this to work? I've tried the selectmode="row"?
Thanks for your help.
It seems that Flash remoting is not correctly set up in your production server. I can't help you with Apache, but I would go to Adobe's website to see how to set it up.
Thomary and James,
First, you should be looking at CF7's docs, not 6.
What you are doing does not work in Flash forms because you can only change the color of the whole column, not individual items.
I would use something like this:
http://www.asfusion.com/blog/entry/looping-over-the-records-of-a-large-cfgrid
to change the color of the row.
Is it possible to filter results using the date picker control with the cfgrid. My resultset has a date from SQL in the results field and I would like users to have two date picker controls so they only see info in a certain date range. Simply comparing the dates doens't seem to work and I assume it's got something to do with the date format, but I am new to flash and not sure how to tell what dates are being passed to the actionscript.
I'm trying to filter the data also via 2 dates. A start date and an End date Based on these dates the grid will display the result from the query. Similar to what C is trying to do on the previous post. Can some please help.
Thanks
Jimmy
(arrMembers[i].month_published.substring(6,10) > activityStart.selectedDate.getFullYear() ||
(arrMembers[i].month_published.substring(6,10) == activityStart.selectedDate.getFullYear() &&
arrMembers[i].month_published.substring(0,2) > activityStart.selectedDate.getMonth()))
Thanks,
Jimmy
<table align="center" width="100%"><tr><td valign="top">
<form action="firstfind.cfm?search=1" method="post" name="getinfo">
Enter the begining of the Last Name and click Find.
<input type="text" id="findme" name="findme" size="5">
<script type="text/javascript" language="JavaScript">
{ document.getElementById("findme").focus(); }
</script>
<input type="Submit" name="btnfind" value="Find">
<input type="hidden" name="btnfind">
</form>
</td></tr></table>
<cfif isdefined ("search") or isdefined("url.back")>
<cfform name="getinfo" format="flash" action="firstfind.cfm" method="post" height="560" onload="formOnLoad()" timeout="200">
<CFQUERY NAME="getArtists" DATASOURCE="docpersonnel">
SELECT *
FROM tblyourtablename
<cfif parameterExists(btnfind) and not parameterExists(url.back)>
WHERE tblyourtablename.LastName like '#form.findme#%'
</cfif>
<cfif parameterExists(url.back)>
WHERE tblyourtablename.EmployeeID = '#url.RecordID#'
</cfif>
ORDER BY tblyourtablename.LastName, tblyourtablename.FirstName
</CFQUERY>
<!--- Do grid here --->
</cfform>
I got this from a coworker. It's a great idea. I had too many records to show the grid with every record.
So he said to do a regular html form first to get the variables set (like your dates, I used the LastName field. HTH...
https://reservations.ihotelier.com/onescreen.cfm?hotelid=3717&languageid=1
Thanks.
Jimmy
Thanks in advance
i use this script to filter records from an oracle db. The difference is that i use as filter a year.
arrMembers[i].year == myselect1.value
But it doesn't work.
Is there a problem with numbers?
thanks
I'm new to this, but how do you get the cfgrid data in this example with the filter applied to post? I added a method, action, and submit button with no luck.
Thanks
If I filter I can't get anything to post.
Can anyone shed some light?
Thanks!