JDeveloper 11g R1: Advanced Multi Column Table Sort

A question on the JDeveloper and ADF Community Space found my attention. A user asked how to sort an af:table after more then one column.
Well, there is the official way, which Frank Nimphius’s bloged about in ‘Declarative multi-column sort for ADF bound tables’.
However this declarative approach needs the user to select the columns and their sort order. In most cases the sort after a second column is driven by the use case specification. A sample would be that the departments tables should normally be sorted after the column selected by the user, but then the data should always be sorted by the department name inside the first sort.
The image below shows the Departments table sorted first after the LocationId and inside the LocationId sorted by the DepartmentName.

Departments sorted after LocationID and DepartmentName

Departments sorted after LocationID and DepartmentName

Now lets see how to implement this. There are some possible solutions:

  1. add a sort criterion in a managed bean
  2. add a sort Criterion in the ViewObject
  3. a combination of 1) and 2)

All solutions have their advantages and disadvantages. Let’s start with the managed bean approach. This is pretty simple as we only need to add sortListener to the af:table which is pointing a bean method. In the sample below we are using the departments table where we wire up the secondary sort to the DepartmentName column.

<af:table value="#{bindings.DepartmentsView.collectionModel}" var="row" rows="#{bindings.DepartmentsView.rangeSize}"

And the sortTableListener in the bean

    public void sortTableListener(SortEvent sortEvent) {
        //log the selected column (just for information)
        List<SortCriterion> criteria = sortEvent.getSortCriteria();
        for (SortCriterion sc : criteria) {
            logger.info("Sort after: " + sc.getProperty());
        // Create new SortCriterion for DepartmentName in ascending order
        SortCriterion scNew = new SortCriterion("DepartmentName", true);
        // Add it to the list
        // and apply it back to the table
        Object object = sortEvent.getSource();
        RichTable table = (RichTable) object;

That’s all we need to do to get the output from the first image. You’ll notice, that both columns are showing the sort icon. Only the one for the DepartmentName can’t change to descending order as we wired things up to always sort in ascending order. From the users point of view this can be disturbing as it’s not obvious why this happens.

For the second solution we use the model layer instead of the view layer. Here we implement the ViewObjectImpl class of the EmployeesView and overwrite the setOrderByOrSortBy(…) method. This is the method the framework calls when you click on a header on the table to sort it.
Now we can hard wire the secondary sort column, as we did in the managed bean. However, let’s think about how to make this more flexible. A nice add on is that we can use the custom properties of each table attribute to define the secondary sort column. This way we can decide which columns to sort after for each of the attributes available. We can even decide to add more then one column for secondary and third sort.

The overwritten setOrderByOrSortBy method looks for the custom property named ‘SECONDARY_SORT’ and if found, creates a new SortCriterion with the column name give in the custom property. This new sort criterion is then added to the list of SortCriteria.

    public String setOrderByOrSortBy(SortCriteria[] sortCriteria) {
        SortCriteriaImpl scNew = null;
        // iterate current sort criteria
        for (int i = 0; i < sortCriteria.length; i++) {
            logger.info("Sort: " + sortCriteria[i].getAttributeName());
            // check for SECONDARY_SORT propertie on each attribute
            int attributeIndexOf = this.getAttributeIndexOf(sortCriteria[i].getAttributeName());
            AttributeDef attributeDef = this.getAttributeDef(attributeIndexOf);
            Object object = attributeDef.getProperty("SECONDARY_SORT");
            if (object != null) {
                logger.info("Secondary sort:" + object.toString());
                scNew = new SortCriteriaImpl(object.toString(), false);

        if (scNew != null) {
            // Create a new array for the added criteria
            SortCriteria scNewArray[] = new SortCriteria[sortCriteria.length + 1];
            for (int j = 0; j < sortCriteria.length; j++) {
                scNewArray[j] = sortCriteria[j];

            // add the new criteria
            scNewArray[sortCriteria.length] = scNew;
            //and exceute the search
            return super.setOrderByOrSortBy(scNewArray);
        return super.setOrderByOrSortBy(sortCriteria);

The image blow shows the result for the employees table which is first sorted after the ManagerId and then after the FirstName of the employee.

Sort after ManagerId and LastName

Sort after ManagerId and LastName

As you see, only the ManagerId column shows the sort icon. The secondary sort column, FirstName, doesn’t show the sort icon.

You can download the sample application, which uses the HR DB schema from the ADF-EMG ADF Samples Repository: BlogAdvancedTableSort.zip

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