Paginated DataGrid with Sorting

April 4th, 2009 by Unknown Morphician

In a recent project we built a DataGrid that showed paginated data from a web service. That itself was pretty straight-forward. It eventually required sorting. And of course the sorting feature with DataGrid would only sort the data within a single page when we wanted the sorting to be applied to the entire data set. So now what? To avoid writing a new DataGrid from scratch, I reread the docs and then dug into the source code ... something I find myself doing all the time. I found that the solution involved listening for and canceling an event and using 2 mx_internal variables.

To demonstrate the paginated sorting, I wrote up the following example that uses hard-coded data:
PaginatedDataGridExample
Source View

Click on the column headers to sort the data and see that the sorting is applied across the entire data set.

Pagination

The PaginatedDataGrid class uses the entireDataProvider property as input to contain the entire data set. The normal dataProvider property represents the data for each page. The bulk of the work is done by the populatePage() method:

protected function populatePage(pageNum:int):void {
	if (_entireDataProvider == null) {
		return;
	}
	var start:int = pageNum * pageSize;
	var end:int = start + pageSize;
	end = Math.min(_entireCollection.length, end);
	_pageDataProvider.splice(0);
	for (var i:int = start; i < end; i++) {
		_pageDataProvider.push(_entireCollection.getItemAt(i));
	}
	super.dataProvider = _pageDataProvider;
	// apply sorting that was lost due to dataProvider change
	if (_savedSortDirection != null) {
		sortIndex = _savedSortIndex;
		sortDirection = _savedSortDirection;
	}
}

The properties page, pageCount, isFirstPage, and isLastPage are used by the application to navigate the PaginatedDataGrid:

 

Sorting

We know from the Flex docs that the DataGrid dispatches the DataGridEvent.HEADER_RELEASE event. This event is dispatched by the mouseUpHandler() method in DataGridHeader and the event is cancelable. The PaginatedDataGrid listens for this event and handles it with the following method:

protected function headerReleaseHandler(event:DataGridEvent):void {
	event.preventDefault();
	sortByColumn(event.columnIndex);
}

The sortByColumn() method was largely copied from the sortByColumn() method from DataGrid. It determines how to sort and applies the sort information. It uses mx_internal properties so we had to import and use that namespace:

import mx.events.DataGridEvent;
use namespace mx_internal;

The significant modifications to sortByColumn() are in the following lines:

// save sort information to be applied when dataProvider changes
_savedSortIndex = sortIndex;
_savedSortDirection = sortDirection;
 _entireCollection.sort = s;
 _entireCollection.refresh();
populatePage(page);

Note that the sort is applied to _entireCollection which is an ArrayCollection and whose source data is entireDataProvider. The current page is then repopulated with the newly sorted data.

What if I'm using web services?

If you want to modify PaginatedDataGrid to work with web services, you will not need a good chunk of the code starting with entireDataProvider. I would start by editing the page setter function which is the entry point of data population. If you're using sorting, you'll have to grab that data from sortIndex/sortDirection and pass them as parameters to the service (reformatted as necessary). If the feature requires additional filtering then you would create methods to set that information and then pass it along when requesting data for a page. This is a bit abstract I know. If you're comfortable with web services, then with this example you should have all the tools you'll need.

Final Thoughts

The more I read Flex source, the more I cry. Just kidding. I'm actually happy to find that between protected and mx_internal properties and methods, I'm able to customize (and fix) the code for my specific requirements.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • DZone
  • Fark
  • LinkedIn
  • Live
  • Reddit
  • Slashdot
  • StumbleUpon
  • Technorati
  • Twitter
  • Yahoo! Bookmarks
  • RSS
  • email

2 Responses to “Paginated DataGrid with Sorting”

  1. Rajesh says:

    Hi, Thanks for your work SAM.
    I’ve an issue with your datagrid, i’m unable to bind the Arraycollection with the datagrid component. Can you advise me in this regard.

    Thanks
    Rajesh

  2. Chinmoy says:

    I’m trying to modify the code to use it with an “Advance Data Grid “. But I’m getting an error like “Overriding a function that is not marked for override. protected function headerReleaseHandler(event:AdvancedDataGridEvent):void” . Can you tell me whether it is possible to overwrite AdvanceDataGridEvent.HEADER_RELEASE .Is there any other cause for the error? Waiting for ur reply.

Leave a Reply