Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi column sort support with an example #276

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions examples/example-multi-column-sort.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>SlickGrid example: Multi Column Sort</title>
<link rel="stylesheet" href="../slick.grid.css" type="text/css"/>
<link rel="stylesheet" href="../css/smoothness/jquery-ui-1.8.16.custom.css" type="text/css"/>
<link rel="stylesheet" href="examples.css" type="text/css"/>
</head>
<body>
<table width="100%">
<tr>
<td valign="top" width="50%">
<div id="myGrid" style="width:600px;height:500px;display:none;"></div>
</td>
<td valign="top">
<h2>Demonstrates:</h2>
<ul>
<li>basic grid with multi column sort option</li>
</ul>
</td>
</tr>
</table>

<script src="../lib/jquery-1.7.min.js"></script>
<script src="../lib/jquery.event.drag-2.0.min.js"></script>

<script src="../slick.core.js"></script>
<script src="../slick.grid.js"></script>

<script>
var grid;
var columns = [
{ id: "title", name: "Title", field: "title", sortable: true },
{ id: "duration", name: "Duration", field: "duration", sortable: true, formatter: dayFormatter },
{ id: "%", name: "% Complete", field: "percentComplete", sortable: true },
{ id: "start", name: "Start", field: "start", formatter: dateFormatter, sortable: true },
{ id: "finish", name: "Finish", field: "finish", formatter: dateFormatter, sortable: true },
{ id: "effort-driven", name: "Effort Driven", field: "effortDriven", sortable: true }
];

function dayFormatter(row, cell, value, columnDef, dataContext) {
return value + ' days';
}

function dateFormatter(row, cell, value, columnDef, dataContext) {
return value.getMonth() + '/' + value.getDate() + '/' + value.getFullYear();
}

var options = {
enableCellNavigation: true,
enableColumnReorder: false,
multiSort: true
};

$(function () {
var data = [];
for (var i = 0; i < 500; i++) {
var startdate = new Date(new Date("1/1/1980").getTime() + Math.round(Math.random() * 365 * 25)*24*60*60*1000);
var endDate = new Date(startdate.getTime() + Math.round(Math.random() * 365) * 24 * 60 * 60 * 1000);
data[i] = {
title: "Task " + i,
duration: Math.round(Math.random() * 30) + 2,
percentComplete: Math.round(Math.random() * 100),
start: startdate,
finish: endDate,
effortDriven: (i % 5 == 0)
};
}

grid = new Slick.Grid("#myGrid", data, columns, options);

grid.onSort.subscribe(function (e, cols) {
data.sort(function (dataRow1, dataRow2) {
for (var i = 0, l = cols.length; i < l; i++) {
var field = cols[i].column.field;
var sign = cols[i].sortAsc ? 1 : -1;
var value1 = dataRow1[field], value2 = dataRow2[field];
var result = (value1 == value2 ? 0 : (value1 > value2 ? 1 : -1)) * sign;
if (result != 0) {
return result;
}
}
return 0;
});
grid.setData(data);
grid.invalidateAllRows();
grid.render();
});

$("#myGrid").show();
})
</script>
</body>
</html>
87 changes: 69 additions & 18 deletions slick.grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ if (typeof Slick === "undefined") {
multiSelect: true,
enableTextSelectionOnCells: false,
dataItemColumnValueExtractor: null,
fullWidthRows: false
fullWidthRows: false,
multiSort: false
};

var columnDefaults = {
Expand Down Expand Up @@ -150,8 +151,8 @@ if (typeof Slick === "undefined") {
var cellCssClasses = {};

var columnsById = {};
var sortColumnId;
var sortAsc = true;
var sortColumns = [];


// async call handles
var h_editorLoader = null;
Expand Down Expand Up @@ -468,7 +469,7 @@ if (typeof Slick === "undefined") {
}
}

setSortColumn(sortColumnId, sortAsc);
setSortColumn();
setupColumnResize();
if (options.enableColumnReorder) {
setupColumnReorder();
Expand All @@ -492,15 +493,37 @@ if (typeof Slick === "undefined") {
return;
}

if (column.id === sortColumnId) {
sortAsc = !sortAsc;
} else {
sortColumnId = column.id;
sortAsc = true;
var sortOpts = null;

for (var i in sortColumns) {
if (sortColumns[i].id == column.id) {
sortOpts = sortColumns[i];
sortOpts.sortAsc = !sortOpts.sortAsc;
break;
}
}

if ((!e.shiftKey && !e.ctrlKey) || !options.multiSort) {
sortColumns.length = 0;
}

if (!sortOpts) {
sortOpts = { id: column.id, sortAsc: true };
sortColumns.push(sortOpts);
} else if (sortColumns.length == 0) {
sortColumns.push(sortOpts);
}

setSortColumn(sortColumnId, sortAsc);
trigger(self.onSort, {sortCol: column, sortAsc: sortAsc}, e);
setSortColumn();

if (!options.multiSort) {
trigger(self.onSort, {sortCol: column, sortAsc: sortOpts.sortAsc}, e);
} else {
trigger(self.onSort, $.map(sortColumns, function(col) {
var colIndex = getColumnIndex(col.id);
return typeof colIndex === 'number' ? {column: columns[colIndex], sortAsc: col.sortAsc } : null;
}), e);
}
}
});
}
Expand Down Expand Up @@ -942,19 +965,47 @@ if (typeof Slick === "undefined") {
}

function setSortColumn(columnId, ascending) {
sortColumnId = columnId;
sortAsc = ascending;
var columnIndex = getColumnIndex(sortColumnId);

// accept multiple columns as 1st arg
if (columnId instanceof Array) {
sortColumns.length = 0;

$.each(columnId, function(i, col) {
switch (typeof col) {
case 'string': // accept column ids instead of object ([id1, id2])
sortColumns.push({ id: col, sortAsc: true });
break;
case 'object':
if (typeof col.id !== 'string' || col.id.length == 0) {
throw new SyntaxError('setSortColumn: missing column id');
}
if (typeof col.sortAsc !== 'boolean') {
col.sortAsc = col.sortAsc ? true : false;
}
sortColumns.push(col);
break;
}
});

// allow old syntax too
} else if (typeof columnId === 'string') {
sortColumns.length = 0;
sortColumns.push({ id: columnId, sortAsc: (typeof ascending === 'boolean' ? ascending : (ascending ? true : false)) });
}
// else simply update from sortColumns

$headers.children().removeClass("slick-header-column-sorted");
$headers.find(".slick-sort-indicator").removeClass("slick-sort-indicator-asc slick-sort-indicator-desc");

if (columnIndex != null) {
$headers.children().eq(columnIndex)
$.each(sortColumns, function(i, col) {
var columnIndex = getColumnIndex(col.id);
if (columnIndex != null) {
$headers.children().eq(columnIndex)
.addClass("slick-header-column-sorted")
.find(".slick-sort-indicator")
.addClass(sortAsc ? "slick-sort-indicator-asc" : "slick-sort-indicator-desc");
}
.addClass(col.sortAsc ? "slick-sort-indicator-asc" : "slick-sort-indicator-desc");
}
});
}

function handleSelectedRangesChanged(e, ranges) {
Expand Down