diff options
-rw-r--r-- | examples/example3-editing.html | 45 | ||||
-rw-r--r-- | plugins/slick.cellrangeselector.js | 127 | ||||
-rw-r--r-- | plugins/slick.cellselectionmodel.js | 117 | ||||
-rw-r--r-- | plugins/slick.rowmovemanager.js | 20 | ||||
-rw-r--r-- | slick.editors.js | 8 | ||||
-rw-r--r-- | slick.grid.js | 2 |
6 files changed, 204 insertions, 115 deletions
diff --git a/examples/example3-editing.html b/examples/example3-editing.html index 9dc8011..bad4149 100644 --- a/examples/example3-editing.html +++ b/examples/example3-editing.html @@ -42,6 +42,8 @@ <script language="JavaScript" src="../lib/jquery.event.drag-2.0.min.js"></script> <script language="JavaScript" src="../slick.core.js"></script> + <script language="JavaScript" src="../plugins/slick.cellrangeselector.js"></script> + <script language="JavaScript" src="../plugins/slick.cellselectionmodel.js"></script> <script language="JavaScript" src="../slick.editors.js"></script> <script language="JavaScript" src="../slick.grid.js"></script> @@ -58,7 +60,7 @@ var columns = [ {id:"title", name:"Title", field:"title", width:120, cssClass:"cell-title", editor:TextCellEditor, validator:requiredFieldValidator}, {id:"desc", name:"Description", field:"description", width:100, editor:LongTextCellEditor}, - {id:"duration", name:"Duration", field:"duration", editor:TextCellEditor}, + {id:"duration", name:"Duration", field:"duration", editor:FormulaEditor}, {id:"%", name:"% Complete", field:"percentComplete", width:80, resizable:false, formatter:GraphicalPercentCompleteCellFormatter, editor:PercentCompleteCellEditor}, {id:"start", name:"Start", field:"start", minWidth:60, editor:DateCellEditor}, {id:"finish", name:"Finish", field:"finish", minWidth:60, editor:DateCellEditor}, @@ -72,6 +74,43 @@ autoEdit: false }; + + /*** + * A proof-of-concept cell editor with Excel-like range selection and insertion. + */ + function FormulaEditor(args) { + var _self = this; + var _editor = new TextCellEditor(args); + var _selector; + + $.extend(this, _editor); + + function init() { + // register a plugin to select a range and append it to the textbox + // since events are fired in reverse order (most recently added are executed first), + // this will override other plugins like moverows or selection model and will + // not require the grid to not be in the edit mode + _selector = new Slick.CellRangeSelector(); + _selector.onCellRangeSelected.subscribe(_self.handleCellRangeSelected); + args.grid.registerPlugin(_selector); + } + + this.destroy = function() { + _selector.onCellRangeSelected.unsubscribe(_self.handleCellRangeSelected); + grid.unregisterPlugin(_selector); + _editor.destroy(); + }; + + this.handleCellRangeSelected = function(e, args) { + _editor.setValue(_editor.getValue() + args.range); + }; + + + init(); + } + + + $(function() { for (var i=0; i<500; i++) { @@ -88,6 +127,10 @@ grid = new Slick.Grid("#myGrid", data, columns, options); + //grid.registerPlugin(new Slick.CellRangeSelector()); + + grid.setSelectionModel(new Slick.CellSelectionModel()); + grid.onAddNewRow.subscribe(function(e, args) { var item = args.item; var column = args.column; diff --git a/plugins/slick.cellrangeselector.js b/plugins/slick.cellrangeselector.js new file mode 100644 index 0000000..ade3135 --- /dev/null +++ b/plugins/slick.cellrangeselector.js @@ -0,0 +1,127 @@ +(function($) { + // register namespace + $.extend(true, window, { + "Slick": { + "CellRangeSelector": CellRangeSelector + } + }); + + + function CellRangeSelector(options) { + var _grid; + var _canvas; + var _dragging; + var _self = this; + var _defaults = { + selectionCss: { + "border": "2px dashed blue" + } + }; + + + function init(grid) { + options = $.extend(true, {}, _defaults, options); + _grid = grid; + _canvas = _grid.getCanvasNode(); + _grid.onDragStart.subscribe(handleDragStart); + _grid.onDrag.subscribe(handleDrag); + _grid.onDragEnd.subscribe(handleDragEnd); + } + + function destroy() { + _grid.onDragStart.unsubscribe(handleDragStart); + _grid.onDrag.unsubscribe(handleDrag); + _grid.onDragEnd.unsubscribe(handleDragEnd); + } + + function fixUpRange(range) { + var r1 = Math.min(range.start.row,range.end.row); + var c1 = Math.min(range.start.cell,range.end.cell); + var r2 = Math.max(range.start.row,range.end.row); + var c2 = Math.max(range.start.cell,range.end.cell); + return { + start: {row:r1, cell:c1}, + end: {row:r2, cell:c2} + }; + } + + function handleDragStart(e,dd) { + var cell = _grid.getCellFromEvent(e); + if (_self.onBeforeCellRangeSelected.notify(cell) !== false) { + if (_grid.canCellBeSelected(cell.row,cell.cell)) { + _dragging = true; + e.stopImmediatePropagation(); + } + } + if (!_dragging) { + return; + } + + var start = _grid.getCellFromPoint( + dd.startX - $(_canvas).offset().left, + dd.startY - $(_canvas).offset().top); + + dd.range = {start:start,end:{}}; + + // TODO: use a decorator + return $("<div></div>", {css: options.selectionCss}) + .css("position", "absolute") + .appendTo(_canvas); + } + + function handleDrag(e,dd) { + if (!_dragging) { + return; + } + + e.stopImmediatePropagation(); + + var end = _grid.getCellFromPoint( + e.pageX - $(_canvas).offset().left, + e.pageY - $(_canvas).offset().top); + + if (!_grid.canCellBeSelected(end.row,end.cell)) { + return; + } + + dd.range.end = end; + var r = fixUpRange(dd.range); + var from = _grid.getCellNodeBox(r.start.row,r.start.cell); + var to = _grid.getCellNodeBox(r.end.row,r.end.cell); + + $(dd.proxy).css({ + top: from.top - 1, + left: from.left - 1, + height: to.bottom - from.top - 2, + width: to.right - from.left - 2 + }); + } + + function handleDragEnd(e,dd) { + if (!_dragging) { + return; + } + + _dragging = false; + e.stopImmediatePropagation(); + $(dd.proxy).remove(); + + _self.onCellRangeSelected.notify({ + range: new Slick.Range( + dd.range.start.row, + dd.range.start.cell, + dd.range.end.row, + dd.range.end.cell + ) + }); + } + + $.extend(this, { + "init": init, + "destroy": destroy, + + "onBeforeCellRangeSelected": new Slick.Event(), + "onCellRangeSelected": new Slick.Event() + }); + } +})(jQuery);
\ No newline at end of file diff --git a/plugins/slick.cellselectionmodel.js b/plugins/slick.cellselectionmodel.js index 0407de1..d1e68da 100644 --- a/plugins/slick.cellselectionmodel.js +++ b/plugins/slick.cellselectionmodel.js @@ -11,29 +11,27 @@ var _grid; var _canvas; var _ranges = []; - var _dragging; var _self = this; - - function returnFalse() { - return false; - } + var _selector = new Slick.CellRangeSelector({ + "selectionCss": { + "border": "2px solid black" + } + }); function init(grid) { _grid = grid; _canvas = _grid.getCanvasNode(); _grid.onActiveCellChanged.subscribe(handleActiveCellChange); - _grid.onDragInit.subscribe(handleDragInit); - _grid.onDragStart.subscribe(handleDragStart); - _grid.onDrag.subscribe(handleDrag); - _grid.onDragEnd.subscribe(handleDragEnd); + grid.registerPlugin(_selector); + _selector.onCellRangeSelected.subscribe(handleCellRangeSelected); + _selector.onBeforeCellRangeSelected.subscribe(handleBeforeCellRangeSelected); } function destroy() { _grid.onActiveCellChanged.unsubscribe(handleActiveCellChange); - _grid.onDragInit.unsubscribe(handleDragInit); - _grid.onDragStart.unsubscribe(handleDragStart); - _grid.onDrag.unsubscribe(handleDrag); - _grid.onDragEnd.unsubscribe(handleDragEnd); + _selector.onCellRangeSelected.unsubscribe(handleCellRangeSelected); + _selector.onBeforeCellRangeSelected.unsubscribe(handleBeforeCellRangeSelected); + _grid.unregisterPlugin(_selector); } function removeInvalidRanges(ranges) { @@ -51,99 +49,26 @@ function setSelectedRanges(ranges) { _ranges = removeInvalidRanges(ranges); - _self.onSelectedRangesChanged.notify(_ranges); } + _self.onSelectedRangesChanged.notify(_ranges); + } function getSelectedRanges() { return _ranges; } - function fixUpRange(range) { - var r1 = Math.min(range.start.row,range.end.row); - var c1 = Math.min(range.start.cell,range.end.cell); - var r2 = Math.max(range.start.row,range.end.row); - var c2 = Math.max(range.start.cell,range.end.cell); - return { - start: {row:r1, cell:c1}, - end: {row:r2, cell:c2} - }; - } - - function handleDragInit(e,dd) { - var cell = _grid.getCellFromEvent(e); - - if (!_grid.getEditorLock().isActive()) { - if (_grid.canCellBeSelected(cell.row,cell.cell)/* && e.ctrlKey*/) { - _dragging = true; - e.stopImmediatePropagation(); - } - } - } - - function handleDragStart(e,dd) { - if (!_dragging) { - return; - } - - var start = _grid.getCellFromPoint( - dd.startX - $(_canvas).offset().left, - dd.startY - $(_canvas).offset().top); - - e.stopImmediatePropagation(); - - dd.range = {start:start,end:{}}; - - return $("<div class='slick-selection'></div>").appendTo(_canvas); - } - - function handleDrag(e,dd) { - if (!_dragging) { - return; - } - - e.stopImmediatePropagation(); - - var end = _grid.getCellFromPoint( - e.pageX - $(_canvas).offset().left, - e.pageY - $(_canvas).offset().top); - - if (!_grid.canCellBeSelected(end.row,end.cell)) { - return; + function handleBeforeCellRangeSelected(e, args) { + if (_grid.getEditorLock().isActive()) { + e.stopPropagation(); + return false; } - - dd.range.end = end; - var r = fixUpRange(dd.range); - var from = _grid.getCellNodeBox(r.start.row,r.start.cell); - var to = _grid.getCellNodeBox(r.end.row,r.end.cell); - - $(dd.proxy).css({ - top: from.top - 1, - left: from.left - 1, - height: to.bottom - from.top - 2, - width: to.right - from.left - 2 - }); } - function handleDragEnd(e,dd) { - if (!_dragging) { - return; - } - - _dragging = false; - e.stopImmediatePropagation(); - $(dd.proxy).remove(); - - setSelectedRanges([ - new Slick.Range( - dd.range.start.row, - dd.range.start.cell, - dd.range.end.row, - dd.range.end.cell - ) - ]); + function handleCellRangeSelected(e, args) { + setSelectedRanges([args.range]); } - function handleActiveCellChange(e, data) { - setSelectedRanges([new Slick.Range(data.row,data.cell)]); + function handleActiveCellChange(e, args) { + setSelectedRanges([new Slick.Range(args.row,args.cell)]); } $.extend(this, { diff --git a/plugins/slick.rowmovemanager.js b/plugins/slick.rowmovemanager.js index 6b037ac..4ecb279 100644 --- a/plugins/slick.rowmovemanager.js +++ b/plugins/slick.rowmovemanager.js @@ -15,38 +15,26 @@ function init(grid) { _grid = grid; _canvas = _grid.getCanvasNode(); - _grid.onDragInit.subscribe(handleDragInit); _grid.onDragStart.subscribe(handleDragStart); _grid.onDrag.subscribe(handleDrag); _grid.onDragEnd.subscribe(handleDragEnd); } function destroy() { - _grid.onDragInit.unsubscribe(handleDragInit); _grid.onDragStart.unsubscribe(handleDragStart); _grid.onDrag.unsubscribe(handleDrag); _grid.onDragEnd.unsubscribe(handleDragEnd); } - function handleDragInit(e,dd) { - var cell = _grid.getCellFromEvent(e); - - if (!_grid.getEditorLock().isActive()) { - if (/move|selectAndMove/.test(_grid.getColumns()[cell.cell].behavior)) { - _dragging = true; - e.stopImmediatePropagation(); - } - } - } - function handleDragStart(e,dd) { - if (!_dragging) { - return; + var cell = _grid.getCellFromEvent(e); + if (_grid.getEditorLock().isActive() || !/move|selectAndMove/.test(_grid.getColumns()[cell.cell].behavior)) { + return false; } + _dragging = true; e.stopImmediatePropagation(); - var cell = _grid.getCellFromEvent(e); var selectedRows = _grid.getSelectedRows(); if (selectedRows.length == 0 || $.inArray(cell.row, selectedRows) == -1) { diff --git a/slick.editors.js b/slick.editors.js index 04bd33d..a458195 100644 --- a/slick.editors.js +++ b/slick.editors.js @@ -90,6 +90,14 @@ $input.focus(); }; + this.getValue = function() { + return $input.val(); + }; + + this.setValue = function(val) { + $input.val(val); + }; + this.loadValue = function(item) { defaultValue = item[args.column.field] || ""; $input.val(defaultValue); diff --git a/slick.grid.js b/slick.grid.js index b4e9994..8a5a0af 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -1391,8 +1391,6 @@ if (typeof Slick === "undefined") { if (e.isImmediatePropagationStopped()) { return retval; } - - return false; } function handleDragStart(e,dd) { |