ColdFusion 8 cfgrid - Implementing User Selected PageSize and using YUI Dom Collection Library
Jan 15
Previously I blogged about implementing a filter feature and ability to show/hide columns in the grid Here. We are going to make another small enhancement to it, we will allow the User to select how many records to display per page (from a pre-defined list). We will also use some powerful Yahoo User Interface (YUI) Do functions to implement this.
Demo Currently Unavailable
So, the first thing to do is build the area where the user selects how many records to display per page, with 5 being the default.
2<a id="p2" class="" href="javascript:changePage(2)">2</a> |
3<a id="p4" class="" href="javascript:changePage(4)">4</a> |
4<a id="p5" class="selected" href="javascript:changePage(5)">5</a> |
5<a id="p6" class="" href="javascript:changePage(6)">6</a> |
I implemented a selected class to show which of the options is currently selected by the user. It just bolds the text. When the user clicks on the link, it calls the changePage function. When the user clicks on one of the numbers, the following things need to happen:
- Strip current selection of its selected class so it goes back to normal text
- New selection should get the selected class so it gets bolded
- Change the grid pageSize
- Reconfigure the grid to reflect the new pagesize
2{
3 //Get current link anchors with selected class
4 var currClasses = YAHOO.util.Dom.getElementsByClassName('selected', 'a');
5 //Remove selected class from them
6 YAHOO.util.Dom.removeClass(currClasses,'selected');
7 //Specify the selected link anchor to have selected class
8 YAHOO.util.Dom.addClass('p' + newSize,'selected');
9 //Store new value in hidden form variable
10 document.getElementById('pages').value = newSize;
11
12 //Get grid footer
13 gridFoot = grid.getView().getFooterPanel(true);
14 //Reload the data using new size
15 grid.getDataSource().reload({params:{start:0,limit:newSize}});
16 //Redo the paging toolbar with the new size
17 var paging = new Ext.PagingToolbar(gridFoot,grid.getDataSource(),{
18 pageSize:newSize
19 }
20 );
21
22 //Reconfigure the grid to have the changes take effect
23 grid.reconfigure(grid.getDataSource(),cols);
24}
So, when the user clicks on a number, we use the YUI Dom's getElementsByClassName to get current anchor links with "selected" class. We then remove this clasee from that anchor link. We also get the new anchor link that was selected and add the "selected" class to it. We also have a hidden form variable called pages, where we store the new pagesize selected by the user (this will be used later on). Finally, CF8 uses the YUI Grid implementation, so looking into that, we first get the grid Footer. We also reload the Grid datastore pasing in a limit of the newly selected pagesize. This reloads the data with the new size but we also have to change the paging toolbar to reflect the new size, which is done next. In the end, we reconfigure the grid to reflect the changes.
Now, as such the code till now would implement user selected pagesizes. But the problem comes in when the user selection interacts with our grid filter. Since, we specified a pagesize of 5 when building the cfgrid, if the user uses the filter options ColdFusion loads the grid again with the pagesize of 5. To stop this, we modify the cfgrid code and the CFC a little bit.
2 bind="cfc:UsersB.getUsers({cfgridpage},{cfgridpagesize},{cfgridsortcolumn},{cfgridsortdirection},getPageSize(),{filtercolumn},{filter})">
3
4<cfgridcolumn name="FirstName" header="First Name">
5<cfgridcolumn name="LastName" header="Last Name">
6<cfgridcolumn name="UserName" header="User Name">
7<cfgridcolumn name="DisplayName" header="Display Name">
8<cfgridcolumn name="UserAccountingCode" header="GL Code (User)" display="false">
9<cfgridcolumn name="Phone" header="Phone No." display="false">
10
11</cfgrid>
To the cfgrid we added a new parameter to be passed in to the CFC, this parameter gets the pagesize from a hidden form variable (which we change in the changePage function) using the getPageSize() function.
2{
3 //Return the pagesize from the form variable
4 return document.getElementById('pages').value;
5}
Next, we modified our CFC function to handle this change.
2 <cfargument name="page" required="yes">
3 <cfargument name="pageSize" required="yes">
4 <cfargument name="gridsortcolumn" required="yes">
5 <cfargument name="gridsortdirection" required="yes">
6 <cfargument name="customPageSize" required="no" default="0">
7 <cfargument name="filtercolumn" required="no" default="">
8 <cfargument name="filter" required="no" default="">
9
10 <!--- If a custompagesize was passed in and it is greater than 0, use that otherwise use the default
11 page size specified in cfgrid tag --->
12 <cfif Val(Arguments.customPageSize) GT 0>
13 <cfset pageSizeToUse = Arguments.customPageSize>
14 <cfelse>
15 <cfset pageSizeToUse = Arguments.pageSize>
16 </cfif>
17
18 <cfquery name="selUsers" datasource="RIADemo">
19 SELECT
20 FirstName, LastName, DisplayName, UserName, UserAccountingCode, Phone
21 FROM
22 Users
23 <cfif Arguments.filtercolumn NEQ "" AND Arguments.filter NEQ "">
24 WHERE #Arguments.filtercolumn# LIKE '#Arguments.filter#%'
25 </cfif>
26
27 <cfif Arguments.gridsortcolumn NEQ "">
28 ORDER BY #Arguments.gridsortcolumn# #Arguments.gridsortdirection#
29 </cfif>
30 </cfquery>
31
32 <cfreturn queryconvertforgrid(selUsers,Arguments.page,pageSizeToUse)/>
33
34 </cffunction>
In the CFC, we added a new paramter called customPageSize, defaulted to 0 if it is not passed in. Then we check if the value of that parameter is greater than 0. If it is, we use that parameter as our pageSize otherwise we use the default specified in the cfgrid tag. Next we had to change the queryconverforgrid() call to use the pageSizeToUse variable.
What this does is, when the user selects a custom pagesize, the hidden form variable is changed to reflect this. So, when the grid is refreshed by ColdFusion, we pass in this hidden form value and use it as the pagesize instead of using the default specified.
#1 by Martin Franklin on 12/7/11 - 12:27 PM
var grid = ColdFusion.Grid.getGridObject('name of your grid');
var cols = grid.getColumnModel();
Also, I found I can to convert newSize var to integer using parseInt(newSize) otherwise page would return some weird numbers.
Thanks Kumar, nice work!