Skip to content

Commit

Permalink
Allow sorting by multiple columns (by holding shift)
Browse files Browse the repository at this point in the history
  • Loading branch information
Robinson7D committed May 15, 2015
1 parent 448d1d6 commit f1e057a
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 20 deletions.
20 changes: 13 additions & 7 deletions src/js/headerRenderer.js
Expand Up @@ -310,20 +310,26 @@ HeaderRenderer.prototype.createHeaderCell = function(column, grouped, headerGrou
HeaderRenderer.prototype.addSortHandling = function(headerCellLabel, colDefWrapper) {
var that = this;

headerCellLabel.addEventListener("click", function() {
headerCellLabel.addEventListener("click", function(e) {

// update sort on current col
if (colDefWrapper.sort === constants.ASC) {
colDefWrapper.sort = constants.DESC;
} else if (colDefWrapper.sort === constants.DESC) {
if (colDefWrapper.sort === constants.DESC) {
colDefWrapper.sort = null
} else {
colDefWrapper.sort = constants.ASC;
}
else {
if (colDefWrapper.sort === constants.ASC) {
colDefWrapper.sort = constants.DESC;
} else {
colDefWrapper.sort = constants.ASC;
}
// Useful for determining the order in which the user sorted the columns:
colDefWrapper.sortedAt = new Date().valueOf();
}

// clear sort on all columns except this one, and update the icons
that.columnModel.getAllColumns().forEach(function(columnToClear) {
if (columnToClear !== colDefWrapper) {
// Do not clear if either holding shift, or if column in question was clicked
if (!(e.shiftKey || columnToClear === colDefWrapper)) {
columnToClear.sort = null;
}

Expand Down
43 changes: 30 additions & 13 deletions src/js/inMemoryRowController.js
Expand Up @@ -137,20 +137,27 @@ InMemoryRowController.prototype.recursivelyCreateAggData = function(nodes, group
// private
InMemoryRowController.prototype.doSort = function() {
//see if there is a col we are sorting by
var columnForSorting = null;
var sortingOptions = [];
this.columnModel.getAllColumns().forEach(function(column) {
if (column.sort) {
columnForSorting = column;
var ascending = column.sort === constants.ASC;
sortingOptions.push({
inverter: ascending ? 1 : -1,
sortedAt: column.sortedAt,
colDef: column.colDef
});
}
});

var rowNodesBeforeSort = this.rowsAfterFilter.slice(0);
// The columns are to be sorted in the order that the user selected them:
sortingOptions.sort(function(optionA, optionB){
return optionA.sortedAt - optionB.sortedAt;
});

if (columnForSorting) {
var ascending = columnForSorting.sort === constants.ASC;
var inverter = ascending ? 1 : -1;
var rowNodesBeforeSort = this.rowsAfterFilter.slice(0);

this.sortList(rowNodesBeforeSort, columnForSorting.colDef, inverter);
if (sortingOptions.length) {
this.sortList(rowNodesBeforeSort, sortingOptions);
} else {
// if no sorting, set all group children after sort to the original list
this.recursivelyResetSort(rowNodesBeforeSort);
Expand All @@ -171,7 +178,7 @@ InMemoryRowController.prototype.recursivelyResetSort = function(rowNodes) {
};

// private
InMemoryRowController.prototype.sortList = function(nodes, colDef, inverter) {
InMemoryRowController.prototype.sortList = function(nodes, sortOptions) {

// sort any groups recursively
for (var i = 0, l = nodes.length; i < l; i++) { // critical section, no functional programming
Expand All @@ -183,19 +190,29 @@ InMemoryRowController.prototype.sortList = function(nodes, colDef, inverter) {
}

var that = this;
nodes.sort(function(objA, objB) {

function compare(objA, objB, colDef){
var valueA = that.getValue(objA.data, colDef, objA);
var valueB = that.getValue(objB.data, colDef, objB);

if (colDef.comparator) {
//if comparator provided, use it
return colDef.comparator(valueA, valueB, objA, objB) * inverter;
return colDef.comparator(valueA, valueB, objA, objB);
} else {
//otherwise do our own comparison
return utils.defaultComparator(valueA, valueB, objA, objB) * inverter;
return utils.defaultComparator(valueA, valueB, objA, objB);
}
}

nodes.sort(function(objA, objB) {
// Iterate columns, return the first that doesn't match
for(var i = 0, len = sortOptions.length; i < len; i++){
var sortOption = sortOptions[i];
var compared = compare(objA, objB, sortOption.colDef);
if(compared !== 0){
return compared * sortOption.inverter;
}
}
// All matched, these are identical as far as the sort is concerned:
return 0;
});
};

Expand Down

0 comments on commit f1e057a

Please sign in to comment.