Search code examples
javascriptjquerytablesorternon-english

Tablesorter: sorting the Czech alphabet


Im using tablesorter characterEquivalents extend as it is described in http://mottie.github.io/tablesorter/docs/example-locale-sort.html.

I prepared similar extend for czech characters, but the sorting do not work for some characters - f. e. \u017d

$.extend( $.tablesorter.characterEquivalents, {
"a" : "\u00e1", // á
"A" : "\u00c1", // Á
"c" : "\u010d", // č
"C" : "\u010c", // Č
"d" : "\u010f", // ď
"D" : "\u010e", // Ď
"e" : "\u00e9\u011b", // éě
"E" : "\u00c9\u011a", // ÉĚ
"i" : "\u00ed", // í
"I" : "\u00cd", // Í
"n" : "\u0148", // ň
"N" : "\u0147", // Ň
"o" : "\u00f3", // ó
"O" : "\u00d3", // Ó    
"r" : "\u0159", // ř
"R" : "\u0158", // Ř
"s" : "\u0161", // š
"Š" : "\u0160", // Š
"t" : "\u0165", // ť
"T" : "\u0164", // Ť        
"u" : "\u00fa\u016f", // úů
"U" : "\u00da\u016e", // ÚŮ
"y" : "\u00fd", // ý
"Y" : "\u00dd", // Ý    
"z" : "\u017e", // ž
"Z" : "\u017d" // Ž
}); 

In example here http://jsfiddle.net/Gk43v/18/ there is issue that Ž is before Z which is wrong.

But on my pages is Ž is in middle of the table which is completely wrong.


Solution

  • It is working. The "z" has been replaced in the internal cache.

    Although you might need to include a true flag to perform a deep extend:

    $.extend( true, $.tablesorter.characterEquivalents, { ... });
    

    Check out this demo (sort to see the column values in the firebug window): http://jsfiddle.net/Gk43v/19/


    Update: Ok, the issue appears to be the actual sort order. The problem is that the default sort is done using the ASCII value of the characters, so that Š and Ž sort after A-Z without any character-equivalent replacement. The function replaces "S" for "Š" and "Z" for "Ž", making them equivalent and indistinguishable from their unaccented letters.

    If you truly want the sort to maintain character order, you'll need to use a different text sorter like sugarjs which allows you to set a sort order:

    Array.AlphanumericSortOrder = 'AaÁáBbCcDdÐðEeÉéĘęFfGgHhIiÍíJjKkLlMmNnOoÓóPpQqRrSsTtUuÚúVvWwXxYyÝýZzÞþÆæÖö';
    

    You can then use the textSorter option to use the sugar array sort for that column - here is a demo showing an Icelandic sort

    $("table").tablesorter({
      theme : 'blue',
      ignoreCase : false,
      textSorter : {
        // alphanumeric sort from sugar (http://sugarjs.com/arrays#sorting)
        // for the first column (zero-based index)
        0 : Array.AlphanumericSort
      }
    });
    

    Update #2: Because the Czech alphabet is a bit more complex, you'll need to replace the "CH" with a placholder because Sugar only allows single characters in the sort order definition.

    So in this example, I replaced "CH" with "Æ" (updated demo)

    $(function () {
        Array.AlphanumericSortOrder = 'AaÁáÄäBbCcČčDdĎďEeÉéĚěFfGgHhÆæIiÍíJjKkLlMmNnŇňOoÓóÖöPpQqRrŘřSsŠšTtŤťUuÚúŮůÜüVvWwXxYyÝýZzŽž';
        Array.AlphanumericSortIgnoreCase = true;
        // see https://github.com/andrewplummer/Sugar/issues/382#issuecomment-41526957
        Array.AlphanumericSortEquivalents = {};
    
        // replace "Ch" and "ch" with a placeholder... it can be anything
        // in this example, I'm replacing ch with "æ" and Ch or CH with "Æ"
        // these characters have been added to the Array.AlphanumericSortOrder
        // between "h" and "I" - according to http://en.wikipedia.org/wiki/Czech_orthography
        var replaceCH = function( node ) {
            return $(node).text()
                .replace(/(Ch|CH)/g, '\u00c6')
                .replace(/ch/g, '\u00e6');
        };
    
        $("table").tablesorter({
            theme: 'blue',
            // table = table object; get config options from table.config
            // column is the column index (zero-based)
            ignoreCase: false,
            textExtraction : {
                1: replaceCH,
                3: replaceCH
            },
            textSorter: {
                1 : Array.AlphanumericSort, // alphanumeric sort from sugar (http://sugarjs.com/arrays#sorting)
                3 : Array.AlphanumericSort
            }
        });
    });
    

    I did try to use the characterEquivalents function to replace the string, but it also currently only supports single character replacements (I'll fix this in a future version), so for now I am using a custom textExtraction function.

    The second issue you reported can be solved by triggering an "update" method on the table after the ajax call completes and the table is rendered.

    $('table').trigger('update');