From 6545243863fa065721118666836aab43c9642b3e Mon Sep 17 00:00:00 2001 From: Thomas Broadley Date: Mon, 3 Oct 2016 23:48:54 +0100 Subject: [PATCH 1/5] allow user to pass custom sorting function --- js/angular-tablesort.js | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/js/angular-tablesort.js b/js/angular-tablesort.js index d79d1bc..565afb5 100644 --- a/js/angular-tablesort.js +++ b/js/angular-tablesort.js @@ -84,9 +84,10 @@ tableSortModule.directive('tsWrapper', ['$parse', '$compile', function( $parse, return [$parse( expr ), null, false, name ? name : expr]; }; - this.setSortField = function( sortexpr, element, name ) { + this.setSortField = function( sortexpr, element, name, sortBy ) { var i; var expr = parse_sortexpr( sortexpr, name ); + expr.push(sortBy); if( $scope.sortExpression.length === 1 && $scope.sortExpression[0][0] === expr[0] ) { if( $scope.sortExpression[0][2] ) { @@ -119,10 +120,11 @@ tableSortModule.directive('tsWrapper', ['$parse', '$compile', function( $parse, } }; - this.addSortField = function( sortexpr, element, name ) { + this.addSortField = function( sortexpr, element, name, sortBy ) { var i; var toggle_order = false; var expr = parse_sortexpr( sortexpr, name ); + expr.push(sortBy); for( i=0; i<$scope.sortExpression.length; i=i+1 ) { if( $scope.sortExpression[i][0] === expr[0] ) { if( $scope.sortExpression[i][2] ) { @@ -269,8 +271,18 @@ tableSortModule.directive('tsWrapper', ['$parse', '$compile', function( $parse, return filteredArr; }; + function defaultSort(a, b) { + if (a > b) { + return 1; + } else if (a === b) { + return 0; + } else { + return -1; + } + } + $scope.sortFun = function( a, b ) { - var i, aval, bval, descending, filterFun; + var i, aval, bval, descending, filterFun, sortBy; for( i=0; i<$scope.sortExpression.length; i=i+1 ){ aval = $scope.sortExpression[i][0](a); bval = $scope.sortExpression[i][0](b); @@ -286,10 +298,11 @@ tableSortModule.directive('tsWrapper', ['$parse', '$compile', function( $parse, bval = ""; } descending = $scope.sortExpression[i][2]; - if( aval > bval ) { + sortBy = $scope.sortExpression[i][4] || defaultSort; + if( sortBy(aval, bval) === 1 ) { return descending ? -1 : 1; } - else if( aval < bval ) { + else if( sortBy(aval, bval) === -1 ) { return descending ? 1 : -1; } } @@ -356,23 +369,26 @@ tableSortModule.directive('tsWrapper', ['$parse', '$compile', function( $parse, tableSortModule.directive('tsCriteria', function() { return { require: "^tsWrapper", + scope: { + tsOrderBy: '=' + }, link: function(scope, element, attrs, tsWrapperCtrl) { var clickingCallback = function(event) { scope.$apply( function() { if( event.shiftKey ) { - tsWrapperCtrl.addSortField(attrs.tsCriteria, element, attrs.tsName); + tsWrapperCtrl.addSortField(attrs.tsCriteria, element, attrs.tsName, scope.tsOrderBy); } else { - tsWrapperCtrl.setSortField(attrs.tsCriteria, element, attrs.tsName); + tsWrapperCtrl.setSortField(attrs.tsCriteria, element, attrs.tsName, scope.tsOrderBy); } } ); }; element.bind('click', clickingCallback); element.addClass('tablesort-sortable'); if( "tsDefault" in attrs && attrs.tsDefault !== "0" ) { - tsWrapperCtrl.addSortField( attrs.tsCriteria, element, attrs.tsName ); + tsWrapperCtrl.addSortField( attrs.tsCriteria, element, attrs.tsName, scope.tsOrderBy ); if( attrs.tsDefault === "descending" ) { - tsWrapperCtrl.addSortField( attrs.tsCriteria, element, attrs.tsName ); + tsWrapperCtrl.addSortField( attrs.tsCriteria, element, attrs.tsName, scope.tsOrderBy ); } } if( "tsFilter" in attrs) { From 155b802fe157cb01567ef4a86c67a6e55715f2f7 Mon Sep 17 00:00:00 2001 From: Thomas Broadley Date: Mon, 3 Oct 2016 23:58:02 +0100 Subject: [PATCH 2/5] updated README.md to include custom sorting instructions --- README.md | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 820c5d3..3dc8544 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,7 @@ Empty Tables By default the content for the empty table cell is set to `"No Items"`, however it can be changed via the `noDataText` configuration option (see below). It is inserted as one `` spanning all columns and placed inside a ``, which is placed at the top of each table. -The message can be customized for each table by specifying the `ts-no-data-text` attribute on the same element as the `ts-wrapper`. +The message can be customized for each table by specifying the `ts-no-data-text` attribute on the same element as the `ts-wrapper`. ```html ``` @@ -195,7 +195,7 @@ angular filterString += ""; filterString += ""; tableSortConfigProvider.filterTemplate = filterString; - + var pagerString = "
"; pagerString += "Showing {{CURRENT_PAGE_RANGE}} {{FILTERED_COUNT === 0 ? '' : 'of'}} "; pagerString += "{{TOTAL_COUNT | number}} {{TOTAL_COUNT === 1 ? ITEM_NAME_SINGULAR : ITEM_NAME_PLURAL}}"; @@ -232,7 +232,7 @@ There are several tokens that can be used in the templates which will be replace The name of the things listed in the table can be displayed in the filtering and pagination templates. They are named `"items"` collectively and `"item"` individually by default, but this can be customized in the global config, and per-table to be more specific as to what is being listed. On a table just set the `ts-item-name` attribute on the same element as `ts-wrapper`. Set this as the singular version of the word, not the plural. - + ```html
``` @@ -274,7 +274,7 @@ Another approach is to add the `ts-filter-fields` attribute to the same element Set the `ts-per-page-options` attribute on the same element that `tw-wrapper` is set on to override the options for the number of items available per page. Set the `ts-per-page-default` attribute on the same element that `tw-wrapper` is set on to override the default number of items available per page. - + ```html
``` @@ -309,7 +309,7 @@ $scope.customFilterFn = function(item){ } }; ``` - + ```html
-``` \ No newline at end of file +``` + +### Customized Sorting + +It may be useful to customize how a particular column is sorted. For example, if a column can contain +numbers and strings, you may want the numbers to be sorted numerically and the strings to be sorted +lexicographically. To specify a custom sorting function, add a `ts-order-by` attribute to your +header element: + +```html +Name +``` + +The function specified in the `ts-order-by` attibute should behave in the same way as a custom comparison +function passed to `Array.prototype.sort`. See +[MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) +for more details. From 96197a7321ecebfbc2b45b6cea402235d00f4afa Mon Sep 17 00:00:00 2001 From: Thomas Broadley Date: Tue, 4 Oct 2016 00:12:40 +0100 Subject: [PATCH 3/5] add an example of custom sorting --- example.html | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/example.html b/example.html index 26aac53..115354d 100644 --- a/example.html +++ b/example.html @@ -84,6 +84,28 @@

Click Select to reveal item details.

+

Angular Tablesort with a custom sort function on the Price column

+ + + + + + + + + + + + + + + + + + + +
SelectIdNamePriceQuantity
{{item.Id}}{{item.Name}}{{item.Price | currency}}{{item.Quantity}}
+

Empty table

@@ -127,7 +149,7 @@

Empty table without "No data" row

- + @@ -139,7 +161,7 @@

Empty table without "No data" row

$scope.items = []; for(var i = 0; i<10; i++){ var idStr = (i < 10 ? "0" + i : i).toString(); - var nameStr = String.fromCharCode(65 + i); //gets alphabet chars + var nameStr = String.fromCharCode(65 + i) + String.fromCharCode(80 - i); //gets alphabet chars var priceStr = (Math.random()*100).toFixed(2); var qty = Math.floor(Math.random() * (25 - 1 + 1) + 1); $scope.items.push({ @@ -151,12 +173,32 @@

Empty table without "No data" row

selected: false }); } - + $scope.noitems = []; $scope.clickRow = function () { alert('You clicked the row.'); } + + function swapBeforeAndAfterDecimal(number) { + var beforeDecimal = Math.floor(number).toString(); + var afterDecimal = number.toString().replace(/.*\./, ''); + + return afterDecimal + '.' + beforeDecimal; + } + + $scope.centsThenDollars = function (a, b) { + var aSwapped = swapBeforeAndAfterDecimal(a); + var bSwapped = swapBeforeAndAfterDecimal(b); + + if (aSwapped > bSwapped) { + return 1; + } else if (aSwapped === bSwapped) { + return 0; + } else { + return -1; + } + } } ); From b63e4b603bee98c1cbac2afb7ae49ebb2560a1a4 Mon Sep 17 00:00:00 2001 From: Thomas Broadley Date: Tue, 4 Oct 2016 00:15:44 +0100 Subject: [PATCH 4/5] undo unnecessary change to example --- example.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example.html b/example.html index 115354d..67139a2 100644 --- a/example.html +++ b/example.html @@ -161,7 +161,7 @@

Empty table without "No data" row

$scope.items = []; for(var i = 0; i<10; i++){ var idStr = (i < 10 ? "0" + i : i).toString(); - var nameStr = String.fromCharCode(65 + i) + String.fromCharCode(80 - i); //gets alphabet chars + var nameStr = String.fromCharCode(65 + i); //gets alphabet chars var priceStr = (Math.random()*100).toFixed(2); var qty = Math.floor(Math.random() * (25 - 1 + 1) + 1); $scope.items.push({ From 1c6202bea07cb8d411cf581951eac438d8ac246d Mon Sep 17 00:00:00 2001 From: Thomas Broadley Date: Tue, 4 Oct 2016 00:40:29 +0100 Subject: [PATCH 5/5] change function declaration formatting --- js/angular-tablesort.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/angular-tablesort.js b/js/angular-tablesort.js index 565afb5..9744240 100644 --- a/js/angular-tablesort.js +++ b/js/angular-tablesort.js @@ -271,7 +271,7 @@ tableSortModule.directive('tsWrapper', ['$parse', '$compile', function( $parse, return filteredArr; }; - function defaultSort(a, b) { + function defaultSort( a, b ) { if (a > b) { return 1; } else if (a === b) {