Search code examples
javascriptjquerydatatable

How to make sort with International characters in dataTable


I am trying to make my sort working with international characters. However is messed up when I try to sort, the order is not right. Below is my code:

function character_substitute(string) {
    var first_char = string.replace( /<.*?>/g, "" ).toLowerCase().charAt(0);
    var chars = /[šđžčć]/g;
    
    if (first_char.match(chars)) {
        if (first_char == "š") { first_char = first_char.replace("š", "s"); return first_char; }
        if (first_char == "ž") { first_char = first_char.replace("ž", "z"); return first_char; }
        if (first_char == "č") { first_char = first_char.replace("č", "c"); return first_char; }
        if (first_char == "ć") { first_char = first_char.replace("ć", "c"); return first_char; }
        if (first_char == "đ") { first_char = first_char.replace("đ", "d"); return first_char; }
    }
    
    return first_char;
}

jQuery.fn.dataTableExt.oSort['balkan_string-asc']  = function(a,b) {
    x = character_substitute(a);
    y = character_substitute(b);
    
    return ((x < y) ? -1 : ((x > y) ? 1 : 0));
};

jQuery.fn.dataTableExt.oSort['balkan_string-desc'] = function(a,b) {
    x = character_substitute(a);
    y = character_substitute(b);
    
    return ((x < y) ? 1 : ((x > y) ? -1 : 0));
};



$(function() {
    $("#example").DataTable({
        columns: [{
            type: 'balkan_string',
            targets: 0
        }]
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>
<link href="https://cdn.datatables.net/1.10.25/css/jquery.dataTables.min.css" rel="stylesheet" >


<table id="example">
    <thead>
        <tr>
            <th>String</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>aaaa</td>
        </tr>
        <tr>
            <td>bbbb</td>
        </tr>
        <tr>
            <td>cccc</td>
        </tr>
        <tr>
            <td>čččč</td>
        </tr>
        <tr>
            <td>ćććć</td>
        </tr>
        <tr>
            <td>dddd</td>
        </tr>
       
        
        
       
    </tbody>

</table>

This is an output when you try to sort:

dddd
cccc
čččč
ćććć
bbbb
aaaa

The order should be like this:

dddd
ćććć
čččč
cccc
bbbb
aaaa

Is there a way to solve this? I didn't found the solution to my problem, so I try to write on my own.

Can anybody try to help me with this?


Solution

  • DataTables has a plug-in for natural language sorting (meaning, broadly, dictionary-based sorting):

    https://cdn.datatables.net/plug-ins/1.10.25/sorting/intl.js
    

    The above file contains usage notes, and you can also read more about it here:

    Locale based sorting

    You can use it as follows:

    $(document).ready(function() {
    
      // the plug-in's function is auto-detected by DataTables:
      $.fn.dataTable.ext.order.intl('pl');
    
      var table = $('#example').DataTable( {
        "order": [[ 0, 'desc' ]] // initial sort order
      } );
    
    } );
    <!doctype html>
    <html>
    <head>
      <meta charset="UTF-8">
      <title>Demo</title>
      <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
      <script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.js"></script>
      <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.25/css/jquery.dataTables.css">
      <link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
    
      <!-- include this plug-in: -->
      <script src="https://cdn.datatables.net/plug-ins/1.10.25/sorting/intl.js"></script>
    
    </head>
    
    <body>
    
    <div style="margin: 20px;">
    
        <table id="example" class="display dataTable cell-border" style="width:100%">
            <thead>
            <tr>
                <th>String</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>aaaa</td>
            </tr>
            <tr>
                <td>bbbb</td>
            </tr>
            <tr>
                <td>cccc</td>
            </tr>
            <tr>
                <td>čččč</td>
            </tr>
            <tr>
                <td>ćććć</td>
            </tr>
            <tr>
                <td>dddd</td>
            </tr>
           
        </tbody>
        </table>
    
    </div>
    
    </body>
    </html>

    The end result:

    dddd
    ćććć
    čččč
    cccc
    bbbb
    aaaa
    

    Some important notes:

    In my JavaScript, I used the pl language tag code to use a Polish locale. This was a bit of a guess on my part, based on the assumption that you are using an alphabet which contains both č and ć. Apologies if I got that wrong! - and you can, of course use whatever locale (or array of locales) you need.