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. <cfform name="test"> <input type="text" name="filter"> <cfgrid autowidth="true" name="entries" format="html" bind="cfc:test.getEntries({cfgridpage},{cfgridpagesize},{cfgridsortcolumn},{cfgridsortdirection},{filter@keyup})" width="600"> <cfgridcolumn name="id" display="false"> <cfgridcolumn name="body" display="false">

<cfgridcolumn name="title" header="Title"> <cfgridcolumn name="posted" header="Posted"> </cfgrid> </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:

<cfset ajaxOnLoad('init')>

In my init() function, I began by grabbing a reference to the grid:

var mygrid = ColdFusion.Grid.getGridObject('entries')

I jumped over to the Ext docs and began to dig. I knew that I could get access to the datasource with the following:

var ds = mygrid.getDataSource()

Then I checked to see if there was an event I could listen for that involved data. Yep, a nicely named "load" event.

ds.addListener('load', function() {

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:

var count = 0; ds.each(function() { if(this.data.ID != null) count++ })

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:

<html>

<head> <script src="jquery/jquery.js"></script> <script> function init() { console.log('Ran') var mygrid = ColdFusion.Grid.getGridObject('entries') //console.dir(mygrid) var ds = mygrid.getDataSource() ds.addListener('load', function() { //console.dir(ds) var count = 0; ds.each(function() { if(this.data.ID != null) count++ }) if(count == 0) $("#msg").text('Sorry, but there are no records to display.') else $("#msg").text('') })

}; </script> </head>

<body> <cfform name="test"> <input type="text" name="filter"> <cfgrid autowidth="true" name="entries" format="html" bind="cfc:test.getEntries({cfgridpage},{cfgridpagesize},{cfgridsortcolumn},{cfgridsortdirection},{filter@keyup})" width="600"> <cfgridcolumn name="id" display="false"> <cfgridcolumn name="body" display="false">

<cfgridcolumn name="title" header="Title"> <cfgridcolumn name="posted" header="Posted"> </cfgrid> </cfform>

<div id="msg"></div>

</body> </html>

<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.