3

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?

Ivan Nukli
  • 57
  • 4

2 Answers2

0

You can accomplish this by using localeCompare in the body of your sort functions.

For ascending sort:

return a.localeCompare(b,'pl');

For descending sort:

return b.localeCompare(a,'pl');

Here are those changes in context of your 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) {
  return a.localeCompare(b,'pl');
};

jQuery.fn.dataTableExt.oSort['balkan_string-desc'] = function(a,b) {
  return b.localeCompare(a,'pl');
};

$(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>
Lonnie Best
  • 9,936
  • 10
  • 57
  • 97
0

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.

andrewJames
  • 19,570
  • 8
  • 19
  • 51