In the last post, we saw how to add a feature module to Gridx, using the simple example of resizing columns. In this post, I’ll show how to add column sorting with a grid using a remote data source.
Gridx Series
Gridx in XPages — Entire Series
SingleSort
The SingleSort
module provides the ability to click on column headers and sort the data. The first click on a column header sorts the data ascending and the second click sorts descending.
Sort of. (See what I did there?)
If the data source is remote — which has been the case in our examples using the JsonRest
data store to read live data remotely from a REST service — then the sorting is left up to the server. Just enabling column sorting on the view underlying our data isn’t sufficient — the REST service is responsible for returning the data in the proper order.
Without this, each click on a column header will execute a request to the server to retrieve the data — but it will come back in the same order in which it started. Even worse, the column header will display an arrow indicating the direction that it expects that the data is sorted.
The Sort Request
Watching the Net panel in the browser’s developer tools, I can see that a click on a column header generates a GET
request to the REST service, adding a query string like this: ?sort(+lastname)
. This indicates that it is requesting that the data be sorted ascending by lastname. There is a minus sign (-) in place of the plus sign (+) when it is requesting a descending sort.
Sorting the REST Service
Fortunately, the REST service has two properties that we can compute in order to support this functionality (under basics > service > ): sortColumn
and sortOrder
The sortColumn
property can be computed to read the column name out of the query string. The value sent will be the programmatic column name, so it will correspond to a column in the view that’s providing the data to the REST service. (If you’re not using a view to provide the data, then you’ll need to provide your own sort routine in the code.)
This code will compute the column name by parsing it out of the URL:
var sortColumn = ''; var qs = context.getUrl().getQueryString(); if (qs.indexOf('sort') > -1) { // Set the starting point based on where it finds 'sort', then add 4 for those letters, then 2 more for the open parenthesis and the plus or minus sign var start = qs.indexOf('sort') + 6; var end = qs.indexOf(')', start); var sortColumn = qs.substring(start, end); } return sortColumn;
Similarly, the sortOrder
property can read the sign out of the query string and return ‘ascending’ or ‘descending’ as needed.
var sortDirection = ''; var qs = context.getUrl().getQueryString(); if (qs.indexOf('sort') > -1) { // Set the starting point based on where it finds 'sort', then add 4 for those letters, then 1 more for the open parenthesis var start = qs.indexOf('sort') + 5; var sortSign = qs.substr(start, 1); sortDirection = (sortSign == '-') ? 'descending' : 'ascending'; } return sortDirection;
Interestingly, the plus sign (+) is not returned as part of the query string. I assume that it’s treated as a placeholder for a space as it does when encoding a URL. Fortunately, the minus sign (-) remains, so we can just check for that and otherwise assume ascending.
Important – The View Must Support the Sort
The underlying view must support column sorting in each direction for this to work. You can set the properties of each column in the view that needs to provide sorting via the Click on column header to sort
property. This will cause the view to include an index for one or both sort directions for that column.
Updated Grid Code
The updates to the REST service required much more effort than the updates required for the grid itself. All we have to do is include the SingleSort
module and add it to the grid object.
Here’s the updated module loading snippet:
require([ "gridx/Grid", "gridx/modules/ColumnResizer", "gridx/modules/SingleSort", "dojo/store/JsonRest", "gridx/core/model/cache/Async", "dojo/domReady!" ], function(Grid, Resizer, SingleSort, JsonRest, Cache) {
It’s the same as the last time, with the exception of the new line 4, which includes the SingleSort
module.
Here’s the updated Grid object. The only part that changed is including the SingleSort
module in the modules
array (line 8).
grid = new Grid({ id: "my_gridX", cacheClass: Cache, store: store, structure: columns, modules: [ Resizer, SingleSort ] });
Once we’ve done this, we have a grid that can be sorted.
