Created
April 4, 2013 17:54
-
-
Save skoon/5312536 to your computer and use it in GitHub Desktop.
Row selector for SlickGrid that allows for drag selecting of rows.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function ($) { | |
// register namespace | |
$.extend(true, window, { | |
"Slick": { | |
"DragRowSelectionModel": DragRowSelectionModel | |
} | |
}); | |
function DragRowSelectionModel(options) { | |
var _grid; | |
var _ranges = []; | |
var _self = this; | |
var _options; | |
var _defaults = { | |
selectActiveRow: true | |
}; | |
var _dragging = false; | |
var _lastSelectedCell = 0; | |
function init(grid) { | |
_options = $.extend(true, {}, _defaults, options); | |
_grid = grid; | |
_grid.onActiveCellChanged.subscribe(handleActiveCellChange); | |
_grid.onKeyDown.subscribe(handleKeyDown); | |
_grid.onClick.subscribe(handleClick); | |
_grid.onDrag.subscribe(handleDrag); | |
_grid.onDragInit.subscribe(handleDragInit); | |
_grid.onDragStart.subscribe(handleDragStart); | |
_grid.onDragEnd.subscribe(handleDragEnd); | |
} | |
function destroy() { | |
_grid.onActiveCellChanged.unsubscribe(handleActiveCellChange); | |
_grid.onKeyDown.unsubscribe(handleKeyDown); | |
_grid.onClick.unsubscribe(handleClick); | |
_grid.onDrag.unsubscribe(handleDrag); | |
_grid.onDragInit.unsubscribe(handleDragInit); | |
_grid.onDragStart.unsubscribe(handleDragStart); | |
_grid.onDragEnd.unsubscribe(handleDragEnd); | |
} | |
function rangesToRows(ranges) { | |
var rows = []; | |
for (var i = 0; i < ranges.length; i++) { | |
for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) { | |
rows.push(j); | |
} | |
} | |
return rows; | |
} | |
function rowsToRanges(rows) { | |
var ranges = []; | |
var lastCell = _grid.getColumns().length - 1; | |
for (var i = 0; i < rows.length; i++) { | |
ranges.push(new Slick.Range(rows[i], 0, rows[i], lastCell)); | |
} | |
return ranges; | |
} | |
function getRowsRange(from, to) { | |
var i, rows = []; | |
for (i = from; i <= to; i++) { | |
rows.push(i); | |
} | |
for (i = to; i < from; i++) { | |
rows.push(i); | |
} | |
return rows; | |
} | |
function getSelectedRows() { | |
return rangesToRows(_ranges); | |
} | |
function setSelectedRows(rows) { | |
setSelectedRanges(rowsToRanges(rows)); | |
} | |
function setSelectedRanges(ranges) { | |
_ranges = ranges; | |
_self.onSelectedRangesChanged.notify(_ranges); | |
} | |
function getSelectedRanges() { | |
return _ranges; | |
} | |
function handleActiveCellChange(e, data) { | |
if (_options.selectActiveRow) { | |
setSelectedRanges([new Slick.Range(data.row, 0, data.row, _grid.getColumns().length - 1)]); | |
} | |
} | |
function handleKeyDown(e) { | |
var activeRow = _grid.getActiveCell(); | |
if (activeRow && e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey && (e.which == 38 || e.which == 40)) { | |
var selectedRows = getSelectedRows(); | |
selectedRows.sort(function (x, y) { return x - y }); | |
if (!selectedRows.length) { | |
selectedRows = [activeRow.row]; | |
} | |
var top = selectedRows[0]; | |
var bottom = selectedRows[selectedRows.length - 1]; | |
var active; | |
if (e.which == 40) { | |
active = activeRow.row < bottom || top == bottom ? ++bottom : ++top; | |
} | |
else { | |
active = activeRow.row < bottom ? --bottom : --top; | |
} | |
if (active >= 0 && active < _grid.getDataLength()) { | |
_grid.scrollRowIntoView(active); | |
_ranges = rowsToRanges(getRowsRange(top, bottom)); | |
setSelectedRanges(_ranges); | |
} | |
e.preventDefault(); | |
e.stopPropagation(); | |
} | |
} | |
function handleClick(e) { | |
var cell = _grid.getCellFromEvent(e); | |
if (!cell || !_grid.canCellBeActive(cell.row, cell.cell)) { | |
return false; | |
} | |
var selection = rangesToRows(_ranges); | |
var idx = $.inArray(cell.row, selection); | |
if (!e.ctrlKey && !e.shiftKey && !e.metaKey) { | |
return false; | |
} | |
else if (_grid.getOptions().multiSelect) { | |
if (idx === -1 && (e.ctrlKey || e.metaKey)) { | |
selection.push(cell.row); | |
_grid.setActiveCell(cell.row, cell.cell); | |
} | |
else if (idx !== -1 && (e.ctrlKey || e.metaKey)) { | |
selection = $.grep(selection, function (o, i) { return (o !== cell.row); }); | |
_grid.setActiveCell(cell.row, cell.cell); | |
} | |
else if (selection.length && e.shiftKey) { | |
var last = selection.pop(); | |
var from = Math.min(cell.row, last); | |
var to = Math.max(cell.row, last); | |
selection = []; | |
for (var i = from; i <= to; i++) { | |
if (i !== last) { | |
selection.push(i); | |
} | |
} | |
selection.push(last); | |
_grid.setActiveCell(cell.row, cell.cell); | |
} | |
} | |
_ranges = rowsToRanges(selection); | |
setSelectedRanges(_ranges); | |
e.stopImmediatePropagation(); | |
return true; | |
} | |
function handleDragInit(e) { | |
e.stopImmediatePropagation(); | |
} | |
function handleDragStart(e) { | |
e.stopImmediatePropagation(); | |
_dragging = true; | |
} | |
function handleDrag(e) { | |
if (_dragging) { | |
var cell = _grid.getCellFromEvent(e); | |
if (!cell || !_grid.canCellBeActive(cell.row, cell.cell)) | |
return false; | |
var selection = rangesToRows(_ranges); | |
var idx = $.inArray(cell.row, selection); | |
if (idx === -1) { | |
selection.push(cell.row); | |
_ranges = rowsToRanges(selection); | |
setSelectedRanges(_ranges); | |
} | |
} | |
} | |
function handleDragEnd(e) { | |
_dragging = false; | |
} | |
$.extend(this, { | |
"getSelectedRows": getSelectedRows, | |
"setSelectedRows": setSelectedRows, | |
"getSelectedRanges": getSelectedRanges, | |
"setSelectedRanges": setSelectedRanges, | |
"init": init, | |
"destroy": destroy, | |
"onSelectedRangesChanged": new Slick.Event() | |
}); | |
} | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment