Custom sort function not called when sorting multiple columns

Custom sort function not called when sorting multiple columns

xabierxabier Posts: 11Questions: 0Answers: 0
edited January 2011 in General
Hello all,

First of all a huge thank you to Allan for the brilliant work he's done with datatables and of course, for giving it for free to the opensource community.

Now the question, I've added a type detection function and the corresponding sorting functions for the the type and that's working great, but when I sort by two columns of that custom type the sort function is called for the first column but not for the second. Is this a known bug? maybe there is something wrong with my sort functions? and if so which ways are there to check it?.

Thanks a lot,

Xabier Burgos.

Replies

  • allanallan Posts: 63,208Questions: 1Answers: 10,415 Site admin
    Hi Xabier,

    It seems to work as expected on this example: http://datatables.net/examples/plug-ins/sorting_sType.html and the unit tests which check this are also passing. So I'm not 100% sure what would be going wrong Perhaps you can give us a link to show us an example?

    Thanks,
    Allan
  • xabierxabier Posts: 11Questions: 0Answers: 0
    edited January 2011
    Hi Allan,

    But in that example you only have one column that's using the custom sorter, like I said, that's working properly, my problem comes only when I sort by 2 columns of that same custom type. The sort function seems to be called when I click on the first column but not after pressing SHIFT and clicking on the second one.

    Thanks,

    Xabier Burgos.
  • allanallan Posts: 63,208Questions: 1Answers: 10,415 Site admin
    Hi Xabier,

    I've just tried the following table modified from my example and again it seems to work as expected for me with sorting on the custom plug-in for two columns.

    [code]



    Rendering engine
    Browser
    Platform(s)
    Engine version
    Engine version
    CSS grade




    Trident
    Internet
    Explorer 4.0
    Win 95+
    4
    4
    X


    Trident
    Internet
    Explorer 5.0
    Win 95+
    4
    5
    C


    Trident
    Internet
    Explorer 5.5
    Win 95+
    4,5
    5,5
    A


    Trident
    Internet
    Explorer 6
    Win 98+
    4,5
    4,5
    A



    [/code]
    Allan
  • xabierxabier Posts: 11Questions: 0Answers: 0
    edited January 2011
    Hi Allan,

    This is a very reduced (it has about 200 rows and a few more columns) version of my table:
    [code]



    FTSE Top 200 - Stock Details

    [Highlights]


    List Format:

    Stock Details
    Beta and Risk
    Support/Resistance
    Short Term Trading
    Trend Summary
    Moving Averages
    Ratios






    Ticker
    LT Rel
    RSI 56
    ST Score
    LT Score
    All




    HOC LN Equity
    ?
    35
    88
    87.84
    88


    FRES LN Equity
    ?
    38
    88
    87.84
    88


    RRS LN Equity
    ?
    56
    -42
    87.84
    54


    RIO LN Equity
    ?
    40
    88
    87.84
    88


    CNE LN Equity
    ?
    53
    -73
    87.84
    46



    [/code]
  • xabierxabier Posts: 11Questions: 0Answers: 0
    And my custom sorter:

    [code]
    /**
    * ====Number sort plugin for datatable===
    * This plugin first adds automatic type detection
    * for the number type and then provides the sorting
    * functions for both ascending and descending sorting.
    * Please note that you must include this file
    * after the inclusion of jQuery and datatable plugins
    * but before the initialization of datatable.
    * @author Xabier Burgos.
    */

    // Add number type detection
    jQuery.fn.dataTableExt.aTypes.unshift(
    function ( sData ){
    if(sData.indexOf("class=\"number") != -1) {
    return 'realnumber';
    }
    return null;
    }
    );
    // Add sort function for number type. Automatic detection will to the rest.
    jQuery.fn.dataTableExt.oSort['realnumber-asc'] = function(a,b) {
    a = $(a); //jQuery-fy (jquery is going to create an html element from the string)
    b = $(b); //jQuery-fy (jquery is going to create an html element from the string)

    var x = parseInt(stringBefore(':', a.attr("title")),10);
    var y = parseInt(stringBefore(':', b.attr("title")),10);

    if( (isNaN(x) && isNaN(y)) || (x == y)) {
    var x = stringAfter(':', a.attr("title").toLowerCase());
    var y = stringAfter(':', b.attr("title").toLowerCase());
    return x < y ? -1 : (x > y ? 1 : 0); // Sorting always ascending
    }

    if(isNaN(x)) return -1;
    if(isNaN(y)) return 1;

    return x < y ? -1 : (x > y ? 1 : 0);
    };

    jQuery.fn.dataTableExt.oSort['realnumber-desc'] = function(a,b) {
    a = $(a); //jQuery-fy (jquery is going to create an html element from the string)
    b = $(b); //jQuery-fy (jquery is going to create an html element from the string)

    var x = parseInt(stringBefore(':', a.attr("title")), 10);
    var y = parseInt(stringBefore(':', b.attr("title")), 10);

    if( (isNaN(x) && isNaN(y)) || (x == y)) {
    var x = stringAfter(':', a.attr("title").toLowerCase());
    var y = stringAfter(':', b.attr("title").toLowerCase());
    return x < y ? -1 : (x > y ? 1 : 0); // Sorting always ascending
    }

    if(isNaN(x)) return 1;
    if(isNaN(y)) return -1;

    return x < y ? 1 : (x > y ? -1 : 0);
    };
    [/code]
  • allanallan Posts: 63,208Questions: 1Answers: 10,415 Site admin
    I'm getting a Javascript error about the (global?) variable 'stringBefore' if I try the above.

    Allan
  • xabierxabier Posts: 11Questions: 0Answers: 0
    edited January 2011
    Yes, sorry about that, It's all part of a bigger project and I sometimes forget I've defined functions elsewhere. Please add the following functions before the plugin.

    [code]
    function stringAfter(char, string) {
    var index = string.indexOf(char);
    return string.substring(index + 1);
    }

    function stringBefore(char, string) {
    var index = string.indexOf(char);
    return string.substring(0, index);
    }
    [/code]

    Also this is the intialization parameters I'm suplying to datatables:

    [code]
    // Initialize datatables
    var oTable = $("#stocklist").dataTable({
    "bJQueryUI": false, // Use JQuery UI themes
    "bStateSave":true, // Save the state of the table in a cookie.
    "bLengthChange":false, // Allow changing the number of records displayed.
    "bPaginate":false, // Paginate table.
    "aaSorting":[], // Intial sorting columns (empty array for no default sorting).
    "sDom":'<"left"f><"right"T><"clear">'//Table tools for xls/csv export
    });
    [/code]
  • allanallan Posts: 63,208Questions: 1Answers: 10,415 Site admin
    I think there is a small error in your sorting function. If you change it to:

    [code]
    jQuery.fn.dataTableExt.oSort['realnumber-asc'] = function(a,b) {
    a = $(a); //jQuery-fy (jquery is going to create an html element from the string)
    b = $(b); //jQuery-fy (jquery is going to create an html element from the string)

    var x = parseInt(stringBefore(':', a.attr("title")),10);
    var y = parseInt(stringBefore(':', b.attr("title")),10);

    if( (isNaN(x) && isNaN(y)) || (x == y)) {
    var x = stringAfter(':', a.attr("title").toLowerCase());
    var y = stringAfter(':', b.attr("title").toLowerCase());
    var z = x < y ? -1 : (x > y ? 1 : 0);
    console.log( 'asc', x, y, z );
    return x < y ? -1 : (x > y ? 1 : 0); // Sorting always ascending
    }

    if(isNaN(x)) return -1;
    if(isNaN(y)) return 1;

    return x < y ? -1 : (x > y ? 1 : 0);
    };
    [/code]
    then on the console you can see that z, the returned value, is not equal to 0 when the numbers in the column match, which I would have expected so that the second sorting column would be called. Unless the return value is 0, then the sort assumes that the value is not equal and that the correct adjustment has been given.

    Allan
  • xabierxabier Posts: 11Questions: 0Answers: 0
    edited January 2011
    Thanks a lot Allan you've nailed it, the issue is that in our case even though we do the sorting client side (thanks to datatables), after you click on one of the rows in the table, you get to another page displaying some more details about the stock (each row represents a stock), in that page we also have prev/next buttons to allow a user to page through the stocks in the table and of course, that paging must follow the same order the rows had in the table.

    The problem is that the paging in those pages is performed by the database, so we must match the sorting Datatables does with the sorting the database performs; in order to perform that matching I modified my sort functions so that whenever 2 records match, a third column (in this case the first one) is used, therefore the "stringBefore,stringAfter" functions; so I was wondering whether there is a way for the custom sorting functions to know if a second column is being used to sort or my only option now is to resort to serverside sorting for datatables too.

    Thanks a lot,

    Xabier Burgos.
  • xabierxabier Posts: 11Questions: 0Answers: 0
    Hello Allan,

    Hmm, I think I didn't explain it very weel, what we need is to have an 'always sort by column 'x' last' option, no matter what other sort column or columns people have chosen. Is that possible?

    Thanks,

    Xabier.
  • allanallan Posts: 63,208Questions: 1Answers: 10,415 Site admin
    DataTables doesn't have an "always sort by column 'x' last" option I'm afraid - there is an option for "always sort by column 'x' first", but that's not much use to you... If your server is already doing this, is server-side processing an option? Failing that, then I'd suggest a small hack to the _fnSort function in DataTables - just concat your fixed sorting array to the end of the one DataTables uses.

    Allan
  • xabierxabier Posts: 11Questions: 0Answers: 0
    Right, I guess serverside processing will be the way to go, I don't like hacking around unless there is no other option when it comes to work stuff.

    Thanks a lot for your help and your time,

    Xabier.

    P.S: Just how many hours a day do you spend answering forum questions?
  • allanallan Posts: 63,208Questions: 1Answers: 10,415 Site admin
    I hate to think :-). Good debugging and programming practice though! Also the best way to improve DataTables I think - see how it is actually being used and where it can be improved.

    I'll bare in mind an option in future to post sort columns - added to the feature list to think about :-)

    Regards,
    Allan
This discussion has been closed.