Skip to content

Commit 3eca46e

Browse files
author
Greg Maslov
committed
feat(core): add sortDirectionCycle column option
This option allows you to specify how a column's sort direction should be cycled as the heading is repeatedly clicked. The default value, [null,ASC,DESC], preserves the existing behavior.
1 parent f137022 commit 3eca46e

File tree

4 files changed

+80
-14
lines changed

4 files changed

+80
-14
lines changed

Diff for: misc/tutorial/102_sorting.ngdoc

+4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ data has changed by calling `gridApi.core.notifyDataChange( uiGridConstants.data
2525
If you set a default sort, you can prevent the user from removing that sort by setting `suppressRemoveSort: true`
2626
for that column. This will let the user change the direction of the sort, but take away the option to remove the sort.
2727

28+
When clicking on a column heading the sort direction will cycle to ascending, then descending, then back to unsorted.
29+
You may rearrange this cycle or skip part of it by setting the
30+
{@link api/ui.grid.class:GridOptions.columnDef#sortDirectionCycle sortDirectionCycle} columnDef option.
31+
2832
The sort algorithm is chosen based on the column type. ui-grid will guess the type based on the data, although if you load data
2933
asynchronously after the columns it will often decide all your columns are string. You can explicitly set the column type in the
3034
column def using `type='number'`. Valid types are documented in {@link api/ui.grid.class:GridOptions.columnDef columnDef}, and

Diff for: src/js/core/factories/Grid.js

+15-13
Original file line numberDiff line numberDiff line change
@@ -1921,7 +1921,8 @@ angular.module('ui.grid')
19211921
* Emits the sortChanged event whenever the sort criteria are changed.
19221922
* @param {GridColumn} column Column to set the sorting on
19231923
* @param {uiGridConstants.ASC|uiGridConstants.DESC} [direction] Direction to sort by, either descending or ascending.
1924-
* If not provided, the column will iterate through the sort directions: ascending, descending, unsorted.
1924+
* If not provided, the column will iterate through the sort directions
1925+
* specified in the {@link ui.grid.class:GridOptions.columnDef#sortDirectionCycle sortDirectionCycle} attribute.
19251926
* @param {boolean} [add] Add this column to the sorting. If not provided or set to `false`, the Grid will reset any existing sorting and sort
19261927
* by this column only
19271928
* @returns {Promise} A resolved promise that supplies the column.
@@ -1955,19 +1956,20 @@ angular.module('ui.grid')
19551956
}
19561957

19571958
if (!direction) {
1958-
// Figure out the sort direction
1959-
if (column.sort.direction && column.sort.direction === uiGridConstants.ASC) {
1960-
column.sort.direction = uiGridConstants.DESC;
1959+
// Find the current position in the cycle (or -1).
1960+
var i = column.sortDirectionCycle.indexOf(column.sort.direction ? column.sort.direction : null);
1961+
// Proceed to the next position in the cycle (or start at the beginning).
1962+
i = (i+1) % column.sortDirectionCycle.length;
1963+
// If suppressRemoveSort is set, and the next position in the cycle would
1964+
// remove the sort, skip it.
1965+
if (column.colDef && column.suppressRemoveSort && !column.sortDirectionCycle[i]) {
1966+
i = (i+1) % column.sortDirectionCycle.length;
19611967
}
1962-
else if (column.sort.direction && column.sort.direction === uiGridConstants.DESC) {
1963-
if ( column.colDef && column.suppressRemoveSort ){
1964-
column.sort.direction = uiGridConstants.ASC;
1965-
} else {
1966-
column.sort = {};
1967-
}
1968-
}
1969-
else {
1970-
column.sort.direction = uiGridConstants.ASC;
1968+
1969+
if (column.sortDirectionCycle[i]) {
1970+
column.sort.direction = column.sortDirectionCycle[i];
1971+
} else {
1972+
column.sort = {};
19711973
}
19721974
}
19731975
else {

Diff for: src/js/core/factories/GridColumn.js

+20-1
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ angular.module('ui.grid')
272272
*
273273
*/
274274

275-
/**
275+
/**
276276
* @ngdoc property
277277
* @name sort
278278
* @propertyOf ui.grid.class:GridOptions.columnDef
@@ -651,6 +651,25 @@ angular.module('ui.grid')
651651
self.enableSorting = typeof(colDef.enableSorting) !== 'undefined' ? colDef.enableSorting : true;
652652
self.sortingAlgorithm = colDef.sortingAlgorithm;
653653

654+
/**
655+
* @ngdoc property
656+
* @name sortDirectionCycle
657+
* @propertyOf ui.grid.class:GridOptions.columnDef
658+
* @description (optional) An array of sort directions, specifying the order that they
659+
* should cycle through as the user repeatedly clicks on the column heading.
660+
* The default is `[null, uiGridConstants.ASC, uiGridConstants.DESC]`. Null
661+
* refers to the unsorted state. This does not affect the initial sort
662+
* direction; use the {@link ui.grid.class:GridOptions.columnDef#sort sort}
663+
* property for that. If
664+
* {@link ui.grid.class:GridOptions.columnDef#suppressRemoveSort suppressRemoveSort}
665+
* is also set, the unsorted state will be skipped even if it is listed here.
666+
* Each direction may not appear in the list more than once (e.g. `[ASC,
667+
* DESC, DESC]` is not allowed), and the list may not be empty.
668+
*/
669+
self.sortDirectionCycle = typeof(colDef.sortDirectionCycle) !== 'undefined' ?
670+
colDef.sortDirectionCycle :
671+
[null, uiGridConstants.ASC, uiGridConstants.DESC];
672+
654673
/**
655674
* @ngdoc boolean
656675
* @name suppressRemoveSort

Diff for: test/unit/core/factories/Grid.spec.js

+41
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,47 @@ describe('Grid factory', function () {
786786
expect( column.sort.priority ).toEqual(2);
787787
expect( priorColumn.sort ).toEqual({ direction: uiGridConstants.ASC, priority: 1});
788788
});
789+
790+
it( 'if sortDirectionCycle is null-DESC-ASC, and sort is currently null, then should toggle to DESC, and reset priority', function() {
791+
column.sort = {};
792+
column.sortDirectionCycle = [null, uiGridConstants.DESC, uiGridConstants.ASC];
793+
794+
grid.sortColumn( column, false );
795+
796+
expect( column.sort.direction ).toEqual(uiGridConstants.DESC);
797+
expect( column.sort.priority ).toEqual(1);
798+
});
799+
800+
it( 'if sortDirectionCycle is null-DESC-ASC, and sort is currently ASC, then should toggle to null, and remove priority', function() {
801+
column.sort = {direction: uiGridConstants.ASC, priority: 1};
802+
column.sortDirectionCycle = [null, uiGridConstants.DESC, uiGridConstants.ASC];
803+
804+
grid.sortColumn( column, false );
805+
806+
expect( column.sort.direction ).toEqual(null);
807+
expect( column.sort.priority ).toEqual(null);
808+
});
809+
810+
it( 'if sortDirectionCycle is DESC, and sort is currently DESC, then should not change the sort', function() {
811+
column.sort = {direction: uiGridConstants.DESC, priority: 1};
812+
column.sortDirectionCycle = [uiGridConstants.DESC];
813+
814+
grid.sortColumn( column, false );
815+
816+
expect( column.sort.direction ).toEqual(uiGridConstants.DESC);
817+
expect( column.sort.priority ).toEqual(1);
818+
});
819+
820+
it( 'if sortDirectionCycle is DESC-null-ASC, and sort is currently DESC, and suppressRemoveSort is true, then should toggle to ASC, and reset priority', function() {
821+
column.sort = {direction: uiGridConstants.DESC, priority: 1};
822+
column.sortDirectionCycle = [uiGridConstants.DESC, null, uiGridConstants.ASC];
823+
column.suppressRemoveSort = true;
824+
825+
grid.sortColumn( column, false );
826+
827+
expect( column.sort.direction ).toEqual(uiGridConstants.ASC);
828+
expect( column.sort.priority ).toEqual(1);
829+
});
789830
});
790831

791832

0 commit comments

Comments
 (0)