jQuery UI Widgets › Forums › Grid › Sorting Throws Errors + Sorting Alphanumerics
Tagged: angular grid, custom sort, custom sorting, grid, Invalid property, jquery grid, jqxgrid, sortcolumn, sortdirection
This topic contains 5 replies, has 2 voices, and was last updated by Dimitar 9 years, 5 months ago.
-
Author
-
Hello. We are using jQWidgets v3.7.1 and trying to sort columns in jqxGrid — we are including jqxGrid.sort.js. When I try to add parameters for “sortcolumn” or “sortdirection”, I get an error in the browser console, e.g.: “Uncaught Invalid property: sortcolumn” or “sortdirection”. Every other parameter does seem to work, including “sortable”.
We also have a unique alphanumeric naming convention, “Foo-1,” “Foo-2” etc., that we’d like to sort by the last integer in the string, but because there are both alphabetic and numeric data in the name, the closest we can get is a sort that goes something like:
Foo-1
Foo-10
Foo-11
Foo-2
Foo-3
etc.I know there are custom sorting abilities for the grid, but it’s not clear to me how we would accomplish this sorting challenge that way. We really do not want to change our data structure to something like “Foo-01”, “Foo-02” if at all possible. We appreciate any help you might be able to provide us — thank you for your attention.
Hello jimiayler,
sortcolumn and sortdirection are properties of the grid source object, unlike sortable, which is a property of the main grid object. Here is how you can set them:
var source = { datatype: "xml", datafields: [{ name: 'ShippedDate', map: 'm\\:properties>d\\:ShippedDate', type: 'date' }, { name: 'Freight', map: 'm\\:properties>d\\:Freight', type: 'float' }, { name: 'ShipName', map: 'm\\:properties>d\\:ShipName', type: 'string' }, { name: 'ShipAddress', map: 'm\\:properties>d\\:ShipAddress', type: 'string' }, { name: 'ShipCity', map: 'm\\:properties>d\\:ShipCity', type: 'string' }, { name: 'ShipCountry', map: 'm\\:properties>d\\:ShipCountry', type: 'string' }], root: "entry", record: "content", id: { name: "OrderID", map: "m\\:properties>d\\:OrderID" }, url: url, sortcolumn: 'ShipName', sortdirection: 'asc' };
You can check the demo Custom Sorting where you can see a sample implementation of such a function. In your code, compare the values after “Foo-” only.
Best Regards,
DimitarjQWidgets team
http://www.jqwidgets.com/Great, thank you for the clarification, those do not throw errors now. However, I don’t see in your demo a clear example of comparing “the values after ‘Foo-‘ only” for our one sortable column. Would truly appreciate any guidance you might be able to provide here. Thanks again.
Hi jimiayler,
This is too specific a requirement and we cannot implement it for you, but here is what I meant by comparing the values after “Foo-” only:
var compare = function(value1, value2) { value1 = value1.slice(4); // returns only the number after "Foo-" value2 = value2.slice(4); // returns only the number after "Foo-" ...
Best Regards,
DimitarjQWidgets team
http://www.jqwidgets.com/Unfortunately, that approach returns a sort that reads (assuming 11 results):
Foo-2
Foo-3
Foo-4
Foo-5
Foo-1
Foo-6
Foo-7
Foo-8
Foo-9
Foo-10
Foo-11It is the same result whether one sorts ascending or descending. I confess I’m surprised no one has ever brought a similarly mixed alphanumeric sort case to your attention before, it seems as though it would be a pretty standard utilization. I’ll put in a request for future versions having this functionality. In the event I am getting the complete custom sorting scenario wrong, please see sample code below trying to get this going. Thank you once more for your attention and assistance.
var customsortfunc = function (column, direction) { var sortdata = new Array(); if (direction == 'ascending') direction = true; if (direction == 'descending') direction = false; if (direction != null) { for (i = 0; i < dataFields.length; i++) { sortdata.push(dataFields[i]); } } else sortdata = dataFields; var tmpToString = Object.prototype.toString; Object.prototype.toString = (typeof column == "function") ? column : function () { return this[column] }; if (direction != null) { sortdata.sort(compare); if (!direction) { sortdata.reverse(); } } source.localdata = sortdata; $("#evaluations-grid").jqxGrid('updatebounddata', 'sort'); Object.prototype.toString = tmpToString; } var compare = function(value1, value2) { value1 = value1.slice(5); // returns only the number after "Eval-" value2 = value2.slice(5); // returns only the number after "Eval-" try { var tmpvalue1 = parseFloat(value1); if (isNaN(tmpvalue1)) { if (value1 < value2) { return -1; } if (value1 > value2) { return 1; } } else { var tmpvalue2 = parseFloat(value2); if (tmpvalue1 < tmpvalue2) { return -1; } if (tmpvalue1 > tmpvalue2) { return 1; } } } catch (error) { var er = error; } return 0; }; var source = { datatype: "json", datafields: dataFields, id: 'session_name', url: url, sort: customsortfunc, sortcolumn: 'session_name', sortdirection: 'asc' };
Hi jimiayler,
An alphanumeric sort functionality may have been required by other users, too, but each time the actual scenario has been different – “Foo-2” in your case, “2-Foo” (for example) in someone else’s. That is why there is no definitive, built-in alphanumeric sorting.
Here is a working modification of your code:
<!DOCTYPE html> <html lang="en"> <head> <link rel="stylesheet" href="../../jqwidgets/styles/jqx.base.css" type="text/css" /> <script type="text/javascript" src="../../scripts/jquery-1.11.1.min.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxcore.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxdata.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxbuttons.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxscrollbar.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxlistbox.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxdropdownlist.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxmenu.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxgrid.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxgrid.sort.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxgrid.pager.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxgrid.columnsresize.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxgrid.selection.js"></script> <script type="text/javascript" src="../../scripts/demos.js"></script> <script type="text/javascript" src="generatedata.js"></script> <script type="text/javascript"> $(document).ready(function () { // prepare the data var data = [{ firstname: 'Foo-1' }, { firstname: 'Foo-2' }, { firstname: 'Foo-11' }, { firstname: 'Foo-10'}]; var customsortfunc = function (column, direction) { var sortdata = new Array(); if (direction == 'ascending') direction = true; if (direction == 'descending') direction = false; if (direction != null) { for (i = 0; i < data.length; i++) { sortdata.push(data[i]); } } else sortdata = data; var tmpToString = Object.prototype.toString; Object.prototype.toString = (typeof column == "function") ? column : function () { return this[column] }; if (direction != null) { sortdata.sort(compare); if (!direction) { sortdata.reverse(); } } source.localdata = sortdata; $("#evaluations-grid").jqxGrid('updatebounddata', 'sort'); Object.prototype.toString = tmpToString; } var compare = function (value1, value2) { value1 = value1.firstname.slice(4); // returns only the number after "Foo-" value2 = value2.firstname.slice(4); // returns only the number after "Foo-" try { var tmpvalue1 = parseFloat(value1); if (isNaN(tmpvalue1)) { if (value1 < value2) { return -1; } if (value1 > value2) { return 1; } } else { var tmpvalue2 = parseFloat(value2); if (tmpvalue1 < tmpvalue2) { return -1; } if (tmpvalue1 > tmpvalue2) { return 1; } } } catch (error) { var er = error; } return 0; }; var source = { localdata: data, sort: customsortfunc, datafields: [ { name: 'firstname', type: 'string' } ], datatype: "array" }; var dataAdapter = new $.jqx.dataAdapter(source); $("#evaluations-grid").jqxGrid( { width: 200, source: dataAdapter, sortable: true, autoheight: true, ready: function () { $("#evaluations-grid").jqxGrid('sortby', 'firstname', 'asc'); }, columns: [ { text: 'First Name', datafield: 'firstname', width: 200 } ] }); }); </script> </head> <body class='default'> <div id="evaluations-grid"> </div> </body> </html>
Best Regards,
DimitarjQWidgets team
http://www.jqwidgets.com/ -
AuthorPosts
You must be logged in to reply to this topic.