Posted in ColdFusion | Posted on 04-09-2009 | 5,944 views
Brett asked:
I have a CFM with a CFGrid that uses a Bind to a CFC. On the CFM page a I have a few CFSelects that allow users to filter down the results being displayed in the CFGrid. I have also included a text input for keywords that uses a vertiy search to filter the results down even more. However is there a way to display to the user that no records were found from their search, the only thing that I get now is an empty grid.
To get an idea of what Brett was talking about, I created a simple grid example that used a text box to filter results.
2<input type="text" name="filter">
3<cfgrid autowidth="true" name="entries" format="html" bind="cfc:test.getEntries({cfgridpage},{cfgridpagesize},{cfgridsortcolumn},{cfgridsortdirection},{filter@keyup})" width="600">
4 <cfgridcolumn name="id" display="false">
5 <cfgridcolumn name="body" display="false">
6
7 <cfgridcolumn name="title" header="Title">
8 <cfgridcolumn name="posted" header="Posted">
9</cfgrid>
10</cfform>
The CFC method in the back end is a simple query against my blog database. I added an additional argument, filter, that will limit the results when something is typed in the filter. You can see an example of this here. Type something wacky (like dflkldfk) in the field and the grid will empty out. There is no real simple visual cue that the results were filtered to an empty set. (Well, ok, it is obvious to me, but I can see some users getting confused.)
I began to dig into the grid to see if there was a nice way to handle this. I started off by setting up a function to run when everything was loaded:
In my init() function, I began by grabbing a reference to the grid:
I jumped over to the Ext docs and began to dig. I knew that I could get access to the datasource with the following:
Then I checked to see if there was an event I could listen for that involved data. Yep, a nicely named "load" event.
The addListener function takes the name of an event to listen to and an inline function.
So what next? The ds object represents the data. But here's the weird thing. Even when you see nothing in the grid, you still have 10 rows of data in the grid. I'm guessing this is something on the ColdFusion side, or perhaps just how Ext works. What you can do - though - is look at the data. This is what I used:
2ds.each(function() {
3 if(this.data.ID != null) count++
4})
Basically, loop over the data, and check the field (ID comes from one of my columns) to see if it is null. This worked perfectly. I brought it all together by using jQuery to update a div when count was 0. It may be overkill to use jQuery for one line of code, but, meh, I'm a fan boy. So here is the entire CFM:
2
3<head>
4<script src="jquery/jquery.js"></script>
5<script>
6function init() {
7 console.log('Ran')
8 var mygrid = ColdFusion.Grid.getGridObject('entries')
9 //console.dir(mygrid)
10 var ds = mygrid.getDataSource()
11 ds.addListener('load', function() {
12 //console.dir(ds)
13 var count = 0;
14 ds.each(function() {
15 if(this.data.ID != null) count++
16 })
17 if(count == 0) $("#msg").text('Sorry, but there are no records to display.')
18 else $("#msg").text('')
19 })
20
21};
22</script>
23</head>
24
25<body>
26<cfform name="test">
27<input type="text" name="filter">
28<cfgrid autowidth="true" name="entries" format="html" bind="cfc:test.getEntries({cfgridpage},{cfgridpagesize},{cfgridsortcolumn},{cfgridsortdirection},{filter@keyup})" width="600">
29 <cfgridcolumn name="id" display="false">
30 <cfgridcolumn name="body" display="false">
31
32 <cfgridcolumn name="title" header="Title">
33 <cfgridcolumn name="posted" header="Posted">
34</cfgrid>
35</cfform>
36
37<div id="msg"></div>
38
39</body>
40</html>
41
42<cfset ajaxOnLoad('init')>
Notice the new DIV at the bottom. That's just there for the message. You could use an alert or some other way to warn the user. You can play with this code here.


Seems kind of odd to me, but there are ways around it.
<cfset foo = queryConvertForGrid(q,arguments.page,arguments.pagesize)>
<cfset zoo = queryNew(foo.query.columnList)>
<cfloop index="x" from="1" to="#foo.totalrowCount#">
<cfset queryAddRow(zoo)>
<cfloop index="l" list="#zoo.columnlist#">
<cfset theval = foo.query[l][x]>
<cfset querySetCell(zoo, l, theval)>
</cfloop>
</cfloop>
<!---
<cfdump var="#zoo#">
<cfdump var="#queryConvertForGrid(q,arguments.page,arguments.pagesize)#"><cfabort>
<cfreturn queryConvertForGrid(q,arguments.page,arguments.pagesize)>
--->
<cfset foo.query = zoo>
<cfreturn foo>
When run, the grid now actually shrinks to the size of the result set.
Hmm. That may be bad for times when the record larger than page count.
<cfloop index="x" from="1" to="#min(foo.totalrowCount,arguments.pagesize)#">
actually works. Kinda cool. Not sure if that is 'better' or not.
Will do a second blog entry today showing this method as well.
All fodder for the next blog entry. Thanks Justin.
<cfset iCount = Max(0,(rs.RecordCount - ((Arguments.page -1 )* arguments.pagesize) ) )>
<cfset retStr = QueryConvertForGrid(rs,arguments.page,min(arguments.pagesize, iCount))>
Thank you,
Adam
Thanks
ColdFusion.Grid.getGridObject('my_grid').view.emptyText = "No Records were found with the specified search criteria";
And the message will appear if the grid is empty.
I display the records this way, but the above works too. Mine is based on CF9.0.1 which is using Ext Grid 3.1. Not sure if it will work on out of the box 9:
mygrid = ColdFusion.Grid.getGridObject('yourGridName');
// FOR CF 9 ROW COUNTING
var mds = mygrid.getStore()
mds.addListener('load', function() {
$("h2").html(mds.getTotalCount() + ' ');
});
[Add Comment] [Subscribe to Comments]