"intl" sorting plugin doesn't work (an issue about columnDefs type:string?)

"intl" sorting plugin doesn't work (an issue about columnDefs type:string?)

koonkoonskoonkoons Posts: 15Questions: 3Answers: 0

I'm trying to make a table with Bootstrap 4.3.1, DataTables and "intl" sorting plugin. Codes are like this:

<script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.10.18/datatables.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/plug-ins/1.10.19/sorting/intl.js"></script>
<script type="text/javascript">
    $(document).ready(function() {
        $.fn.dataTable.ext.order.intl();

        $('#data-tables').DataTable( {
            "columnDefs": [ { "type": "string", "targets": 2 } ],
            "order": [[2, "asc"]],
        });
    } );
</script>

But this doesn't work at all. When I try to sort the table by column 2, it's sorted by column 0.

Then I found that even I removed the lines about "intl" plugin the same issue was there. It seems
"columnDefs": [ { "type": "string", "targets": 2 } ],
is the cause.

But I need this columnDefs to make "intl" plugin work, I guess? What should I do?

Answers

  • koonkoonskoonkoons Posts: 15Questions: 3Answers: 0
    edited March 2019

    If I remove columnDefs, "intl" do nothing. My browser is Chrome 73.

  • colincolin Posts: 15,144Questions: 1Answers: 2,586

    Hi @koonkoons ,

    We're happy to take a look, but as per the forum rules, please link to a test case - a test case that replicates the issue will ensure you'll get a quick and accurate response. Information on how to create a test case (if you aren't able to link to the page you are working on) is available here.

    Cheers,

    Colin

  • koonkoonskoonkoons Posts: 15Questions: 3Answers: 0
    edited March 2019

    Hi colin,

    I found the cause - my cells contain HTML tags including ID numbers (like <a href="http://bra.bra/1">), so "type": "string" messes them up.

    However, it seems "intl" plugin doesn't work with html type columns.
    http://live.datatables.net/qihopuna/1/edit

    Column 1's type is string, so "intl" plugin works. (AAA, ØØØ, ZZZ).
    Column 2's type is html, so "intl" plugin doesn't work. (AAA, ZZZ, ØØØ).

    Is there a way to make "intl" work with html columns?
    Thanks.

  • allanallan Posts: 61,726Questions: 1Answers: 10,109 Site admin

    Try this:

    $.fn.dataTable.ext.order['html-intl'] = function ( locales, options ) {
        if ( window.Intl ) {
            var collator = new Intl.Collator( locales, options );
            var types = $.fn.dataTable.ext.type;
    
            delete types.order['html-pre'];
            types.order['html-asc'] = function ( a, b ) {
                a = a.replace(/<.*?>/g, '');
                b = b.replace(/<.*?>/g, '');
                return collator.compare( a, b );
            };
            types.order['html-desc'] = function ( a, b ) {
                a = a.replace(/<.*?>/g, '');
                b = b.replace(/<.*?>/g, '');
                return collator.compare( a, b ) * -1;
            };
        }
    };
    

    Allan

  • koonkoonskoonkoons Posts: 15Questions: 3Answers: 0
    edited March 2019

    Hi @allan,

    I replaced intl.js to

    (function( factory ) {
        "use strict";
    
        if ( typeof define === 'function' && define.amd ) {
            // AMD
            define( ['jquery'], function ( $ ) {
                return factory( $, window, document );
            } );
        }
        else if ( typeof exports === 'object' ) {
            // CommonJS
            module.exports = function (root, $) {
                if ( ! root ) {
                    root = window;
                }
    
                if ( ! $ ) {
                    $ = typeof window !== 'undefined' ?
                        require('jquery') :
                        require('jquery')( root );
                }
    
                return factory( $, root, root.document );
            };
        }
        else {
            // Browser
            factory( jQuery, window, document );
        }
    }
    
    (function( $, window, document ) {
        $.fn.dataTable.ext.order['html-intl'] = function ( locales, options ) {
            if ( window.Intl ) {
                var collator = new Intl.Collator( locales, options );
                var types = $.fn.dataTable.ext.type;
    
                delete types.order['html-pre'];
                types.order['html-asc'] = function ( a, b ) {
                    a = a.replace(/<.*?>/g, '');
                    b = b.replace(/<.*?>/g, '');
                    return collator.compare( a, b );
                };
                types.order['html-desc'] = function ( a, b ) {
                    a = a.replace(/<.*?>/g, '');
                    b = b.replace(/<.*?>/g, '');
                    return collator.compare( a, b ) * -1;
                };
            }
        };
    });
    

    but it didn't work.

  • allanallan Posts: 61,726Questions: 1Answers: 10,109 Site admin

    Need to also execute the html-intl function. I've made a few small changes (including an easier name) here:

    http://live.datatables.net/qihopuna/4/edit

    Allan

  • koonkoonskoonkoons Posts: 15Questions: 3Answers: 0

    Hi @allan,

    Thanks, it finally worked!

    The final state of intl.js is

    /**
     * This sorting type will replace DataTables' default string sort with one that
     * will use a locale aware collator. This is supported by IE11, Edge, Chrome,
     * Firefox and Safari 10+. Any browser that does not support the Intl will
     * simply fall back to UTF8 string sorting.
     *
     * This method simply needs to be called prior to the DataTables' initialisation
     * to replace the default string sort with locale aware sorting. The method
     * optionally takes two arguments:
     *
     * 1. [Optional] Locale or array of locales
     * 2. [Optional] Collator options
     *
     * For the supported options please see the
     * [MDN Intl documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator).
     *
     * @name intl
     * @summary Sort string data using the Intl Javascript API
     * @author [Allan Jardine](//datatables.net)
     * @depends DataTables 1.10+
     *
     * @example
     *    // Host's current locale
     *    $.fn.dataTable.ext.order.intl();
     *
     * @example
     *    // Explicit locale
     *    $.fn.dataTable.ext.order.intl('de-u-co-phonebk');
     *
     * @example
     *    // Locale with configuration options
     *    $.fn.dataTable.ext.order.intl('fr', {
     *      sensitivity: 'base'
     *    } );
     */
    
    
    // UMD
    (function( factory ) {
        "use strict";
    
        if ( typeof define === 'function' && define.amd ) {
            // AMD
            define( ['jquery'], function ( $ ) {
                return factory( $, window, document );
            } );
        }
        else if ( typeof exports === 'object' ) {
            // CommonJS
            module.exports = function (root, $) {
                if ( ! root ) {
                    root = window;
                }
    
                if ( ! $ ) {
                    $ = typeof window !== 'undefined' ?
                        require('jquery') :
                        require('jquery')( root );
                }
    
                return factory( $, root, root.document );
            };
        }
        else {
            // Browser
            factory( jQuery, window, document );
        }
    }
    (function( $, window, document ) {
    
    
    $.fn.dataTable.ext.order.intl = function ( locales, options ) {
        if ( window.Intl ) {
            var collator = new Intl.Collator( locales, options );
            var types = $.fn.dataTable.ext.type;
    
            delete types.order['string-pre'];
            types.order['string-asc'] = collator.compare;
            types.order['string-desc'] = function ( a, b ) {
                return collator.compare( a, b ) * -1;
            };
        }
    };
    
    $.fn.dataTable.ext.order.htmlIntl = function ( locales, options ) {
        if ( window.Intl ) {
            var collator = new Intl.Collator( locales, options );
            var types = $.fn.dataTable.ext.type;
    
            delete types.order['html-pre'];
            types.order['html-asc'] = function ( a, b ) {
                a = a.replace(/<.*?>/g, '');
                b = b.replace(/<.*?>/g, '');
                return collator.compare( a, b );
            };
            types.order['html-desc'] = function ( a, b ) {
                a = a.replace(/<.*?>/g, '');
                b = b.replace(/<.*?>/g, '');
                return collator.compare( a, b ) * -1;
            };
        }
    };
    
    
    }));
    

    and the execution is

    $(document).ready( function () {
        $.fn.dataTable.ext.order.intl('gb');
        $.fn.dataTable.ext.order.htmlIntl('gb');
    
        $('#example').DataTable();
    } );
    

    Thank you so much.

This discussion has been closed.