1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456 |
- /*
- Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
- Available via Academic Free License >= 2.1 OR the modified BSD license.
- see: http://dojotoolkit.org/license for details
- */
- if(!dojo._hasResource["dojox.grid.enhanced.plugins.Selector"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
- dojo._hasResource["dojox.grid.enhanced.plugins.Selector"] = true;
- dojo.provide("dojox.grid.enhanced.plugins.Selector");
- dojo.require("dojox.grid.enhanced._Plugin");
- dojo.require("dojox.grid.enhanced.plugins.AutoScroll");
- dojo.require("dojox.grid.cells._base");
- (function(){
- /*=====
- dojo.declare("__SelectItem", null,{
- // summary:
- // An abstract representation of an item.
- });
- dojo.declare("__SelectCellItem", __SelectItem,{
- // summary:
- // An abstract representation of a cell.
-
- // row: Integer
- // Row index of this cell
- row: 0,
-
- // col: Integer
- // Column index of this cell
- col: 0
- });
- dojo.declare("__SelectRowItem", __SelectItem,{
- // summary:
- // An abstract representation of a row.
-
- // row: Integer
- // Row index of this row
- row: 0,
-
- // except: Integer[]
- // An array of column indexes of all the unselected cells in this row.
- except: []
- });
- dojo.declare("__SelectColItem", __SelectItem,{
- // summary:
- // An abstract representation of a column.
-
- // col: Integer
- // Column index of this column
- col: 0,
-
- // except: Integer[]
- // An array of row indexes of all the unselected cells in this column.
- except: []
- });
- =====*/
- var DISABLED = 0, SINGLE = 1, MULTI = 2,
- _theOther = { col: "row", row: "col" },
- _inRange = function(type, value, start, end, halfClose){
- if(type !== "cell"){
- value = value[type];
- start = start[type];
- end = end[type];
- if(typeof value !== "number" || typeof start !== "number" || typeof end !== "number"){
- return false;
- }
- return halfClose ? ((value >= start && value < end) || (value > end && value <= start))
- : ((value >= start && value <= end) || (value >= end && value <= start));
- }else{
- return _inRange("col", value, start, end, halfClose) && _inRange("row", value, start, end, halfClose);
- }
- },
- _isEqual = function(type, v1, v2){
- try{
- if(v1 && v2){
- switch(type){
- case "col": case "row":
- return v1[type] == v2[type] && typeof v1[type] == "number" &&
- !(_theOther[type] in v1) && !(_theOther[type] in v2);
- case "cell":
- return v1.col == v2.col && v1.row == v2.row && typeof v1.col == "number" && typeof v1.row == "number";
- }
- }
- }catch(e){}
- return false;
- },
- _stopEvent = function(evt){
- try{
- if(evt && evt.preventDefault){
- dojo.stopEvent(evt);
- }
- }catch(e){}
- },
- _createItem = function(type, rowIndex, colIndex){
- switch(type){
- case "col":
- return {
- "col": typeof colIndex == "undefined" ? rowIndex : colIndex,
- "except": []
- };
- case "row":
- return {
- "row": rowIndex,
- "except": []
- };
- case "cell":
- return {
- "row": rowIndex,
- "col": colIndex
- };
- }
- return null;
- };
- dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin, {
- // summary:
- // Provides standard extended selection for grid.
- // Supports mouse/keyboard selection, multi-selection, and de-selection.
- // Acceptable plugin parameters:
- // The whole plugin parameter object is a config object passed to the setupConfig function.
- //
- // Acceptable cell parameters defined in layout:
- // 1. notselectable: boolean
- // Whether this column is (and all the cells in it are) selectable.
-
- // name: String
- // plugin name
- name: "selector",
- /*
- // _config: null,
- // _enabled: true,
- // _selecting: {
- // row: false,
- // col: false,
- // cell: false
- // },
- // _selected: {
- // row: [],
- // col: [],
- // cell: []
- // },
- // _startPoint: {},
- // _currentPoint: {},
- // _lastAnchorPoint: {},
- // _lastEndPoint: {},
- // _lastSelectedAnchorPoint: {},
- // _lastSelectedEndPoint: {},
- // _keyboardSelect: {
- // row: 0,
- // col: 0,
- // cell: 0
- // },
- // _curType: null,
- // _lastType: null,
- // _usingKeyboard: false,
- // _toSelect: true,
- */
- constructor: function(grid, args){
- this.grid = grid;
- this._config = {
- row: MULTI,
- col: MULTI,
- cell: MULTI
- };
- this.setupConfig(args);
- if(grid.selectionMode === "single"){
- this._config.row = SINGLE;
- }
- this._enabled = true;
- this._selecting = {};
- this._selected = {
- "col": [],
- "row": [],
- "cell": []
- };
- this._startPoint = {};
- this._currentPoint = {};
- this._lastAnchorPoint = {};
- this._lastEndPoint = {};
- this._lastSelectedAnchorPoint = {};
- this._lastSelectedEndPoint = {};
- this._keyboardSelect = {};
- this._lastType = null;
- this._selectedRowModified = {};
- this._hacks();
- this._initEvents();
- this._initAreas();
- this._mixinGrid();
- },
- destroy: function(){
- this.inherited(arguments);
- },
- //------------public--------------------
- setupConfig: function(config){
- // summary:
- // Set selection mode for row/col/cell.
- // config: Object
- // An object with the following structure (all properties are optional):
- // {
- // //Default is "multi", all other values are same as "multi".
- // row: false|"disabled"|"single",
- // col: false|"disabled"|"single",
- // cell: false|"disabled"|"single"
- // }
- if(!config || !dojo.isObject(config)){
- return;
- }
- var types = ["row", "col", "cell"];
- for(var type in config){
- if(dojo.indexOf(types, type) >= 0){
- if(!config[type] || config[type] == "disabled"){
- this._config[type] = DISABLED;
- }else if(config[type] == "single"){
- this._config[type] = SINGLE;
- }else{
- this._config[type] = MULTI;
- }
- }
- }
-
- //Have to set mode to default grid selection.
- var mode = ["none","single","extended"][this._config.row];
- this.grid.selection.setMode(mode);
- },
- isSelected: function(type, rowIndex, colIndex){
- // summary:
- // Check whether a location (a cell, a column or a row) is selected.
- // tag:
- // public
- // type: String
- // "row" or "col" or "cell"
- // rowIndex: Integer
- // If type is "row" or "cell", this is the row index.
- // If type if "col", this is the column index.
- // colIndex: Integer?
- // Only valid when type is "cell"
- // return: Boolean
- // true if selected, false if not. If cell is covered by a selected column, it's selected.
- return this._isSelected(type, _createItem(type, rowIndex, colIndex));
- },
- toggleSelect: function(type, rowIndex, colIndex){
- this._startSelect(type, _createItem(type, rowIndex, colIndex), this._config[type] === MULTI, false, false, !this.isSelected(type, rowIndex, colIndex));
- this._endSelect(type);
- },
- select: function(type, rowIndex, colIndex){
- // summary:
- // Select a location (a cell, a column or a row).
- // tag:
- // public
- // type: String
- // "row" or "col" or "cell"
- // rowIndex: Integer
- // If type is "row" or "cell", this is the row index.
- // If type if "col", this is the column index.
- // colIndex: Integer?
- // Only valid when type is "cell"
- if(!this.isSelected(type, rowIndex, colIndex)){
- this.toggleSelect(type, rowIndex, colIndex);
- }
- },
- deselect: function(type, rowIndex, colIndex){
- if(this.isSelected(type, rowIndex, colIndex)){
- this.toggleSelect(type, rowIndex, colIndex);
- }
- },
- selectRange: function(type, start, end, toSelect){
- // summary:
- // Select a continuous range (a block of cells, a set of continuous columns or rows)
- // tag:
- // public
- // type: String
- // "row" or "col" or "cell"
- // start: Integer | Object
- // If type is "row" or "col", this is the index of the starting row or column.
- // If type if "cell", this is the left-top cell of the range.
- // end: Integer | Object
- // If type is "row" or "col", this is the index of the ending row or column.
- // If type if "cell", this is the right-bottom cell of the range.
- this.grid._selectingRange = true;
- var startPoint = type == "cell" ? _createItem(type, start.row, start.col) : _createItem(type, start),
- endPoint = type == "cell" ? _createItem(type, end.row, end.col) : _createItem(type, end);
- this._startSelect(type, startPoint, false, false, false, toSelect);
- this._highlight(type, endPoint, toSelect === undefined ? true : toSelect);
- this._endSelect(type);
- this.grid._selectingRange = false;
- },
- clear: function(type){
- // summary:
- // Clear all selections.
- // tag:
- // public
- // type: String?
- // "row" or "col" or "cell". If omitted, clear all.
- this._clearSelection(type || "all");
- },
- isSelecting: function(type){
- // summary:
- // Check whether the user is currently selecting something.
- // tag:
- // public
- // type: String
- // "row" or "col" or "cell"
- // return: Boolean
- // true if is selection, false otherwise.
- if(typeof type == "undefined"){
- return this._selecting.col || this._selecting.row || this._selecting.cell;
- }
- return this._selecting[type];
- },
- selectEnabled: function(toEnable){
- // summary:
- // Turn on/off this selection functionality if *toEnable* is provided.
- // Check whether this selection functionality is enabled if nothing is passed in.
- // tag:
- // public
- // toEnable: Boolean?
- // To enable or not. Optional.
- // return: Boolean | undefined
- // Enabled or not.
- if(typeof toEnable != "undefined" && !this.isSelecting()){
- this._enabled = !!toEnable;
- }
- return this._enabled;
- },
- getSelected: function(type, includeExceptions){
- // summary:
- // Get an array of selected locations.
- // tag:
- // public
- // type: String
- // "row" or "col" or "cell"
- // includeExceptions: Boolean
- // Only meaningful for rows/columns. If true, all selected rows/cols, even they are partly selected, are all returned.
- // return: __SelectItem[]
- switch(type){
- case "cell":
- return dojo.map(this._selected[type], function(item){ return item; });
- case "col": case "row":
- return dojo.map(includeExceptions ? this._selected[type]
- : dojo.filter(this._selected[type], function(item){
- return item.except.length === 0;
- }), function(item){
- return includeExceptions ? item : item[type];
- });
- }
- return [];
- },
- getSelectedCount: function(type, includeExceptions){
- // summary:
- // Get the number of selected items.
- // tag:
- // public
- // type: String
- // "row" or "col" or "cell"
- // includeExceptions: Boolean
- // Only meaningful for rows/columns. If true, all selected rows/cols, even they are partly selected, are all returned.
- // return: Integer
- // The number of selected items.
- switch(type){
- case "cell":
- return this._selected[type].length;
- case "col": case "row":
- return (includeExceptions ? this._selected[type]
- : dojo.filter(this._selected[type], function(item){
- return item.except.length === 0;
- })).length;
- }
- return 0;
- },
- getSelectedType: function(){
- // summary:
- // Get the type of selected items.
- // tag:
- // public
- // return: String
- // "row" or "col" or "cell", or any mix of these (separator is | ).
- var s = this._selected;
- return ["", "cell", "row", "row|cell",
- "col", "col|cell", "col|row", "col|row|cell"
- ][(!!s.cell.length) | (!!s.row.length << 1) | (!!s.col.length << 2)];
- },
- getLastSelectedRange: function(type){
- // summary:
- // Get last selected range of the given type.
- // tag:
- // public
- // return: Object
- // {start: __SelectItem, end: __SelectItem}
- // return null if nothing is selected.
- return this._lastAnchorPoint[type] ? {
- "start": this._lastAnchorPoint[type],
- "end": this._lastEndPoint[type]
- } : null;
- },
-
- //--------------------------private----------------------------
- _hacks: function(){
- // summary:
- // Complete the event system of grid, hack some grid functions to prevent default behavior.
- var g = this.grid;
- var doContentMouseUp = function(e){
- if(e.cellNode){
- g.onMouseUp(e);
- }
- g.onMouseUpRow(e);
- };
- var mouseUp = dojo.hitch(g, "onMouseUp");
- var mouseDown = dojo.hitch(g, "onMouseDown");
- var doRowSelectorFocus = function(e){
- e.cellNode.style.border = "solid 1px";
- };
- dojo.forEach(g.views.views, function(view){
- view.content.domouseup = doContentMouseUp;
- view.header.domouseup = mouseUp;
- if(view.declaredClass == "dojox.grid._RowSelector"){
- view.domousedown = mouseDown;
- view.domouseup = mouseUp;
- view.dofocus = doRowSelectorFocus;
- }
- });
- //Disable default selection.
- g.selection.clickSelect = function(){};
-
- this._oldDeselectAll = g.selection.deselectAll;
- var _this = this;
- g.selection.selectRange = function(from, to){
- _this.selectRange("row", from, to, true);
- if(g.selection.preserver){
- g.selection.preserver._updateMapping(true, true, false, from, to);
- }
- g.selection.onChanged();
- };
- g.selection.deselectRange = function(from, to){
- _this.selectRange("row", from, to, false);
- if(g.selection.preserver){
- g.selection.preserver._updateMapping(true, false, false, from, to);
- }
- g.selection.onChanged();
- };
- g.selection.deselectAll = function(){
- g._selectingRange = true;
- _this._oldDeselectAll.apply(g.selection, arguments);
- _this._clearSelection("row");
- g._selectingRange = false;
- if(g.selection.preserver){
- g.selection.preserver._updateMapping(true, false, true);
- }
- g.selection.onChanged();
- };
-
- var rowSelector = g.views.views[0];
- //The default function re-write the whole className, so can not insert any other classes.
- if(rowSelector instanceof dojox.grid._RowSelector){
- rowSelector.doStyleRowNode = function(inRowIndex, inRowNode){
- dojo.removeClass(inRowNode, "dojoxGridRow");
- dojo.addClass(inRowNode, "dojoxGridRowbar");
- dojo.addClass(inRowNode, "dojoxGridNonNormalizedCell");
- dojo.toggleClass(inRowNode, "dojoxGridRowbarOver", g.rows.isOver(inRowIndex));
- dojo.toggleClass(inRowNode, "dojoxGridRowbarSelected", !!g.selection.isSelected(inRowIndex));
- };
- }
- this.connect(g, "updateRow", function(rowIndex){
- dojo.forEach(g.layout.cells, function(cell){
- if(this.isSelected("cell", rowIndex, cell.index)){
- this._highlightNode(cell.getNode(rowIndex), true);
- }
- }, this);
- });
- },
- _mixinGrid: function(){
- // summary:
- // Expose events to grid.
- var g = this.grid;
- g.setupSelectorConfig = dojo.hitch(this, this.setupConfig);
- g.onStartSelect = function(){};
- g.onEndSelect = function(){};
- g.onStartDeselect = function(){};
- g.onEndDeselect = function(){};
- g.onSelectCleared = function(){};
- },
- _initEvents: function(){
- // summary:
- // Connect events, create event handlers.
- var g = this.grid,
- _this = this,
- dp = dojo.partial,
- starter = function(type, e){
- if(type === "row"){
- _this._isUsingRowSelector = true;
- }
- //only left mouse button can select.
- if(_this.selectEnabled() && _this._config[type] && e.button != 2){
- if(_this._keyboardSelect.col || _this._keyboardSelect.row || _this._keyboardSelect.cell){
- _this._endSelect("all");
- _this._keyboardSelect.col = _this._keyboardSelect.row = _this._keyboardSelect.cell = 0;
- }
- if(_this._usingKeyboard){
- _this._usingKeyboard = false;
- }
- var target = _createItem(type, e.rowIndex, e.cell && e.cell.index);
- _this._startSelect(type, target, e.ctrlKey, e.shiftKey);
- }
- },
- ender = dojo.hitch(this, "_endSelect");
- this.connect(g, "onHeaderCellMouseDown", dp(starter, "col"));
- this.connect(g, "onHeaderCellMouseUp", dp(ender, "col"));
-
- this.connect(g, "onRowSelectorMouseDown", dp(starter, "row"));
- this.connect(g, "onRowSelectorMouseUp", dp(ender, "row"));
-
- this.connect(g, "onCellMouseDown", function(e){
- if(e.cell && e.cell.isRowSelector){ return; }
- if(g.singleClickEdit){
- _this._singleClickEdit = true;
- g.singleClickEdit = false;
- }
- starter(_this._config["cell"] == DISABLED ? "row" : "cell", e);
- });
- this.connect(g, "onCellMouseUp", function(e){
- if(_this._singleClickEdit){
- delete _this._singleClickEdit;
- g.singleClickEdit = true;
- }
- ender("all", e);
- });
-
- this.connect(g, "onCellMouseOver", function(e){
- if(_this._curType != "row" && _this._selecting[_this._curType] && _this._config[_this._curType] == MULTI){
- _this._highlight("col", _createItem("col", e.cell.index), _this._toSelect);
- if(!_this._keyboardSelect.cell){
- _this._highlight("cell", _createItem("cell", e.rowIndex, e.cell.index), _this._toSelect);
- }
- }
- });
- this.connect(g, "onHeaderCellMouseOver", function(e){
- if(_this._selecting.col && _this._config.col == MULTI){
- _this._highlight("col", _createItem("col", e.cell.index), _this._toSelect);
- }
- });
- this.connect(g, "onRowMouseOver", function(e){
- if(_this._selecting.row && _this._config.row == MULTI){
- _this._highlight("row", _createItem("row", e.rowIndex), _this._toSelect);
- }
- });
-
- //When row order has changed in a unpredictable way (sorted or filtered), map the new rowindex.
- this.connect(g, "onSelectedById", "_onSelectedById");
-
- //When the grid refreshes, all those selected should still appear selected.
- this.connect(g, "_onFetchComplete", function(){
- //console.debug("refresh after buildPage:", g._notRefreshSelection);
- if(!g._notRefreshSelection){
- this._refreshSelected(true);
- }
- });
- //Small scroll might not refresh the grid.
- this.connect(g.scroller, "buildPage", function(){
- //console.debug("refresh after buildPage:", g._notRefreshSelection);
- if(!g._notRefreshSelection){
- this._refreshSelected(true);
- }
- });
-
- //Whenever the mouse is up, end selecting.
- this.connect(dojo.doc, "onmouseup", dp(ender, "all"));
-
- //If autoscroll is enabled, connect to it.
- this.connect(g, "onEndAutoScroll", function(isVertical, isForward, view, target){
- var selectCell = _this._selecting.cell,
- type, current, dir = isForward ? 1 : -1;
- if(isVertical && (selectCell || _this._selecting.row)){
- type = selectCell ? "cell" : "row";
- current = _this._currentPoint[type];
- _this._highlight(type, _createItem(type, current.row + dir, current.col), _this._toSelect);
- }else if(!isVertical && (selectCell || _this._selecting.col)){
- type = selectCell ? "cell" : "col";
- current = _this._currentPoint[type];
- _this._highlight(type, _createItem(type, current.row, target), _this._toSelect);
- }
- });
- //If the grid is changed, selection should be consistent.
- this.subscribe("dojox/grid/rearrange/move/" + g.id, "_onInternalRearrange");
- this.subscribe("dojox/grid/rearrange/copy/" + g.id, "_onInternalRearrange");
- this.subscribe("dojox/grid/rearrange/change/" + g.id, "_onExternalChange");
- this.subscribe("dojox/grid/rearrange/insert/" + g.id, "_onExternalChange");
- this.subscribe("dojox/grid/rearrange/remove/" + g.id, "clear");
-
- //have to also select when the grid's default select is used.
- this.connect(g, "onSelected", function(rowIndex){
- if(this._selectedRowModified && this._isUsingRowSelector){
- delete this._selectedRowModified;
- }else if(!this.grid._selectingRange){
- this.select("row", rowIndex);
- }
- });
- this.connect(g, "onDeselected", function(rowIndex){
- if(this._selectedRowModified && this._isUsingRowSelector){
- delete this._selectedRowModified;
- }else if(!this.grid._selectingRange){
- this.deselect("row", rowIndex);
- }
- });
- },
- _onSelectedById: function(id, newIndex, isSelected){
- if(this.grid._noInternalMapping){
- return;
- }
- var pointSet = [this._lastAnchorPoint.row, this._lastEndPoint.row,
- this._lastSelectedAnchorPoint.row, this._lastSelectedEndPoint.row];
- pointSet = pointSet.concat(this._selected.row);
- var found = false;
- dojo.forEach(pointSet, function(item){
- if(item){
- if(item.id === id){
- found = true;
- item.row = newIndex;
- }else if(item.row === newIndex && item.id){
- item.row = -1;
- }
- }
- });
- if(!found && isSelected){
- dojo.some(this._selected.row, function(item){
- if(item && !item.id && !item.except.length){
- item.id = id;
- item.row = newIndex;
- return true;
- }
- return false;
- });
- }
- found = false;
- pointSet = [this._lastAnchorPoint.cell, this._lastEndPoint.cell,
- this._lastSelectedAnchorPoint.cell, this._lastSelectedEndPoint.cell];
- pointSet = pointSet.concat(this._selected.cell);
- dojo.forEach(pointSet, function(item){
- if(item){
- if(item.id === id){
- found = true;
- item.row = newIndex;
- }else if(item.row === newIndex && item.id){
- item.row = -1;
- }
- }
- });
- },
- onSetStore: function(){
- this._clearSelection("all");
- },
- _onInternalRearrange: function(type, mapping){
- try{
- //The column can not refresh it self!
- this._refresh("col", false);
-
- dojo.forEach(this._selected.row, function(item){
- dojo.forEach(this.grid.layout.cells, function(cell){
- this._highlightNode(cell.getNode(item.row), false);
- }, this);
- }, this);
- //The rowbar must be cleaned manually
- dojo.query(".dojoxGridRowSelectorSelected").forEach(function(node){
- dojo.removeClass(node, "dojoxGridRowSelectorSelected");
- dojo.removeClass(node, "dojoxGridRowSelectorSelectedUp");
- dojo.removeClass(node, "dojoxGridRowSelectorSelectedDown");
- });
-
- var cleanUp = function(item){
- if(item){
- delete item.converted;
- }
- },
- pointSet = [this._lastAnchorPoint[type], this._lastEndPoint[type],
- this._lastSelectedAnchorPoint[type], this._lastSelectedEndPoint[type]];
-
- if(type === "cell"){
- this.selectRange("cell", mapping.to.min, mapping.to.max);
- var cells = this.grid.layout.cells;
- dojo.forEach(pointSet, function(item){
- if(item.converted){ return; }
- for(var r = mapping.from.min.row, tr = mapping.to.min.row; r <= mapping.from.max.row; ++r, ++tr){
- for(var c = mapping.from.min.col, tc = mapping.to.min.col; c <= mapping.from.max.col; ++c, ++tc){
- while(cells[c].hidden){ ++c; }
- while(cells[tc].hidden){ ++tc; }
- if(item.row == r && item.col == c){
- //console.log('mapping found: (', item.row, ",",item.col,") to (", tr, ",", tc,")");
- item.row = tr;
- item.col = tc;
- item.converted = true;
- return;
- }
- }
- }
- });
- }else{
- pointSet = this._selected.cell.concat(this._selected[type]).concat(pointSet).concat(
- [this._lastAnchorPoint.cell, this._lastEndPoint.cell,
- this._lastSelectedAnchorPoint.cell, this._lastSelectedEndPoint.cell]);
- dojo.forEach(pointSet, function(item){
- if(item && !item.converted){
- var from = item[type];
- if(from in mapping){
- item[type] = mapping[from];
- }
- item.converted = true;
- }
- });
- dojo.forEach(this._selected[_theOther[type]], function(item){
- for(var i = 0, len = item.except.length; i < len; ++i){
- var from = item.except[i];
- if(from in mapping){
- item.except[i] = mapping[from];
- }
- }
- });
- }
-
- dojo.forEach(pointSet, cleanUp);
-
- this._refreshSelected(true);
- this._focusPoint(type, this._lastEndPoint);
- }catch(e){
- console.warn("Selector._onInternalRearrange() error",e);
- }
- },
- _onExternalChange: function(type, target){
- var start = type == "cell" ? target.min : target[0],
- end = type == "cell" ? target.max : target[target.length - 1];
- this.selectRange(type, start, end);
- },
- _refresh: function(type, toHighlight){
- if(!this._keyboardSelect[type]){
- dojo.forEach(this._selected[type], function(item){
- this._highlightSingle(type, toHighlight, item, undefined, true);
- }, this);
- }
- },
- _refreshSelected: function(){
- this._refresh("col", true);
- this._refresh("row", true);
- this._refresh("cell", true);
- },
- _initAreas: function(){
- var g = this.grid, f = g.focus, _this = this, dk = dojo.keys,
- keyboardSelectReady = 1, duringKeyboardSelect = 2,
- onmove = function(type, createNewEnd, rowStep, colStep, evt){
- //Keyboard swipe selection is SHIFT + Direction Keys.
- var ks = _this._keyboardSelect;
- //Tricky, rely on valid status not being 0.
- if(evt.shiftKey && ks[type]){
- if(ks[type] === keyboardSelectReady){
- if(type === "cell"){
- var item = _this._lastEndPoint[type];
- if(f.cell != g.layout.cells[item.col + colStep] || f.rowIndex != item.row + rowStep){
- ks[type] = 0;
- return;
- }
- }
- //If selecting is not started, start it
- _this._startSelect(type, _this._lastAnchorPoint[type], true, false, true);
- _this._highlight(type, _this._lastEndPoint[type], _this._toSelect);
- ks[type] = duringKeyboardSelect;
- }
- //Highlight to the new end point.
- var newEnd = createNewEnd(type, rowStep, colStep, evt);
- if(_this._isValid(type, newEnd, g)){
- _this._highlight(type, newEnd, _this._toSelect);
- }
- _stopEvent(evt);
- }
- },
- onkeydown = function(type, getTarget, evt, isBubble){
- if(isBubble && _this.selectEnabled() && _this._config[type] != DISABLED){
- switch(evt.keyCode){
- case dk.SPACE:
- //Keyboard single point selection is SPACE.
- _this._startSelect(type, getTarget(), evt.ctrlKey, evt.shiftKey);
- _this._endSelect(type);
- break;
- case dk.SHIFT:
- //Keyboard swipe selection starts with SHIFT.
- if(_this._config[type] == MULTI && _this._isValid(type, _this._lastAnchorPoint[type], g)){
- //End last selection if any.
- _this._endSelect(type);
- _this._keyboardSelect[type] = keyboardSelectReady;
- _this._usingKeyboard = true;
- }
- }
- }
- },
- onkeyup = function(type, evt, isBubble){
- if(isBubble && evt.keyCode == dojo.keys.SHIFT && _this._keyboardSelect[type]){
- _this._endSelect(type);
- _this._keyboardSelect[type] = 0;
- }
- };
- //TODO: this area "rowHeader" should be put outside, same level as header/content.
- if(g.views.views[0] instanceof dojox.grid._RowSelector){
- this._lastFocusedRowBarIdx = 0;
- f.addArea({
- name:"rowHeader",
- onFocus: function(evt, step){
- var view = g.views.views[0];
- if(view instanceof dojox.grid._RowSelector){
- var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
- if(rowBarNode){
- dojo.toggleClass(rowBarNode, f.focusClass, false);
- }
- //evt might not be real event, it may be a mock object instead.
- if(evt && "rowIndex" in evt){
- if(evt.rowIndex >= 0){
- _this._lastFocusedRowBarIdx = evt.rowIndex;
- }else if(!_this._lastFocusedRowBarIdx){
- _this._lastFocusedRowBarIdx = 0;
- }
- }
- rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
- if(rowBarNode){
- dijit.focus(rowBarNode);
- dojo.toggleClass(rowBarNode, f.focusClass, true);
- }
- f.rowIndex = _this._lastFocusedRowBarIdx;
- _stopEvent(evt);
- return true;
- }
- return false;
- },
- onBlur: function(evt, step){
- var view = g.views.views[0];
- if(view instanceof dojox.grid._RowSelector){
- var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
- if(rowBarNode){
- dojo.toggleClass(rowBarNode, f.focusClass, false);
- }
- _stopEvent(evt);
- }
- return true;
- },
- onMove: function(rowStep, colStep, evt){
- var view = g.views.views[0];
- if(rowStep && view instanceof dojox.grid._RowSelector){
- var next = _this._lastFocusedRowBarIdx + rowStep;
- if(next >= 0 && next < g.rowCount){
- //TODO: these logic require a better Scroller.
- _stopEvent(evt);
- var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
- dojo.toggleClass(rowBarNode, f.focusClass, false);
- //If the row is not fetched, fetch it.
- var sc = g.scroller;
- var lastPageRow = sc.getLastPageRow(sc.page);
- var rc = g.rowCount - 1, row = Math.min(rc, next);
- if(next > lastPageRow){
- g.setScrollTop(g.scrollTop + sc.findScrollTop(row) - sc.findScrollTop(_this._lastFocusedRowBarIdx));
- }
- //Now we have fetched the row.
- rowBarNode = view.getCellNode(next, 0);
- dijit.focus(rowBarNode);
- dojo.toggleClass(rowBarNode, f.focusClass, true);
- _this._lastFocusedRowBarIdx = next;
- //If the row is out of view, scroll to it.
- f.cell = rowBarNode;
- f.cell.view = view;
- f.cell.getNode = function(index){
- return f.cell;
- };
- f.rowIndex = _this._lastFocusedRowBarIdx;
- f.scrollIntoView();
- f.cell = null;
- }
- }
- }
- });
- f.placeArea("rowHeader","before","content");
- }
- //Support keyboard selection.
- f.addArea({
- name:"cellselect",
- onMove: dojo.partial(onmove, "cell", function(type, rowStep, colStep, evt){
- var current = _this._currentPoint[type];
- return _createItem("cell", current.row + rowStep, current.col + colStep);
- }),
- onKeyDown: dojo.partial(onkeydown, "cell", function(){
- return _createItem("cell", f.rowIndex, f.cell.index);
- }),
- onKeyUp: dojo.partial(onkeyup, "cell")
- });
- f.placeArea("cellselect","below","content");
- f.addArea({
- name:"colselect",
- onMove: dojo.partial(onmove, "col", function(type, rowStep, colStep, evt){
- var current = _this._currentPoint[type];
- return _createItem("col", current.col + colStep);
- }),
- onKeyDown: dojo.partial(onkeydown, "col", function(){
- return _createItem("col", f.getHeaderIndex());
- }),
- onKeyUp: dojo.partial(onkeyup, "col")
- });
- f.placeArea("colselect","below","header");
- f.addArea({
- name:"rowselect",
- onMove: dojo.partial(onmove, "row", function(type, rowStep, colStep, evt){
- return _createItem("row", f.rowIndex);
- }),
- onKeyDown: dojo.partial(onkeydown, "row", function(){
- return _createItem("row", f.rowIndex);
- }),
- onKeyUp: dojo.partial(onkeyup, "row")
- });
- f.placeArea("rowselect","below","rowHeader");
- },
- _clearSelection: function(type, reservedItem){
- // summary:
- // Clear selection for given type and fire events, but retain the highlight for *reservedItem*,
- // thus avoid "flashing".
- // tag:
- // private
- // type: String
- // "row", "col", or "cell
- // reservedItem: __SelectItem
- // The item to retain highlight.
- if(type == "all"){
- this._clearSelection("cell", reservedItem);
- this._clearSelection("col", reservedItem);
- this._clearSelection("row", reservedItem);
- return;
- }
- this._isUsingRowSelector = true;
- dojo.forEach(this._selected[type], function(item){
- if(!_isEqual(type, reservedItem, item)){
- this._highlightSingle(type, false, item);
- }
- }, this);
- this._blurPoint(type, this._currentPoint);
- this._selecting[type] = false;
- this._startPoint[type] = this._currentPoint[type] = null;
- this._selected[type] = [];
-
- //Have to also deselect default grid selection.
- if(type == "row" && !this.grid._selectingRange){
- this._oldDeselectAll.call(this.grid.selection);
- this.grid.selection._selectedById = {};
- }
-
- //Fire events.
- this.grid.onEndDeselect(type, null, null, this._selected);
- this.grid.onSelectCleared(type);
- },
- _startSelect: function(type, start, extending, isRange, mandatarySelect, toSelect){
- // summary:
- // Start selection, setup start point and current point, fire events.
- // tag:
- // private
- // type: String
- // "row", "col", or "cell"
- // extending: Boolean
- // Whether this is a multi selection
- // isRange: Boolean
- // Whether this is a range selection (i.e. select from the last end point to this point)
- // start: __SelectItem
- // The start point
- // mandatarySelect: Boolean
- // If true, toSelect will be same as the original selection status.
- if(!this._isValid(type, start)){
- return;
- }
- var lastIsSelected = this._isSelected(type, this._lastEndPoint[type]),
- isSelected = this._isSelected(type, start);
-
- //If we are modifying the selection using keyboard, retain the old status.
- this._toSelect = mandatarySelect ? isSelected : !isSelected;
-
- //If CTRL is not pressed or it's SINGLE mode, this is a brand new selection.
- if(!extending || (!isSelected && this._config[type] == SINGLE)){
- this._clearSelection("all", start);
- this._toSelect = toSelect === undefined ? true : toSelect;
- }
-
- this._selecting[type] = true;
- this._currentPoint[type] = null;
-
- //We're holding SHIFT while clicking, it's a Click-Range selection.
- if(isRange && this._lastType == type && lastIsSelected == this._toSelect){
- if(type === "row"){
- this._isUsingRowSelector = true;
- }
- this._startPoint[type] = this._lastAnchorPoint[type];
- this._highlight(type, this._startPoint[type]);
- this._isUsingRowSelector = false;
- }else{
- this._startPoint[type] = start;
- }
- //Now start selection
- this._curType = type;
- this._fireEvent("start", type);
- this._isStartFocus = true;
- this._isUsingRowSelector = true;
- this._highlight(type, start, this._toSelect);
- this._isStartFocus = false;
- },
- _endSelect: function(type){
- // summary:
- // End selection. Keep records, fire events and cleanup status.
- // tag:
- // private
- // type: String
- // "row", "col", or "cell"
- if(type === "row"){
- delete this._isUsingRowSelector;
- }
- if(type == "all"){
- this._endSelect("col");
- this._endSelect("row");
- this._endSelect("cell");
- }else if(this._selecting[type]){
- this._addToSelected(type);
- this._lastAnchorPoint[type] = this._startPoint[type];
- this._lastEndPoint[type] = this._currentPoint[type];
- if(this._toSelect){
- this._lastSelectedAnchorPoint[type] = this._lastAnchorPoint[type];
- this._lastSelectedEndPoint[type] = this._lastEndPoint[type];
- }
- this._startPoint[type] = this._currentPoint[type] = null;
- this._selecting[type] = false;
- this._lastType = type;
- this._fireEvent("end", type);
- }
- },
- _fireEvent: function(evtName, type){
- switch(evtName){
- case "start":
- this.grid[this._toSelect ? "onStartSelect" : "onStartDeselect"](type, this._startPoint[type], this._selected);
- break;
- case "end":
- this.grid[this._toSelect ? "onEndSelect" : "onEndDeselect"](type, this._lastAnchorPoint[type], this._lastEndPoint[type], this._selected);
- break;
- }
- },
- _calcToHighlight: function(type, target, toHighlight, toSelect){
- // summary:
- // Calculate what status should *target* have.
- // If *toSelect* is not provided, this is a no op.
- // This function is time-critical!!
- if(toSelect !== undefined){
- var sltd;
- if(this._usingKeyboard && !toHighlight){
- var last = this._isInLastRange(this._lastType, target);
- if(last){
- sltd = this._isSelected(type, target);
- //This 2 cases makes the keyboard swipe selection valid!
- if(toSelect && sltd){
- return false;
- }
- if(!toSelect && !sltd && this._isInLastRange(this._lastType, target, true)){
- return true;
- }
- }
- }
- return toHighlight ? toSelect : (sltd || this._isSelected(type, target));
- }
- return toHighlight;
- },
- _highlightNode: function(node, toHighlight){
- // summary:
- // Do the actual highlight work.
- if(node){
- var selectCSSClass = "dojoxGridRowSelected";
- var selectCellClass = "dojoxGridCellSelected";
- dojo.toggleClass(node, selectCSSClass, toHighlight);
- dojo.toggleClass(node, selectCellClass, toHighlight);
- }
- },
- _highlightHeader: function(colIdx, toHighlight){
- var cells = this.grid.layout.cells;
- var node = cells[colIdx].getHeaderNode();
- var selectedClass = "dojoxGridHeaderSelected";
- dojo.toggleClass(node, selectedClass, toHighlight);
- },
- _highlightRowSelector: function(rowIdx, toHighlight){
- //var t1 = (new Date()).getTime();
- var rowSelector = this.grid.views.views[0];
- if(rowSelector instanceof dojox.grid._RowSelector){
- var node = rowSelector.getRowNode(rowIdx);
- if(node){
- var selectedClass = "dojoxGridRowSelectorSelected";
- dojo.toggleClass(node, selectedClass, toHighlight);
- }
- }
- //console.log((new Date()).getTime() - t1);
- },
- _highlightSingle: function(type, toHighlight, target, toSelect, isRefresh){
- // summary:
- // Highlight a single item.
- // This function is time critical!!
- var _this = this, toHL, g = _this.grid, cells = g.layout.cells;
- switch(type){
- case "cell":
- toHL = this._calcToHighlight(type, target, toHighlight, toSelect);
- var c = cells[target.col];
- if(!c.hidden && !c.notselectable){
- this._highlightNode(target.node || c.getNode(target.row), toHL);
- }
- break;
- case "col":
- toHL = this._calcToHighlight(type, target, toHighlight, toSelect);
- this._highlightHeader(target.col, toHL);
- dojo.query("td[idx='" + target.col + "']", g.domNode).forEach(function(cellNode){
- var rowNode = cells[target.col].view.content.findRowTarget(cellNode);
- if(rowNode){
- var rowIndex = rowNode[dojox.grid.util.rowIndexTag];
- _this._highlightSingle("cell", toHL, {
- "row": rowIndex,
- "col": target.col,
- "node": cellNode
- });
- }
- });
- break;
- case "row":
- toHL = this._calcToHighlight(type, target, toHighlight, toSelect);
- this._highlightRowSelector(target.row, toHL);
- dojo.forEach(cells, function(cell){
- _this._highlightSingle("cell", toHL, {
- "row": target.row,
- "col": cell.index,
- "node": cell.getNode(target.row)
- });
- });
- //To avoid dead lock
- this._selectedRowModified = true;
- if(!isRefresh){
- g.selection.setSelected(target.row, toHL);
- }
- }
- },
- _highlight: function(type, target, toSelect){
- // summary:
- // Highlight from start point to target.
- // toSelect: Boolean
- // Whether we are selecting or deselecting.
- // This function is time critical!!
- if(this._selecting[type] && target !== null){
- var start = this._startPoint[type],
- current = this._currentPoint[type],
- _this = this,
- highlight = function(from, to, toHL){
- _this._forEach(type, from, to, function(item){
- _this._highlightSingle(type, toHL, item, toSelect);
- }, true);
- };
- switch(type){
- case "col": case "row":
- if(current !== null){
- if(_inRange(type, target, start, current, true)){
- //target is between start and current, some selected should be deselected.
- highlight(current, target, false);
- }else{
- if(_inRange(type, start, target, current, true)){
- //selection has jumped to different direction, all should be deselected.
- highlight(current, start, false);
- current = start;
- }
- highlight(target, current, true);
- }
- }else{
- //First time select.
- this._highlightSingle(type, true, target, toSelect);
- }
- break;
- case "cell":
- if(current !== null){
- if(_inRange("row", target, start, current, true) ||
- _inRange("col", target, start, current, true) ||
- _inRange("row", start, target, current, true) ||
- _inRange("col", start, target, current, true)){
- highlight(start, current, false);
- }
- }
- highlight(start, target, true);
- }
- this._currentPoint[type] = target;
- this._focusPoint(type, this._currentPoint);
- }
- },
- _focusPoint: function(type, point){
- // summary:
- // Focus the current point, so when you move mouse, the focus indicator follows you.
- if(!this._isStartFocus){
- var current = point[type],
- f = this.grid.focus;
- if(type == "col"){
- f._colHeadFocusIdx = current.col;
- f.focusArea("header");
- }else if(type == "row"){
- f.focusArea("rowHeader", {
- "rowIndex": current.row
- });
- }else if(type == "cell"){
- f.setFocusIndex(current.row, current.col);
- }
- }
- },
- _blurPoint: function(type, point){
- // summary:
- // Blur the current point.
- var f = this.grid.focus;
- if(type == "cell"){
- f._blurContent();
- }
- },
- _addToSelected: function(type){
- // summary:
- // Record the selected items.
- var toSelect = this._toSelect, _this = this,
- toAdd = [], toRemove = [],
- start = this._startPoint[type],
- end = this._currentPoint[type];
- if(this._usingKeyboard){
- //If using keyboard, selection will be ended after every move. But we have to remember the original selection status,
- //so as to return to correct status when we shrink the selection region.
- this._forEach(type, this._lastAnchorPoint[type], this._lastEndPoint[type], function(item){
- //If the original selected item is not in current range, change its status.
- if(!_inRange(type, item, start, end)){
- (toSelect ? toRemove : toAdd).push(item);
- }
- });
- }
- this._forEach(type, start, end, function(item){
- var isSelected = _this._isSelected(type, item);
- if(toSelect && !isSelected){
- //Add new selected items
- toAdd.push(item);
- }else if(!toSelect){
- //Remove deselected items.
- toRemove.push(item);
- }
- });
- this._add(type, toAdd);
- this._remove(type, toRemove);
-
- // have to keep record in original grid selection
- dojo.forEach(this._selected.row, function(item){
- if(item.except.length > 0){
- //to avoid dead lock
- this._selectedRowModified = true;
- this.grid.selection.setSelected(item.row, false);
- }
- }, this);
- },
- _forEach: function(type, start, end, func, halfClose){
- // summary:
- // Go through items from *start* point to *end* point.
- // This function is time critical!!
- if(!this._isValid(type, start, true) || !this._isValid(type, end, true)){
- return;
- }
- switch(type){
- case "col": case "row":
- start = start[type];
- end = end[type];
- var dir = end > start ? 1 : -1;
- if(!halfClose){
- end += dir;
- }
- for(; start != end; start += dir){
- func(_createItem(type, start));
- }
- break;
- case "cell":
- var colDir = end.col > start.col ? 1 : -1,
- rowDir = end.row > start.row ? 1 : -1;
- for(var i = start.row, p = end.row + rowDir; i != p; i += rowDir){
- for(var j = start.col, q = end.col + colDir; j != q; j += colDir){
- func(_createItem(type, i, j));
- }
- }
- }
- },
- _makeupForExceptions: function(type, newCellItems){
- // summary:
- // When new cells is selected, maybe they will fill in the "holes" in selected rows and columns.
- var makedUps = [];
- dojo.forEach(this._selected[type], function(v1){
- dojo.forEach(newCellItems, function(v2){
- if(v1[type] == v2[type]){
- var pos = dojo.indexOf(v1.except, v2[_theOther[type]]);
- if(pos >= 0){
- v1.except.splice(pos, 1);
- }
- makedUps.push(v2);
- }
- });
- });
- return makedUps;
- },
- _makeupForCells: function(type, newItems){
- // summary:
- // When some rows/cols are selected, maybe they can cover some of the selected cells,
- // and fill some of the "holes" in the selected cols/rows.
- var toRemove = [];
- dojo.forEach(this._selected.cell, function(v1){
- dojo.some(newItems, function(v2){
- if(v1[type] == v2[type]){
- toRemove.push(v1);
- return true;
- }
- return false;
- });
- });
- this._remove("cell", toRemove);
- dojo.forEach(this._selected[_theOther[type]], function(v1){
- dojo.forEach(newItems, function(v2){
- var pos = dojo.indexOf(v1.except, v2[type]);
- if(pos >= 0){
- v1.except.splice(pos, 1);
- }
- });
- });
- },
- _addException: function(type, items){
- // summary:
- // If some rows/cols are deselected, maybe they have created "holes" in selected cols/rows.
- dojo.forEach(this._selected[type], function(v1){
- dojo.forEach(items, function(v2){
- v1.except.push(v2[_theOther[type]]);
- });
- });
- },
- _addCellException: function(type, items){
- // summary:
- // If some cells are deselected, maybe they have created "holes" in selected rows/cols.
- dojo.forEach(this._selected[type], function(v1){
- dojo.forEach(items, function(v2){
- if(v1[type] == v2[type]){
- v1.except.push(v2[_theOther[type]]);
- }
- });
- });
- },
- _add: function(type, items){
- // summary:
- // Add to the selection record.
- var cells = this.grid.layout.cells;
- if(type == "cell"){
- var colMakedup = this._makeupForExceptions("col", items);
- var rowMakedup = this._makeupForExceptions("row", items);
- //Step over hidden columns.
- items = dojo.filter(items, function(item){
- return dojo.indexOf(colMakedup, item) < 0 && dojo.indexOf(rowMakedup, item) < 0 &&
- !cells[item.col].hidden && !cells[item.col].notselectable;
- });
- }else{
- if(type == "col"){
- //Step over hidden columns.
- items = dojo.filter(items, function(item){
- return !cells[item.col].hidden && !cells[item.col].notselectable;
- });
- }
- this._makeupForCells(type, items);
- this._selected[type] = dojo.filter(this._selected[type], function(v){
- return dojo.every(items, function(item){
- return v[type] !== item[type];
- });
- });
- }
- if(type != "col" && this.grid._hasIdentity){
- dojo.forEach(items, function(item){
- var record = this.grid._by_idx[item.row];
- if(record){
- item.id = record.idty;
- }
- }, this);
- }
- this._selected[type] = this._selected[type].concat(items);
- },
- _remove: function(type, items){
- // summary:
- // Remove from the selection record.
- var comp = dojo.partial(_isEqual, type);
- this._selected[type] = dojo.filter(this._selected[type], function(v1){
- return !dojo.some(items, function(v2){
- return comp(v1, v2);
- });
- });
- if(type == "cell"){
- this._addCellException("col", items);
- this._addCellException("row", items);
- }else{
- this._addException(_theOther[type], items);
- }
- },
- _isCellNotInExcept: function(type, item){
- // summary:
- // Return true only when a cell is covered by selected row/col, and its not a "hole".
- var attr = item[type], corres = item[_theOther[type]];
- return dojo.some(this._selected[type], function(v){
- return v[type] == attr && dojo.indexOf(v.except, corres) < 0;
- });
- },
- _isSelected: function(type, item){
- // summary:
- // Return true when the item is selected. (or logically selected, i.e, covered by a row/col).
- if(!item){ return false; }
- var res = dojo.some(this._selected[type], function(v){
- var ret = _isEqual(type, item, v);
- if(ret && type !== "cell"){
- return v.except.length === 0;
- }
- return ret;
- });
- if(!res && type === "cell"){
- res = (this._isCellNotInExcept("col", item) || this._isCellNotInExcept("row", item));
- if(type === "cell"){
- res = res && !this.grid.layout.cells[item.col].notselectable;
- }
- }
- return res;
- },
- _isInLastRange: function(type, item, isSelected){
- // summary:
- // Return true only when the item is in the last seletion/deseletion range.
- var start = this[isSelected ? "_lastSelectedAnchorPoint" : "_lastAnchorPoint"][type],
- end = this[isSelected ? "_lastSelectedEndPoint" : "_lastEndPoint"][type];
- if(!item || !start || !end){ return false; }
- return _inRange(type, item, start, end);
- },
- _isValid: function(type, item, allowNotSelectable){
- // summary:
- // Check whether the item is a valid __SelectItem for the given type.
- if(!item){ return false; }
- try{
- var g = this.grid, index = item[type];
- switch(type){
- case "col":
- return index >= 0 && index < g.layout.cells.length && dojo.isArray(item.except) &&
- (allowNotSelectable || !g.layout.cells[index].notselectable);
- case "row":
- return index >= 0 && index < g.rowCount && dojo.isArray(item.except);
- case "cell":
- return item.col >= 0 && item.col < g.layout.cells.length &&
- item.row >= 0 && item.row < g.rowCount &&
- (allowNotSelectable || !g.layout.cells[item.col].notselectable);
- }
- }catch(e){}
- return false;
- }
- });
- dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Selector/*name:'selector'*/, {
- "dependency": ["autoScroll"]
- });
- })();
- }
|