Setting sortable with aoColumnDefs glitched

Setting sortable with aoColumnDefs glitched

TiaxTiax Posts: 12Questions: 0Answers: 0
edited November 2012 in Bug reports
Is it me, or the issue discussed here has returned (I'm using 1.9.4)? http://datatables.net/forums/discussion/5472/sort-classes-not-getting-reset-after-disabling-and-enabling-with-aocolumndefs-bug-plus-patch/p1

Summary:
- disabling sorting on all columns with matching aoColumnDefs on "_all"
- enabling it on the ones with matching on a css class, e.g. "sortable"

Script:
[code]
$(function () {
var oOptions = {
aoColumnDefs: [
{ aTargets: [ 'searchable' ], bSearchable: true },
{ aTargets: [ 'sortable' ], bSortable: true },
{ aTargets: [ '_all' ], bSortable: false, bSearchable: false }
]
};

$('#table').dataTable(oOptions);
});
[/code]

Markup:
[code]


Header 1
Header 2
Header 3
Header 4


[/code]

This does result in the expected columns correctly being sortable and not sortable with the click events. However, all columns get assigned the wrong css class "sorting_disabled".

Edit: moved it to "Bug reports"

Replies

  • TiaxTiax Posts: 12Questions: 0Answers: 0
    edited November 2012
    made a jsbin: http://live.datatables.net/azijaw/3
    The wrong sorting classes are added to the header cells and searching just doesn't get applied at all...
  • TiaxTiax Posts: 12Questions: 0Answers: 0
    edited November 2012
    I took a more indepth look into the source of this problem and the applying of the css classes kind of surprised me:

    [code]/* Check that the class assignment is correct for sorting */
    if ( !oCol.bSortable ||
    ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) )
    {
    oCol.sSortingClass = oSettings.oClasses.sSortableNone;
    oCol.sSortingClassJUI = "";
    }
    else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1 )
    {
    oCol.sSortingClass = oSettings.oClasses.sSortable;
    oCol.sSortingClassJUI = oSettings.oClasses.sSortJUI;
    }
    else if ( $.inArray('asc', oCol.asSorting) != -1 && $.inArray('desc', oCol.asSorting) == -1 )
    {
    oCol.sSortingClass = oSettings.oClasses.sSortableAsc;
    oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIAscAllowed;
    }
    else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) != -1 )
    {
    oCol.sSortingClass = oSettings.oClasses.sSortableDesc;
    oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIDescAllowed;
    }[/code]

    oCol is the column the classes are currently edited on,
    oCol.bSortable is the sorting flag (which is overriden, if sorting is disabled in the table's option),
    oCol.asSorting is the applicable sorting directions for this column (http://www.datatables.net/usage/columns#asSorting)

    I changed it to this (the first else if is inverted) and added comments to the conditional branches, explaining them the way I understand it should be.

    [code]/* Check that the class assignment is correct for sorting */
    if ( !oCol.bSortable ||
    ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) )
    {
    // either sorting is disabled for this column or neither 'asc' nor 'desc' is in the array
    oCol.sSortingClass = oSettings.oClasses.sSortableNone;
    oCol.sSortingClassJUI = "";
    }
    else if ( $.inArray('asc', oCol.asSorting) != -1 && $.inArray('desc', oCol.asSorting) != -1 )
    {
    // both, 'asc' and 'desc' are in the array, so it can be sorted both directions
    oCol.sSortingClass = oSettings.oClasses.sSortable;
    oCol.sSortingClassJUI = oSettings.oClasses.sSortJUI;
    }
    else if ( $.inArray('asc', oCol.asSorting) != -1 && $.inArray('desc', oCol.asSorting) == -1 )
    {
    // 'asc' is in the array, while 'desc' is not, so the column can only be sorted ascending
    oCol.sSortingClass = oSettings.oClasses.sSortableAsc;
    oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIAscAllowed;
    }
    else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) != -1 )
    {
    // 'asc' is not in the array, while 'desc' is, so the column can only be sorted descending
    oCol.sSortingClass = oSettings.oClasses.sSortableDesc;
    oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIDescAllowed;
    }[/code]

    and now it's working as I intended.

    Am I getting the whole sorting handler/class assignments wrong or is it just been wrong all this time?

    P.S.: The css classes sSortableAsc ("sorting_asc_disabled"), sSortableDesc ("sorting_dsc_disabled") are kind of confusing as well: sSortableAsc is applied when a column can only be sorted ascending - but shouldn't that class be "sorting_desc_disabled", as obviously descending ordering is disabled in that case?
  • allanallan Posts: 61,443Questions: 1Answers: 10,053 Site admin
    Thanks for the live example. I think it does work as intended, but the priority order is reversed from what you have in your aoColumnDefs. Top of the array takes top priority, bottom takes the lowest.

    So if you change the order around we get this: http://live.datatables.net/azijaw/4/edit

    I've also added aaSorting since you don't' want sorting on the first column (DataTables by default will do a sort on the first column, regardless of bSortable on that column - which is probably wrong...).

    Allan
  • TiaxTiax Posts: 12Questions: 0Answers: 0
    Oh, yeah I messed that up playing around with it in #3, had it correct in #2 (and yeah, it's clearly stated in the doc, that elements at the start of the array have higher prio).

    It's not exactly right in #4, either: Look at the zero config example and you'll see the THs having the css class "sorting" (which also gives arrows in both directions in the demo css) - in #4 they'll all get sorting_disabled, which is obviously not the case as you notice when clicking on them ;)
  • allanallan Posts: 61,443Questions: 1Answers: 10,053 Site admin
    Good point - I missed that. The third column has and incorrect class assigned to it there. Thanks very much for flagging this up and your fix above. I'll look at integrating this into the main line.

    Its a fairly horrific code block that! But (almost) gets the job done...

    Allan
  • TiaxTiax Posts: 12Questions: 0Answers: 0
    edited November 2012
    With my change applied: http://live.datatables.net/azijaw/5

    Also wonder why the "sorting" class was ever applied correctly, since it's basically:

    [code]if(!a || b)
    {
    ...
    }
    else if(b)
    {
    // this is never executed, because the first condition would already evaluate to true because of b!
    }
    ...[/code]

    The only problem that persists, as you said, is sorting by the first column by default (even if sorting is disabled for it)...

    I think the sorting_asc/desc_disabled is basically just a naming consitency issue - consider the current mapping:
    "sorting" -> column is sortable, but currently is not sorted by
    "sorting_asc" / sorting_desc -> column is sortable and currently sorted the respective direction
    "sorting_disabled" -> column is not available for sorting at all, since it's been disabled
    "sorting_asc_disabled" / sorting_desc_disabled -> column CAN be sorted asc/desc only. Currently it is not sorted by this column, though

    The "_disabled " has different meanings here: for the former "disabled" means sorting for that column is completly turned off, while it means "it's currently not applied but available" for the latter classes. Kinda confusing...
This discussion has been closed.