Paging Using Next - Previous Through Records Displayed In A Flex DataGrid

This example is a simple demonstration of paging (previous - next) through data being displayed in a Flex datagrid. By default the datagrid will enable vertical scrolling to allow the user to view all the records in the datagrid's dataProvider. However, if you have a large number of records in the dataProvider, you may want to only show a subset of these records and enable a Next and Previous functionality.

You can view a Flex demonstration application here: /flex/pagingdatagrid/bin/PagingDataGrid.html (right click on the app to view the source code)

In this demonstration application, I am only showing 10 records at a time. There is a Previous and Next button that allow the user to see the next 10 records or if applicable the previous 10 records. The buttons are enabled only if it is appropriate (for example, there are previous records to show).

The key to being able to page through the records and have the datagrid only display the current page of records is to create two Arrays. The first array (named submissionsAllAry, see code below ) holds all the records returned from calling the CFC function. The second array (named submissionsSlicedAry) holds only a subset of the first array.


public function handleQueryResult(event:ResultEvent):void{
                
                //place the query results into an ArrayCollection
                submissionsAllAryCol = event.result as ArrayCollection;
                
                //convert ArrayCollection to a standard Array
                //so we can use Array slice function
                submissionsAllAry = submissionsAllAryCol.toArray();
                
                //how many total submissions?
                total = submissionsAllAry.length;
                
                //determine initial value for end (cannot exceed total)
                
                if ( total < increment) {
                    
                    end = total;
                    
                } else {
                    
                    end = increment ;
                    
                }//end if
                
                
                //take out of the array records start to end
                //(includes records from start to end-1)
                submissionsSlicedAry = submissionsAllAry.slice(start, end);
                
                //Create an ArrayCollection using the subset of our Array
                //and assign it to the data provider for the datagrid
                submissionsViewAryCol = new ArrayCollection( submissionsSlicedAry );
                
                //determine if Next button should be enabled
                //as its possible that the number of records returned
                //is less than our number per page (increment)
                nextBtn.enabled = isNextBtnEnabled();
                
                    
            } //end function


To create the subset array, I use the slice function of class Array (see: http://livedocs.macromedia.com/flex/2/langref/Array.html ). The slice function creates an array by "slicing out" those array elements specified by the start and end arguments.

I then use this second array (submissionsSlicedAry) to create the ArrayCollection object (submissionsViewAryCol) that is the dataProvider for the datagrid. Therefore all that is displayed in the datagrid are those records in the subset array (the records I've sliced out of the array that is holding all the records).

When the user clicks on the Next button function getNext is called. This function increases the start and end values, gets a new "slice" out of the array holding all the records, and recreates the ArrayCollection that is the datagrid's dataProvider.


private function getNext():void {
             
             //going forward so
             //increase start and end by the increment
             
             start = start + increment ;
             end = end + increment ;
             
             //don't let the value of end be larger than the
             //total number of records
             if (end >
total) {
                 
                 end = total;
                 
             }
             
             //create a new subset of the Array that is holding
                //all the submissions
             submissionsSlicedAry = submissionsAllAry.slice(start, end);
             
             //update the dataprovider for the datagrid
             submissionsViewAryCol = new ArrayCollection( submissionsSlicedAry );
             
             //determine if Next button should still be enabled
                
                nextBtn.enabled = isNextBtnEnabled();
                
                //enable previous button
                //since we have gone to a next page of records
                previousBtn.enabled = true;
             
             
         }//end getNext

When the user clicks on the Previous button, function getPrevious is called. This function works similar to the getNext function except moving the start and end values backwards.

This simple implementation has not been tested with very large datasets (thousands of records) and has not been tested with sorting and filtering of the datagrid.

For very large numbers of records you may want to investigate using Flex Data Services (FDS). I've not used FDS, but I understand from reading some other blogs, that paging large record sets is built into FDS.

Related Blog Entries

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
I have expanded on your flex paging to include page numbers and page set. Check it out on my blog. http://gurufaction.blogspot.com/
# Posted By Michael Ramirez | 11/30/06 2:02 PM
Michael:

Nice modifications.
# Posted By Bruce | 11/30/06 6:24 PM
What are the chances of seeing your cfc for this example? I'm stuck on trying to make the call to cfc to return data from a oracle database.
# Posted By Chris Tilley | 12/6/06 9:25 AM
Below is the CFC. I removed the real data source.

<cfcomponent name="SubmissionsGateway">

<cffunction name="getAllSubmissions" access="public" returntype="query">
      
      <cfargument name="confid" required="yes" type="numeric">
   
   
      <cfquery name="submissions" datasource="REMOVED">
      
         
         SELECT presenters.firstname+' '+presenters.lastname AS presenter, submissions.submissionid, submissions.pres_title as title
FROM (submissions INNER JOIN Submissions2Presenters ON submissions.SubmissionID = Submissions2Presenters.SubmissionID) INNER JOIN Presenters ON Submissions2Presenters.PresenterID = Presenters.PresenterID
WHERE ( ((submissions.Cancelled)=0) AND ((submissions.ConfID)=<cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#arguments.confid#">) AND ((Submissions2Presenters.MainPresenter)=-1))
ORDER BY submissions.SubmissionID
         
      
    </cfquery>
   
   
    <cfreturn submissions>
      
   </cffunction>

</cfcomponent>
# Posted By Bruce | 12/6/06 3:45 PM
In your example u applied paging using remote object & cold fusion!

How do i applying paging records using http service i.e for xml data?

Any ideas Bruce!
Thanks in Advance
# Posted By arthur | 5/1/07 6:53 AM
arthur - not sure how well this would scale, but you could try looping over your xml, create an object for each node, and add the object to an array. Then you can use the array slice function to get just the part of the array you want to show in the datagrid.
# Posted By Bruce | 5/1/07 4:23 PM
it's a great example, but when i add filter to data grid nothing display if it's not on that page. How can filter or sort all grid data not page.

Thank you
# Posted By Jason | 9/4/07 2:29 PM
Thank you Bruce Phillips. Your code was very help fullto me in page navigation. keep contributing in the blog.
# Posted By M Prasath | 8/12/08 11:58 PM
Thanks for this article. I've just finished adding paging capability to an AdvancedDataGrid using your technique. Thanks a bunch! You're a lifesaver.
# Posted By Alex C | 10/29/08 12:41 PM
One issue I've run into: If I set the variableRowHeight=true and try to scroll all the way down the page of records in an AdvancedDataGrid, it doesn't seem to want to show the last record. The scrollbar gets stuck a little before the bottom and refuses to proceed. Also, there seems to be an extra blank record displayed at the bottom. If I set the rowHeight, that takes care of the issue with the scrollbar but now makes the extra record even more apparent.

There's one solution out there (the "autosizingdatagrid") but I'd like to keep the scrollbars and have variable row height. Not sure how to do that.

Any thoughts? Thanks.
# Posted By Alex C | 11/5/08 5:05 PM
Found a solution to the previous problem: Removed the height attribute completely from the ADG and that fixed the scrollbar not going all the way down. This causes the screen size to change as you click Next/Previous; thus the background image for the app was resizing. Used the Degrafa package to fix the background issue.
# Posted By Alex C | 12/4/08 8:53 AM
BlogCFC was created by Raymond Camden. This blog is running version 5.9.1.002. Contact Blog Owner