2

I'm trying to create a plugin that will change the sorting behavior of a column. The data in the column is a <ul> element. Within each <li> element of the list, there is some text, and a decimal number. I want to sort the table based on the largest decimal number in the cell's list. Here's a jsfiddle showing the plugin, and as you can see, when you sort on the second column, it does not work correctly:

http://jsfiddle.net/flyingL123/1whzq1w2/3/

If it worked, the descending order should be Sam (97.50), Joe (80.50), Mike (17.50), and ascending should of course be the opposite. Based on my debugging, the plugin is returning the correct numerical value for each cell. Do you have any idea why the table wouldn't be sorted accordingly?

Here is the code from the plugin:

$.fn.dataTable.ext.order['number-list'] = function  ( settings, col )
{
    return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {

                    //get all numbers from the cell into an array and parseFloat each one
                    var nums = $(td).html().match(/(\d+.\d+)/);

                    if(nums){
                            nums = nums.map(function(val){return parseFloat(val, 10);});
                            return Math.max.apply(null, nums);
                    }
                    else{
                            return 0;
                    }
            } );
}

1 Answer 1

3

Note : This answer is completely rewritten.

About dataTables custom sorting and custom data sources
The original answer was what dataTables calls type based sorting. dataTables is born with sorting capabilities for basic "primitives" or types : string, numeric, date and html. By default, dataTables try to guess what type of data a column contains, and then the user click on the table header, the table is sorted according to that detected type. You can force a type to a specific column by using the sType / type options, like sType : 'string', if that somehow is needed, or if dataTables not detect the type correct. For example, you want the column to be sorted as number, but dataTables sort alphabetically, then you can set sType : 'numeric'.

Obviously the builtin sorting capabilities does not always fulfill all needs, like in your example. In that case, you can create a new type as you saw in the original answer or have seen in other custom sorting plugins. Eg. add a object to oSort after the scheme type-pre, type-desc, type-asc. Those function definitions are not mandatory, but is those dataTables will respond to. For example type-pre - the preprocessing function - is not mandatory, but very helpful if the content needs special treatment before the actual sorting functions is called.

dom-text (and its like) is basically a standalone type-pre. This is useful if you just want the sorting algorithm to sort on a certain part of the columns content, but not have any need for a whole new sorting algorithm. dataTables defines that as custom data source sorting. For example, if you have a column with names, like firstname lastname, but want to sort on the lastname, then this is the way to go.

The very good thing is, that you can combine all of the above. Default sorting, default type detection, forced types, custom sort plugins and custom data sources.

And here we have the embarrasing part :( I have myself a lot of cases where I need special sorting algorithms, so I have been so used to slam a custom sort plugin together, that I simply overlooked what you were trying to do :( I really do not recall the situation exactly, but obviosly I have seen your question while drinking coffee at 9am, and then answered with a custom sort plugin as on autopilot.

I can see why you are wondering - you are absolutely right. The code in your question is also right. Consider what I have written above : What you need is a combination of a custom data source and the builtin sort type numeric. The real answer is that you were so close, you just forgot to set the type, which is nessecary because the default sort type is string. So

var myDataTable = $('#myTable').DataTable({
  "columns":[
       null,
       {"orderDataType":"number-list", type: 'numeric'} // <--- just set the type to numeric
   ],
   "order":[],
});

and thats it! Here is your original fiddle forked with that -> http://jsfiddle.net/rd0p6ts8/

Sorry for the confusion. Hope you will accept the answer anyway.

Sign up to request clarification or add additional context in comments.

2 Comments

This works, but I am unclear why it works. I am also using the dom-text plugin found here: datatables.net/plug-ins/sorting/custom-data-source/dom-text. Why is this one defined differently? It was my impression that the custom sort I tried to implement is doing the same thing that this dom-text plugin is doing. So why is it defined differently?
@flyingL123 - have rewritten the answer totally. Understand why you are wondering. Even though my answer worked, regarding functionality, it was not the real answer, since the real answer is very simple without the need of creating a new sorting algortihm. A good answer must solve the problem on its own terms, not reinvent the wheel. Appearently I wasnt thinking when I did the first answer :(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.