Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect sorting in Icelandic #212

Closed
laddi opened this issue Jan 9, 2013 · 7 comments
Closed

Incorrect sorting in Icelandic #212

laddi opened this issue Jan 9, 2013 · 7 comments

Comments

@laddi
Copy link

laddi commented Jan 9, 2013

I have a problem with text sorting using Icelandic characters. The problem is that character equivalents aren't really suitable since there is a strict sorting order for each character, the accented characters and then the special Icelandic characters (þ [thorn] and ð [eth]). The sorting is actually the same as specified on the sugar.js array sorting page which is as follows:

AÁ[ÀÂÃĄ]BC[ĆČÇ]D[Ď]ÐEÉ[ÈĚÊË]ĘFG[Ğ]H[ı]IÍ[ÌİÎÏ]JKL[Ł]MN[ŃŇÑ]OÓ[ÒÔ]PQR[Ř]S[ŚŠŞ]T[Ť]UÚ[ÙŮÛÜ]VWXYÝZ[ŹŻŽ]ÞÆ[ŒØÕÅÄ]Ö (characters in brackets not in Icelandic alphabet)

But using the sortLocaleCompare sorts á/Á, for example, as an a/A which is wrong because a > á. Also ö/Ö is mixed in with the O's but is actually the last letter in the alphabet. And þ/Þ is last behind both æ/Æ and ö/Ö even though both of them should be behind þ/Þ.

Any ideas on a possible fix for this or, better yet, use the correct sorting as specified in the sugar.js documentation? Or is there possibly a character to number (place in alphabet) conversion I could use?

@Mottie
Copy link
Owner

Mottie commented Jan 9, 2013

Hmm, well I guess I'll need to dig into sugar.js' sort function because this plugin doesn't sort characters in that manner.

It might not be a simple, quick fix either. So, I'll apologize in advance for the inconvenience and hopefully will have a viable solution for you soon.

@laddi
Copy link
Author

laddi commented Jan 9, 2013

Thanks for a speedy reply!

I actually kind of knew that already since I've been trying to fix this for a while now. This is the drawback of working in a language that only around 330.000 people in the world can speak and/or understand... ;)

@Mottie
Copy link
Owner

Mottie commented Jan 10, 2013

Whew... my darn OCD. Anyway, I pulled out the relevant code from sugar.js and made a sort function (sortBy). So all you need to do is include the sort code below, and set the textSorter option to sortBy. :)

You do not need to include sugar.js. Here is a demo.

$(function(){

    /* sortBy functions & helpers extracted and slightly modified from
    * Sugar Library v1.3.7
    * Freely distributable and licensed under the MIT-style license.
    * Copyright (c) 2012 Andrew Plummer
    * http://sugarjs.com/arrays#sorting
    */
    var array = {
        AlphanumericSortIgnoreCase  : true,
        AlphanumericSortEquivalents : {}
    },

    // order = 'AÁÀÂÃĄBCĆČÇDĎÐEÉÈĚÊËĘFGĞHıIÍÌİÎÏJKLŁMNŃŇÑOÓÒÔPQRŘSŚŠŞTŤUÚÙŮÛÜVWXYÝZŹŻŽÞÆŒØÕÅÄÖ',
    // equiv = 'AÁÀÂÃ,CÇ,EÉÈÊË,IÍÌİÎÏ,OÓÒÔ,Sß,UÚÙÛÜ',
    // modified order to match Icelandic sorting - see https://github.com/Mottie/tablesorter/issues/212
    order = 'AÁBCDÐEÉĘFGHIÍJKLMNOÓPQRSTUÚVWXYÝZÞÆÖ',
    equiv = '',

    sortBy = function(a,b){
        return typeof a === "string" && typeof b === "string" ? collateStrings(a,b) : a < b ? -1 : a > b ? 1 : 0;
    },

    // Alphanumeric collation helpers
    collateStrings = function(a, b) {
        var aValue, bValue, aChar, bChar, aEquiv, bEquiv, index = 0, tiebreaker = 0;
        a = getCollationReadyString(a);
        b = getCollationReadyString(b);
        do {
            aChar  = getCollationCharacter(a, index);
            bChar  = getCollationCharacter(b, index);
            aValue = getCollationValue(aChar);
            bValue = getCollationValue(bChar);
            if (aValue === -1 || bValue === -1) {
                aValue = a.charCodeAt(index) || null;
                bValue = b.charCodeAt(index) || null;
            }
            aEquiv = aChar !== a.charAt(index);
            bEquiv = bChar !== b.charAt(index);
            if (aEquiv !== bEquiv && tiebreaker === 0) {
                tiebreaker = aEquiv - bEquiv;
            }
            index += 1;
        } while (aValue != null && bValue != null && aValue === bValue);
        if (aValue === bValue) return tiebreaker;
        return aValue < bValue ? -1 : 1;
    },

    getCollationReadyString = function(str) {
        if (array.AlphanumericSortIgnoreCase) {
            str = str.toLowerCase();
        }
        return str.replace(array.AlphanumericSortIgnore, '');
    },

    getCollationCharacter = function(str, index) {
        var chr = str.charAt(index), eq = array.AlphanumericSortEquivalents || {};
        return eq[chr] || chr;
    },

    getCollationValue = function(chr){
        var order = array.AlphanumericSortOrder;
        return chr ? order.indexOf(chr) : null;
    },

    equivalents = {};

    array.AlphanumericSortOrder = $.map(order.split(''), function(str) {
        return str + str.toLowerCase();
    }).join('');

    $.each(equiv.split(','), function(i,set) {
        var equivalent = set.charAt(0);
        $.each(set.slice(1).split(''), function(i,chr) {
            equivalents[chr] = equivalent;
            equivalents[chr.toLowerCase()] = equivalent.toLowerCase();
        });
    });

    $('table.tablesorter').tablesorter({
        widgets    : ['zebra'],
        textSorter : sortBy
    });
});

@laddi
Copy link
Author

laddi commented Jan 10, 2013

Thanks a million! :D

I just added a global override of the textSorter default and now it's working perfectly for me in all views. Thanks again and keep up the good work on an excellent plugin! :D

@Mottie
Copy link
Owner

Mottie commented Jan 10, 2013

Glad I could help! :)

@Mottie
Copy link
Owner

Mottie commented Mar 20, 2015

Just to update you, Sugar has since exposed the sort functions so there is no longer a need to extract out specific code from that library. All you need to get a proper Icelandic alphabetical sort is to do the following (demo):

$(function () {

    Array.AlphanumericSortOrder = 'AaÁáBbCcDdÐðEeÉéĘęFfGgHhIiÍíJjKkLlMmNnOoÓóPpQqRrSsTtUuÚúVvWwXxYyÝýZzÞþÆæÖö';
    Array.AlphanumericSortIgnoreCase = true;
    // see https://github.com/andrewplummer/Sugar/issues/382#issuecomment-41526957
    Array.AlphanumericSortEquivalents = {};

    $('table.tablesorter').tablesorter({
        widgets: ['zebra'],
        textSorter: {
            0 : Array.AlphanumericSort
        }
    });

});

@laddi
Copy link
Author

laddi commented Mar 20, 2015

Cool, thanks! :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants