Force secondary sort always ascending

Force secondary sort always ascending

nwallacenwallace Posts: 2Questions: 0Answers: 0
edited February 2013 in DataTables 1.9
Hi,

I've got a use case where I want to do a 2-column sort. I could use aDataSort, but the problem with that is that the sorting direction is the same for both columns (either asc or desc). I want the secondary sort to always be ascending, regardless of the primary sort direction.

Let's say I have a 2-column table -- Last Name (0), First Name (1). Both columns are sortable, but when I sort by Last Name, I also want to sort by First Name ascending.

I tried using fnSortListener and fnSort, but I had trouble with the sort direction.

First attempt: (see at this fiddle -- http://live.datatables.net/isitij/2/edit#preview)
[code]
$(document).ready(function() {
oTable = $('#myTable').dataTable();
oTable.fnSortListener($('#myTable th#lastName').get(0), 0, secondarySortListener);
} );

function secondarySortListener() {
// when table is sorted by vendor, also sort by product asc
var direction = oTable.fnSettings().aaSorting[0][1];
table.fnSort( [ [0,direction], [1,'asc'] ] );
}
[/code]

This doesn't work, as the example shows. So I wondered if the direction attribute should be its opposite, so I tried reversing the direction myself:
[code]direction == 'asc' ? direction = 'desc' : direction = 'asc';[/code]
Still no luck.

What is wrong with that code? Why doesn't it work?

I tried to do some tests on the behavior of aaSorting and it seems to me that aaSorting doesn't update the sort direction when you do fnSort.

I don't want to track the direction with some global variable, because that could lead to sorting descending first, but it needs to sort ascending first when you first click the column header.

Replies

  • nwallacenwallace Posts: 2Questions: 0Answers: 0
    edited February 2013
    Ok, I implemented a custom solution to this problem. I'm posting it here in case anyone stumbles across this in the future.

    Still, if there is a better way to accomplish this, please let me know!

    Motivation: my underlying problem with the solution described in the OP was that aaSorting wasn't returning the sort direction I needed it to. I'm still not sure what's going on with that variable, but my solution was to track the sorting direction myself in a global variable (nextSort). To make this behave properly, I had to add a listener to all other sorts on the table that would reset this global variable so that the first sort on the "last name" column would always be ascending, and subsequent sorts would toggle desc/asc.

    Simplified example code:
    [code]
    // stores the direction of the next sort on the vendor column in the table
    // begins as 'desc' because table is automatically pre-sorted asc by this column
    var nextSort = 'desc';

    $(document).ready(function() {

    // initialize table and set sort listener on Last Name column
    oTable = $('#myTable').dataTable();
    oTable.fnSortListener($('#myTable th#lastName').get(0), 0, secondarySortListener);

    // if table sorts by any other column, reset nextSort to ascending so that when user
    // tries to sort on Last Name, the first sort will always be ascending
    $('#myTable th.sorting, #myTable th.sorting_asc, #myTable th.sorting_desc').not('#lastName').click(function() {
    nextSort = 'asc';
    });
    } );

    // when table is sorted by vendor, also sort by product asc
    function secondarySortListener() {
    var direction = nextSort; // get direction for the sort
    nextSort == 'asc' ? nextSort = 'desc' : nextSort = 'asc'; // set nextSort to the opposite of current direction for next time
    table.fnSort( [ [0,direction], [1,'asc'] ] );
    }
    [/code]


    My actual code is more complex than this, because I had multiple columns I wanted to do the same subsort on -- no matter what column you're sorting on, my table would always subsort on 2 columns. For that, I made nextSort an array whose index matched the table column index.

    Here is that code, in case it helps anyone. My table has 6 columns. Columns indexed 2 & 5 (third and last columns) are not sortable. When table sorts by column 0, it should subsort by column 1. When table sorts by column 1, no subsort required. When table sorts by columns 3 or 4, it should subsort by column 0 then column 1. Also, column 4 should sort descending first, then ascending -- that's why it's initialization value in nextSort is 'desc' instead of 'asc'.
    [code]
    var table;

    $(document).ready(function() {
    table = $('#productsTable').dataTable({
    "aoColumnDefs": [
    { "bSortable": false, "aTargets": [2,5] },
    ]
    });
    });

    // set up table subsorts listeners!
    $('#productsTable th.sorting, #productsTable th.sorting_asc, #productsTable th.sorting_desc').click(function() {
    var i = $(this).index();
    var direction, nextSortAtI;
    if (nextSort[i] == 'asc') {
    direction = 'asc';
    nextSortAtI = 'desc';
    } else if (nextSort[i] == 'desc') {
    direction = 'desc';
    nextSortAtI = 'asc';
    }
    // reset original soring directions
    nextSort = ['asc','asc',null,'asc','desc',null];
    nextSort[i] = nextSortAtI;
    if (i == 0) {
    table.fnSort( [ [0,direction], [1,'asc'] ] );
    } else if (i == 3 || i == 4) {
    // subsort by vendor/product
    table.fnSort( [ [i,direction], [0,'asc'], [1,'asc'] ] );
    }
    // strip away secondary sort classes to avoid confusing display
    $(this).siblings().filter('.sorting_asc, .sorting_desc').removeClass('sorting_asc sorting_desc').addClass('sorting');
    });
    [/code]
  • allanallan Posts: 61,814Questions: 1Answers: 10,123 Site admin
    I think the way I'd approach this myself is to detect the DataTables sort listener and then attach my own that calls fnSort - i.e. do not use fnSortListener.

    However it is a good point, this is something that DataTables should perhaps provide options for internally.

    Allan
This discussion has been closed.