Manual sorting using a hidden column

Manual sorting using a hidden column

rf1234rf1234 Posts: 2,991Questions: 87Answers: 421
edited January 2022 in DataTables 1.10

I have a column my users want to sort by that doesn't contain values that are reasonably sortable. The sort order the users want to achieve is rather psycho-logical than logical.

I built a solution that allows the user to click on the sorting symbols in the column header. Subsequently the table is sorted by using values from a hidden column. For the user it feels like the table was sorted using the values from the column she clicked on.

I could only achieve this messing around with jQuery which I don't like. I didn't find anything suitable in the API. Question: Is there anything usable for this purpose in the API?

This is my solution:
The user sees open tasks and can order the contracts by the earliest task due date a contract has. If the contract has several tasks with several due dates the following due dates of that contract are being ignored for sorting.

This is what it looks like. Contracts with at least one overdue task are red.

The column is "Offene Aufgaben" the sorting symbol is "fake" if you will. If the user clicks on it the table is sorted by a hidden column.

HTML: the "Offene Aufgaben" column and the hidden column are marked in yellow.

Column "Weitere Ereignisse" is renamed to "Offene Aufgaben" later - so don't be confused ...

And here is the javascript code. (The data table is used on multiple pages in different configurations. We are on "inboxTasksPage" here. The ids to look for are "furtherEventsCol" and "minTaskDueDate". "furtherEventsCol" Column has "orderable: false" set.

//has to be set on top of the code because the columns will be hidden - then the jquery
//command does not work any longer!
var ixOrder; var descAsc;
if ( inboxTasksPage ) {
    ixOrder = $('#minTaskDueDate').index();
    descAsc = 'asc';
} else {
    ixOrder = $('#updateTime').index();
    descAsc = 'desc';
} 
......
if ( inboxTasksPage ) {
    //first click on OpenTasks causes descending order because the initial order
    //is by OpenTasks (furtherEventsCol) ascending
    var clickCounter = 0;
    //table was ordered initially by column #minTaskDueDate which contains the
    //minimum due dates of each contract with open tasks
    $('#tblCtrManagement').on( 'click', 'th:not(#furtherEventsCol)', function () {        
        clickCounter = 1; //next click on OpenTasks will cause ascending order
        $('th#furtherEventsCol').addClass('sorting');
        $('th#furtherEventsCol').removeClass('sorting_asc sorting_desc');
    } );
    $('#tblCtrManagement').on( 'click', 'th#furtherEventsCol', function () { 
        clickCounter++;
        $('th#furtherEventsCol').removeClass('sorting sorting_asc sorting_desc');
        if ( clickCounter % 2 == 0 ) { //even click number
            ctrTable.order([ ixOrder, 'asc' ]).draw();
            $('th#furtherEventsCol').addClass('sorting_asc');
        } else { //odd click number
            ctrTable.order([ ixOrder, 'desc' ]).draw();
            $('th#furtherEventsCol').addClass('sorting_desc');
        }
    } );
}

Replies

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    I have a column my users want to sort by that doesn't contain values that are reasonably sortable.

    Haha! Tell your users that they are being unreasonable then ;-)

    Thanks for the description. It sounds like you want the columns.orderData option. With that you can have a hidden column and tell DataTables to sort by a different (in this case hidden) column.

    An alternative is to use orthogonal data whereby your rendering function (or data object) returns different data for sorting and type detection that it does for display.

    If you already have the data in a hidden column though, then option 1 is easier.

    Allan

  • rf1234rf1234 Posts: 2,991Questions: 87Answers: 421

    Thanks Allan!

    I had seen columns.orderData but didn't get that I could use it for my purpose. It would be great to have a usage example for columns.orderData! (Would help people like me to understand what it is good for ...)

    Roland

  • rf1234rf1234 Posts: 2,991Questions: 87Answers: 421

    Ok, got rid of my custom jQuery and use the API now:

    //has to be set here because the update timme column will be hidden then the jquery
    //command does not work any longer
    var ixFurtherEventsCol  = $('#furtherEventsCol').index();
    var ixMinTaskDueDate    = $('#minTaskDueDate').index();
    .....
    
    columnDefs: [
       // targets may be classes
        {   targets: ixFurtherEventsCol, orderData: ixMinTaskDueDate }
    ],
    
  • tangerinetangerine Posts: 3,365Questions: 39Answers: 395
    edited January 2022

    Roland, here's an example from my own code:

     
                // Sort column 2 (title_for_display) using data from column 3 (title_body).
                {
                    data: "Songs.title_for_display" ,
                    orderData: [3]
                },
                {
                    data: "Songs.title_body",
                    visible: false,
                    searchable: false
                },
    
  • rf1234rf1234 Posts: 2,991Questions: 87Answers: 421

    Thanks, tangerine. Eventually I figured it out using column defs. The description in the docs is clear as well ... Must have overlooked it. Examples help in any case!

    I am trying to avoid hard coded column numbers though. That caused lots of problems for me when changing large and complex data tables: I always forgot to change those hard coded numbers and decided to get rid of them. I either use classes in columnDefs or save the index of a column by its ID using jQuery on top of my code (i.e. before hiding columns etc.) (see above).

Sign In or Register to comment.