Cannot sort decimals with leading zero ListJS

214 Views Asked by At

I am using List.js (v1.5.0) to add sorting on a table and cannot get my decimal values to sort correctly. Decimal values are being sorted by 'standard sorting' as opposed to 'natural order sorting'. Sorting the following table by "EC AVG" yields an incorrect sort. It does not seem to be recognizing the leading zeros after the decimal.

Link to the incorrectly sorted table

Here is a snippet of the HTML table:

<div id="sort-me" class="tableFixHead">
  <table class="table mdl-shadow--4dp" id="myTable" >
    <thead>
      <tr>
        <th class="sort" data-sort="unit_name">Unit Name</th>
        <th class="sort" data-sort="ec_average">EC Avg</th>
        <th class="sort" data-sort="ph_average">pH Avg</th>
        <th class="sort" data-sort="ec_min">EC Min</th>
        <th class="sort" data-sort="ec_max">EC Max</th>
        <th class="sort" data-sort="ph_min">pH Min</th>
        <th class="sort" data-sort="ph_max">pH Max</th>
      </tr>
    </thead>
    <tbody class="list">
     <tr>
      <td class="unit_name">Fake Unit 1</td>
      <td class="ec_average" >0.01</td>
      <td class="ph_average" >6.26</td>
      <td class="ec_min" >0.01</td>
      <td class="ec_max" >0.01</td>
      <td class="ph_min" >6.14</td>
      <td class="ph_max" >6.38</td>  
     </tr>
     <tr>
      <td class="unit_name">Fake Unit 2</td>
      <td class="ec_average" >0.3</td>
      <td class="ph_average" >6.41</td>
      <td class="ec_min" >0.3</td>
      <td class="ec_max" >0.01</td>
      <td class="ph_min" >5.68</td>
      <td class="ph_max" >6.44</td>  
     </tr>
     <tr>
      <td class="unit_name">Fake Unit 3</td>
      <td class="ec_average" >0.03</td>
      <td class="ph_average" >6.13</td>
      <td class="ec_min" >0.01</td>
      <td class="ec_max" >0.05</td>
      <td class="ph_min" >5.62</td>
      <td class="ph_max" >6.33</td>  
     </tr>
     <tr>
      <td class="unit_name">Fake Unit 4</td>
      <td class="ec_average" >0.5</td>
      <td class="ph_average" >4.81</td>
      <td class="ec_min" >0.3</td>
      <td class="ec_max" >0.55</td>
      <td class="ph_min" >5.68</td>
      <td class="ph_max" >6.24</td>  
     </tr>
     <tr>
      <td class="unit_name">Fake Unit 5</td>
      <td class="ec_average" >0.05</td>
      <td class="ph_average" >4.93</td>
      <td class="ec_min" >0.01</td>
      <td class="ec_max" >0.07</td>
      <td class="ph_min" >5.64</td>
      <td class="ph_max" >6.13</td>  
     </tr>
    </tbody>
  </table>
</div>

Along with the following List.js options and initializer:

var sorting_options = {
  valueNames: ['unit_name', 'ec_average', 'ec_min', 'ec_max', 'ph_average', 'ph_min', 'ph_max']
};

var statusList = new List('sort-me', sorting_options);

My use-case seems to be a pretty standard sorting problem so I feel like I may just be missing something that hasn't been easy to track down in the documentation.

Any ideas why sorting decimals with List.js doesn't seem to work?

1

There are 1 best solutions below

0
On

That appears to the the intended behavior of the sort method used by List.js (https://github.com/nwoltman/string-natural-compare).

That sorting algorithm doesn't actually treat each string as a single decimal number, it's treating the decimal point as a period, and is sorting on the things after the decimal point as if they were zero-padded integers.

You're going to have to supply List.js your own sorting function. Per the List.js docs:

The default sort function is found here https://github.com/nwoltman/string-natural-compare, if you want to use your own, read the code and check out the tests.

Which is not super helpful, but there you go. Skimming the code, it looks like passing a sortFunction property into the constructor's second argument should do it.

Update: I found the relevant test. Note the "a bit wrong" in the test description.