Dojo Data Grid – Part 7: Sorting

The Dojo Data Grid does its best to provide sorting options by default. Strangely enough, it takes more work to prevent sorting! This post will cover how to allow the grid to sort columns and how to prevent sorting of some columns or directions.

Dojo Data Grid Series

Default Sorting Features

When you surface a grid, it automatically attempts to provide the ability to sort any column ascending or descending. When you click on a column header, it displays a triangle pointing upward and attempts to sort that column in ascending order. When you click the column header again, it displays a triangle pointing downward and attempts to sort that column in descending order.

On every click, the data disappears and the grid is refreshed. But nothing happens on many of the column clicks!

This is because each sorting option can only work if the underlying view column already has that sort option (and, therefore, the view has an index to support that sorting option).

The sort options are provided on the Click on column header to sort properties of the underlying view columns:
Grid7_1

If your underlying view already has every column set to allow both sorting directions, then you can leave it as is and it will work like a charm.

However, if your view does not have those options set — and it is valid not to have that set because every potential sorting option requires the view to maintain another index — then you can disable sorting options with a little bit of client-side JavaScript coding.

It’s worth the effort to prevent the confusion of users seeing arrows and grid refreshes, but not seeing any difference in the data.

Preventing Specific Sorting Options

The dojo data grid has an attribue named canSort which defines a function that is called when the user clicks on a column header. It accepts a number, which is the index of the column, and returns true or false, based on whether the sorting option is allowed.

It is a one-based index (meaning, the first column is 1, the second column is 2, and so on).

The other important thing to note is that the function will be called with a positive number if an ascending sort is requested and a negative number of a descending sort is requested. So, the function will receive a 1 if it is attempting to sort the first column in ascending order, but it will receive -1 if it is attempting to sort the first column in descending order.

Attaching the canSort function

You can use dojo to attach the function to the canSort attribute of the grid and pass it a function that will return true or false.

The function will automatically receive a single parameter with the column index. The name of the parameter does not matter.

Run the code in the onClientLoad event of the page or custom control containing the grid.

Examples

This function will prevent column 3 from being sortable. The Math.abs() function is used to return the absolute value of the index passed in, meaning it will return a positive number regardless of whether the index passed in is positive (ascending sort) or negative (descending sort):

dijit.byId('#{id:djxDataGrid1}').canSort = function(col){
  if(Math.abs(col) == 3) {
    return false;
  } else {
    return true;
  }
};

This function will prevent all column sorting:

dijit.byId('#{id:djxDataGrid1}').canSort = function(col){
  return false;
};

This function will prevent all descending sorting:

dijit.byId('#{id:djxDataGrid1}').canSort = function(col){
  if (col < 0) {
    return false;
  } else {
    return true;
  }
};

This function will only allow even numbered columns to be sorted:

dijit.byId('#{id:djxDataGrid1}').canSort = function(col){
  if (col % 2 == 0) {
    return true;
  } else {
    return false;
  }
};

Caveat with Column Reordering

This logic is all based on the column index. However, if you allow users to reorder the columns in the grid, you may have unexpected results with the canSort logic.

For example, if my canSort function prevents sorting column 3, but I move that column ahead of the second column, then I’ll be able to try to sort the column, since it’s at a different position, and I’ll lose the sorting option for column 2, because it is now column 3.

This isn’t going to cause any errors, but there is the potential for confusion, so keep that in mind.

Sorting Compared to ExtJS

It’s interesting to note the difference in how sorting works in ExtJS, which described in this post by Mark Roden.

In the Dojo Data Grid, all sorting is done remotely, unlike ExtJS, where it has the built-in feature to sort the current page of data locally (i.e. without requiring a call to the REST service). The Dojo Data Grid doesn’t do any paging, so it does a full sort on the data every time. The advantage is that the results are always what the user expects, but the disadvantage is that it requires a server round trip and a refresh of the grid.

Advertisements

10 responses to “Dojo Data Grid – Part 7: Sorting”

  1. Alan Hurt says :

    Dojo grid can sort locally, so is it an XPages thing ( I would assume that to be the case ) that does all sorting remotely

  2. Pantelis Botsas says :

    Hi Brad, you told something about a caveat on reordering the columns.

    I noticed that it is possible to manipulate the *canSort* attribute by using the given field name given in the structure (layout) definition of the grid.

    Using this detour you can have this function

    {YourGrid}.canSort = function(col) {
    if(({YourGrid}.getCellByField(“field1”).layoutIndex+1) == Math.abs(col)) { return false; }
    return true;
    }

    helping you to define the sorting restrictions.

    Hope this can help other also.

    Pantelis

  3. Steve Zavocki says :

    Brad, love the series and the service you provide to the Notes community. I am using the dojo grid on a page where the grid is initially hidden, and then shown when the users checks a checkbox. Only then can users add values to the grid using a button.

    I wanted to disable the column sorting, and I couldn’t use your example. It only worked if the page was refreshed manually. Firebug would say that dijit.byId(‘#{id:djxDataGrid1}’).canSort was undefined. It took me a long time to figure out but the fix is to put djxDataGrid1.canSort = function(col){return false;} in the onFocus event in the All Properties.

    The first way works only if the grid is rendered on page load. I have no idea why the reference in the DOM changes when the grid is rendered via a partial refresh. It appears like the grid becomes a sibling of the dijit object, and not a child of it as when it loads. Strange, but I am relieved I figured it out, as I hate that column sorting.

    • Brad Balassaitis says :

      Thank you very much!

      The examples are all set up with code on the onClientLoad event of the page, so, you’re right, that it will only render the grid when the page loads. If you need it to work on a partial refresh, you could put the code on the onClientLoad event of a panel that is the target of a partial refresh and it should work there.

  4. Nachiket says :

    Hey Brad thanks for the great help that you have provided to the Notes community via this blog. I am trying to implement sorting in a data grid, but the default sort option does not seem to work on a grid with is already filtered on load. I am displaying filtered documents in the data grid based on the current user who has logged in and I am using the key property to filter the view results. I made the back-end view columns sortable both ways but when I try to sort the view displayed in the data-grid it does not sort when I click on the column header and displays a blank result. Could you please help me out i you have any solution for the same.

  5. Nachiket says :

    Just to add to it I tried the sorting after removing the filter and it works like a charm. How can I make it work with the filter on.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: