The datatable component of yui3 supports data sorting. You only need to add sortable: true when defining columns.
Here, we need to solve the remote sorting problem first.
Remote sorting means that all data is sorted, rather than the default click of the table itself.
This can be handled through the sort method of the datatable component.
For example:
table.after(‘sort‘, function(e) { var page = _getCurrentPage(); var key = _getCurrentKey(); doSearch(key, page); });
In this way, the dosearch method can be called after the table header is sorted.
Dosearch can be written in this way.
var doSearch = function(key, page, clearsort) { var param = _getParam(); var field = ‘‘; var asc = true; if (clearsort == true) { table.set(‘sortBy‘, ‘‘); } else { var sort = table.get(‘sortBy‘); if (sort != null && sort[0] != null) { for (var p in sort[0]) { field = p; asc = sort[0][p] == 1 ? true : false; } } } var configuration = { method: ‘POST‘, data: Y.mix({ key: key, page: page, sort: field, asc: asc, method: ‘search‘}, param), on: { complete: function(o) { var data = Y.JSON.parse(o.data.responseText); table.set(‘data‘, data.items); } } }; var io = new Y.IO({ emitFacade: true, bubbles: true }); io.send(‘Search.ashx‘, configuration); };
Here, the _ getparam method is used to obtain the query parameters selected by the user. The clearsort parameter is used to clear the sorting mark when the user clicks the refresh or query buttons.
The background code performs sorting query based on the obtained parameters.
In actual development, I encountered a problem: when a column of data type returned in the background is string, but there is a value in it, how should I handle the sorting based on the value size?
In fact, the backend has already processed SQL queries and converted the values in this column to numerical sorting first, the value that cannot be converted to the minimum value (in my logic, the minimum value is treated as 0). Then, sort the value based on the result and then sort the value based on the text. However, the problem is, after the data is transferred to the foreground, the sorting of this column is still incorrect.
In addition, the sorting results vary according to different browsers. Some browsers display rows according to the returned results, and some are in a disordered order.
The method I tried to make the datatable not to sort the event by default to execute the command is invalid. In this case, the system was supposed to convert the data that can be converted to the numeric type in the background to the numeric type in the output JSON.
Finally, we adopted this method:
Datatable supports the custom sorting function when defining columns. We write this as follows:
var sortfunc = function(a, b, desc) { var sort = table.get(‘sortBy‘); var field; for (var p in sort[0]) { field = p; } var avalue = a.get(field); var bvalue = b.get(field); var order; if (!isNaN(avalue) && !isNaN(bvalue)) { order = parseFloat(avalue) > parseFloat(bvalue) ? 1 : -1; } else { order = avalue > bvalue ? 1 : -1; } return desc ? -order : order; };
Processing during sorting. First, determine whether the data can be converted to a numeric type. If the data can be sorted by numeric type, the default sorting cannot be used.
In the defined column, specify the sortfn of the column as sortfunc.
The columns in my code are dynamically generated, So I handle them as follows:
var newcolumn = eval(data.header); newcolumn.each(function(k, v) { k.sortFn = unsortfunc;
});...... table = new Y.DataTable({ columns: newcolumn.concat(columns), scrollable: ‘x‘, width: ‘100%‘, data: [] }).render(‘#tablearea‘);
Columns is a fixed column, and newcolumn is a dynamic creation column.
In this way, the generated dynamic columns can be correctly sorted in the foreground.