source: Dev/trunk/src/client/dojox/grid/enhanced/plugins/IndirectSelection.js

Last change on this file was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 20.5 KB
Line 
1define([
2        "dojo/_base/declare",
3        "dojo/_base/array",
4        "dojo/_base/event",
5        "dojo/_base/lang",
6        "dojo/_base/html",
7        "dojo/_base/window",
8        "dojo/_base/connect",
9        "dojo/_base/sniff",
10        "dojo/query",
11        "dojo/keys",
12        "dojo/string",
13        "../_Plugin",
14        "../../EnhancedGrid",
15        "../../cells/dijit"
16], function(declare, array, evt, lang, html, win, connect, has, query, keys, string, _Plugin, EnhancedGrid){
17
18var gridCells = lang.getObject("dojox.grid.cells");
19
20var RowSelector = declare("dojox.grid.cells.RowSelector", gridCells._Widget, {
21        // summary:
22        //               Common attributes & functions for row selectors(Radio|CheckBox)
23
24        // inputType: String
25        //              Input type - Radio|CheckBox
26        inputType: "",
27       
28        // map: Object
29        //              Cache div refs of radio|checkbox to avoid querying each time
30        map: null,
31       
32        // disabledMap: Object
33        //              Cache index of disabled rows
34        disabledMap: null,
35       
36        // isRowSelector: Boolean
37        //              Marker of indirectSelection cell(column)
38        isRowSelector: true,
39
40        // _connects: Array
41        //              List of all connections.
42        _connects: null,
43       
44        // _subscribes: Array
45        //              List of all subscribes.
46        _subscribes: null,
47
48        // checkedText: String
49        //              Checked character for high contrast mode
50        checkedText: '✓',
51
52        // unCheckedText: String
53        //              Unchecked character for high contrast mode
54        unCheckedText: 'O',
55
56        constructor: function(){
57                this.map = {}; this.disabledMap = {}; this.disabledCount= 0;
58                this._connects = []; this._subscribes = [];
59                this.inA11YMode = html.hasClass(win.body(), "dijit_a11y");
60               
61                this.baseClass = "dojoxGridRowSelector dijitReset dijitInline dijit" + this.inputType;
62                this.checkedClass = " dijit" + this.inputType + "Checked";
63                this.disabledClass = " dijit" + this.inputType + "Disabled";
64                this.checkedDisabledClass = " dijit" + this.inputType + "CheckedDisabled";
65                this.statusTextClass = " dojoxGridRowSelectorStatusText";//a11y use
66
67                this._connects.push(connect.connect(this.grid, 'dokeyup', this, '_dokeyup'));
68                this._connects.push(connect.connect(this.grid.selection, 'onSelected', this, '_onSelected'));
69                this._connects.push(connect.connect(this.grid.selection, 'onDeselected', this, '_onDeselected'));
70                this._connects.push(connect.connect(this.grid.scroller, 'invalidatePageNode', this, '_pageDestroyed'));
71                this._connects.push(connect.connect(this.grid, 'onCellClick', this, '_onClick'));
72                this._connects.push(connect.connect(this.grid, 'updateRow', this, '_onUpdateRow'));
73        },
74        formatter: function(data, rowIndex, scope){
75                // summary:
76                //              Overwritten, see dojox.grid.cells._Widget
77                var _this = scope;
78                var clazz = _this.baseClass;
79                var checked = !!_this.getValue(rowIndex);
80                var disabled = !!_this.disabledMap[rowIndex];//normalize 'undefined'
81               
82                if(checked){
83                        clazz += _this.checkedClass;
84                        if(disabled){ clazz += _this.checkedDisabledClass; }
85                }else if(disabled){
86                        clazz += _this.disabledClass;
87                }
88                return ["<div tabindex = -1 ",
89                                "id = '" + _this.grid.id + "_rowSelector_" + rowIndex + "' ",
90                                "name = '" + _this.grid.id + "_rowSelector' class = '" + clazz + "' ",
91                                "role = " + _this.inputType + " aria-checked = '" + checked + "' aria-disabled = '" + disabled +
92                                "' aria-label = '" + string.substitute(_this.grid._nls["indirectSelection" + _this.inputType], [rowIndex + 1]) + "'>",
93                                "<span class = '" + _this.statusTextClass + "'>" + (checked ? _this.checkedText : _this.unCheckedText) + "</span>",
94                                "</div>"].join("");
95        },
96        setValue: function(rowIndex, inValue){
97                // summary:
98                //              Overwritten, see dojox.grid.cells._Widget
99                //              Simply return, no action
100        },
101        getValue: function(rowIndex){
102                // summary:
103                //              Overwritten, see dojox.grid.cells._Widget
104                return this.grid.selection.isSelected(rowIndex);
105        },
106        toggleRow: function(index, value){
107                // summary:
108                //              toggle checked | unchecked state for given row
109                // index: Integer
110                //              Row index
111                // value: Boolean
112                //              True - checked | False - unchecked
113                this._nativeSelect(index, value);
114        },
115        setDisabled: function(index, disabled){
116                // summary:
117                //              toggle disabled | enabled state for given row
118                // idx: Integer
119                //              Row index
120                // disabled: Boolean
121                //              True - disabled | False - enabled
122                if(index < 0){ return; }
123                this._toggleDisabledStyle(index, disabled);
124        },
125        disabled: function(index){
126                // summary:
127                //              Check if one row is disabled
128                return !!this.disabledMap[index];
129        },
130        _onClick: function(e){
131                // summary:
132                //              When mouse click on the selector cell, select/deselect the row.
133                if(e.cell === this){
134                        this._selectRow(e);
135                }
136        },
137        _dokeyup: function(e){
138                // summary:
139                //              Event handler for key up event
140                //              - from dojox.grid.enhanced._Events.dokeyup()
141                // e: Event
142                //              Key up event
143                if(e.cellIndex == this.index && e.rowIndex >= 0 && e.keyCode == keys.SPACE){
144                        this._selectRow(e);
145                }
146        },
147        focus: function(rowIndex){
148                // summary:
149                //              Set focus to given row
150                // rowIndex: Integer
151                //              Target row
152                var selector = this.map[rowIndex];
153                if(selector){ selector.focus(); }
154        },
155        _focusEndingCell: function(rowIndex, cellIndex){
156                // summary:
157                //              Set focus to the ending grid cell(rowIndex,cellIndex) when swipe selection finished
158                // rowIndex: Integer
159                //              Row index
160                // cellIndex: Integer
161                //              Column index
162                var cell = this.grid.getCell(cellIndex);
163                this.grid.focus.setFocusCell(cell, rowIndex);
164        },
165        _nativeSelect: function(index, value){
166                // summary:
167                //              Use grid's native selection
168                this.grid.selection[value ? 'select' : 'deselect'](index);
169        },
170        _onSelected: function(index){
171                // summary:
172                //              Triggered when a row is selected
173                this._toggleCheckedStyle(index, true);
174        },
175        _onDeselected: function(index){
176                // summary:
177                //              Triggered when a row is deselected
178                this._toggleCheckedStyle(index, false);
179        },
180        _onUpdateRow: function(index){
181                // summary:
182                //              Clear cache when row is re-built.
183                delete this.map[index];
184        },
185        _toggleCheckedStyle: function(index, value){
186                // summary:
187                //              Change css styles for checked | unchecked
188                var selector = this._getSelector(index);
189                if(selector){
190                        html.toggleClass(selector, this.checkedClass, value);
191                        if(this.disabledMap[index]){
192                                html.toggleClass(selector, this.checkedDisabledClass, value);
193                        }
194                        selector.setAttribute("aria-checked", value);
195                        if(this.inA11YMode){
196                                selector.firstChild.innerHTML = (value ? this.checkedText : this.unCheckedText);
197                        }
198                }
199        },
200        _toggleDisabledStyle: function(index, disabled){
201                // summary:
202                //              Change css styles for disabled | enabled
203                var selector = this._getSelector(index);
204                if(selector){
205                        html.toggleClass(selector, this.disabledClass, disabled);
206                        if(this.getValue(index)){
207                                html.toggleClass(selector, this.checkedDisabledClass, disabled);
208                        }
209                        selector.setAttribute("aria-disabled", disabled);
210                }
211                this.disabledMap[index] = disabled;
212                if(index >= 0){
213                        this.disabledCount += disabled ? 1 : -1;
214                }
215        },
216        _getSelector: function(index){
217                // summary:
218                //              Find selector for given row caching it if 1st time found
219                var selector = this.map[index];
220                if(!selector){//use accurate query for better performance
221                        var rowNode = this.view.rowNodes[index];
222                        if(rowNode){
223                                selector = query('.dojoxGridRowSelector', rowNode)[0];
224                                if(selector){ this.map[index] = selector; }
225                        }
226                }
227                return selector;
228        },
229        _pageDestroyed: function(pageIndex){
230                // summary:
231                //              Explicitly empty map cache when a page destroyed
232                //              See dojox.grid._Scroller.invalidatePageNode()
233                // pageIndex: Integer
234                //              Index of destroyed page
235                var rowsPerPage = this.grid.scroller.rowsPerPage;
236                var start = pageIndex * rowsPerPage, end = start + rowsPerPage - 1;
237                for(var i = start; i <= end; i++){
238                        if(!this.map[i]){continue;}
239                        html.destroy(this.map[i]);
240                        delete this.map[i];
241                }
242                //console.log("Page ",pageIndex, " destroyed, Map=",this.map);
243        },
244        destroy: function(){
245                for(var i in this.map){
246                        html.destroy(this.map[i]);
247                        delete this.map[i];
248                }
249                for(i in this.disabledMap){ delete this.disabledMap[i]; }
250                array.forEach(this._connects, connect.disconnect);
251                array.forEach(this._subscribes, connect.unsubscribe);
252                delete this._connects;
253                delete this._subscribes;
254                //console.log('Single(Multiple)RowSelector.destroy() executed!');
255        }
256});
257
258var SingleRowSelector = declare("dojox.grid.cells.SingleRowSelector", RowSelector, {
259        // summary:
260        //              IndirectSelection cell(column) for single selection mode, using styles of dijit.form.RadioButton
261        inputType: "Radio",
262
263        _selectRow: function(e){
264                // summary:
265                //              Select the target row
266                // e: Event
267                //              Event fired on the target row
268                var index = e.rowIndex;
269                if(this.disabledMap[index]){ return; }
270                this._focusEndingCell(index, e.cellIndex);
271                this._nativeSelect(index, !this.grid.selection.selected[index]);
272        }
273});
274
275var MultipleRowSelector = declare("dojox.grid.cells.MultipleRowSelector", RowSelector, {
276        // summary:
277        //              Indirect selection cell for multiple or extended mode, using dijit.form.CheckBox
278
279        // inputType: String
280        inputType: "CheckBox",
281       
282        // swipeStartRowIndex: Integer
283        //              Start row index for swipe selection
284        swipeStartRowIndex: -1,
285
286        // swipeMinRowIndex: Integer
287        //              Min row index for swipe selection
288        swipeMinRowIndex: -1,
289       
290        // swipeMinRowIndex: Integer
291        //              Max row index for swipe selection
292        swipeMaxRowIndex: -1,
293       
294        // toSelect: Boolean
295        //              new state for selection
296        toSelect: false,
297       
298        // lastClickRowIdx: Integer
299        //              Row index for last click, used for range selection via Shift + click
300        lastClickRowIdx: -1,
301               
302        unCheckedText: '&#9633;',
303
304        constructor: function(){
305                this._connects.push(connect.connect(win.doc, 'onmouseup', this, '_domouseup'));
306                this._connects.push(connect.connect(this.grid, 'onRowMouseOver', this, '_onRowMouseOver'));
307                this._connects.push(connect.connect(this.grid.focus, 'move', this, '_swipeByKey'));
308                this._connects.push(connect.connect(this.grid, 'onCellMouseDown', this, '_onMouseDown'));
309                if(this.headerSelector){//option set by user to add a select-all checkbox in column header
310                        this._connects.push(connect.connect(this.grid.views, 'render', this, '_addHeaderSelector'));
311                        this._connects.push(connect.connect(this.grid, '_onFetchComplete', this, '_addHeaderSelector'));
312                        this._connects.push(connect.connect(this.grid, 'onSelectionChanged', this, '_onSelectionChanged'));
313                        this._connects.push(connect.connect(this.grid, 'onKeyDown', this, function(e){
314                                if(e.rowIndex == -1 && e.cellIndex == this.index && e.keyCode == keys.SPACE){
315                                        this._toggletHeader();//TBD - a better way
316                                }
317                        }));
318                }
319        },
320        toggleAllSelection:function(checked){
321                // summary:
322                //              Toggle select all|deselect all
323                // checked: Boolean
324                //              True - select all, False - deselect all
325                var grid = this.grid, selection = grid.selection;
326                if(checked){
327                        selection.selectRange(0, grid.rowCount-1);
328                }else{
329                        selection.deselectAll();
330                }
331        },
332        _onMouseDown: function(e){
333                if(e.cell == this){
334                        this._startSelection(e.rowIndex);
335                        evt.stop(e);
336                }
337        },
338        _onRowMouseOver: function(e){
339                // summary:
340                //              Event fired when mouse moves over a data row(outside of this column).
341                //              - from dojox.grid.enhanced._Events.onRowMouseOver()
342                // e: Event
343                //              Decorated event object which contains reference to grid, cell, and rowIndex
344                this._updateSelection(e, 0);
345        },
346        _domouseup: function(e){
347                // summary:
348                //              Event handler for mouse up event - from dojo.doc.domouseup()
349                // e: Event
350                //              Mouse up event
351                if(has('ie')){
352                        this.view.content.decorateEvent(e);//TODO - why only e in IE hasn't been decorated?
353                }
354                var inSwipeSelection = e.cellIndex >= 0 && this.inSwipeSelection() && !this.grid.edit.isEditRow(e.rowIndex);
355                if(inSwipeSelection){
356                        this._focusEndingCell(e.rowIndex, e.cellIndex);
357                }
358                this._finishSelect();
359        },
360        _dokeyup: function(e){
361                // summary:
362                //              Event handler for key up event
363                //              - from dojox.grid.enhanced._Events.dokeyup()
364                // e: Event
365                //              Key up event
366                this.inherited(arguments);
367                if(!e.shiftKey){
368                        this._finishSelect();
369                }
370        },
371        _startSelection: function(rowIndex){
372                // summary:
373                //              Initialize parameters to start a new swipe selection
374                // rowIndex: Integer
375                //              Index of the start row
376                this.swipeStartRowIndex = this.swipeMinRowIndex = this.swipeMaxRowIndex = rowIndex;
377                this.toSelect = !this.getValue(rowIndex);
378        },
379        _updateSelection: function(e, delta){
380                // summary:
381                //              Update row selections, fired during a swipe selection
382                // e: Event
383                //              Event of the current row,
384                // delta: Integer
385                //              Row index delta, used for swipe selection via Shift + Arrow key
386                //              0: not via key, -1 : Shift +  Up, 1 : Shift + Down
387                if(!this.inSwipeSelection()){ return; }
388               
389                var byKey = delta !== 0;//whether via Shift + Arrow Key
390                var currRow = e.rowIndex, deltaRow = currRow - this.swipeStartRowIndex + delta;
391                if(deltaRow > 0 && this.swipeMaxRowIndex < currRow + delta){
392                        this.swipeMaxRowIndex = currRow + delta;
393                }
394                if(deltaRow < 0 && this.swipeMinRowIndex > currRow + delta){
395                        this.swipeMinRowIndex = currRow + delta;
396                }
397
398                var min = deltaRow > 0 ? this.swipeStartRowIndex : currRow + delta;
399                var max = deltaRow > 0 ? currRow + delta : this.swipeStartRowIndex;
400                for(var i = this.swipeMinRowIndex; i <= this.swipeMaxRowIndex; i++){
401                        if(this.disabledMap[i] || i < 0){ continue; }
402                        if(i >= min && i <= max){//deltaRow != 0 || this.toSelect
403                                this._nativeSelect(i, this.toSelect);
404                        }else if(!byKey){
405                                this._nativeSelect(i, !this.toSelect);
406                        }
407                }
408        },
409        _swipeByKey: function(rowOffset, colOffset, e){
410                // summary:
411                //              Update row selections, fired when Shift + Cursor is used for swipe selection
412                //              See dojox.grid.enhanced._Events.onKeyDown
413                // e: Event
414                //              Event of the current row,
415                // rowOffset: Integer
416                //              Row offset, used for swipe selection via Shift + Cursor
417                //              -1 : Shift +  Up, 1 : Shift + Down
418                if(!e || rowOffset === 0 || !e.shiftKey || e.cellIndex != this.index ||
419                        this.grid.focus.rowIndex < 0){ //TBD - e.rowIndex == 0 && delta == -1
420                        return;
421                }
422                var rowIndex = e.rowIndex;
423                if(this.swipeStartRowIndex < 0){
424                        //A new swipe selection starts via Shift + Arrow key
425                        this.swipeStartRowIndex = rowIndex;
426                        if(rowOffset > 0){//Shift + Down
427                                this.swipeMaxRowIndex = rowIndex + rowOffset;
428                                this.swipeMinRowIndex = rowIndex;
429                        }else{//Shift + UP
430                                this.swipeMinRowIndex = rowIndex + rowOffset;
431                                this.swipeMaxRowIndex = rowIndex;
432                        }
433                        this.toSelect = this.getValue(rowIndex);
434                }
435                this._updateSelection(e, rowOffset);
436        },
437        _finishSelect: function(){
438                // summary:
439                //              Reset parameters to end a swipe selection
440                this.swipeStartRowIndex = -1;
441                this.swipeMinRowIndex = -1;
442                this.swipeMaxRowIndex = -1;
443                this.toSelect = false;
444        },
445        inSwipeSelection: function(){
446                // summary:
447                //              Check if during a swipe selection
448                // returns: Boolean
449                //              Whether in swipe selection
450                return this.swipeStartRowIndex >= 0;
451        },
452        _nativeSelect: function(index, value){
453                // summary:
454                //              Overwritten
455                this.grid.selection[value ? 'addToSelection' : 'deselect'](index);
456        },
457        _selectRow: function(e){
458                // summary:
459                //              Select the target row or range or rows
460                // e: Event
461                //              Event fired on the target row
462                var rowIndex = e.rowIndex;
463                if(this.disabledMap[rowIndex]){ return; }
464                evt.stop(e);
465                this._focusEndingCell(rowIndex, e.cellIndex);
466               
467                var delta = rowIndex - this.lastClickRowIdx;
468                var newValue = !this.grid.selection.selected[rowIndex];
469                if(this.lastClickRowIdx >= 0 && !e.ctrlKey && !e.altKey && e.shiftKey){
470                        var min = delta > 0 ? this.lastClickRowIdx : rowIndex;
471                        var max = delta > 0 ? rowIndex : this.lastClickRowIdx;
472                        for(var i = min; i >= 0 && i <= max; i++){
473                                this._nativeSelect(i, newValue);
474                        }
475                }else{
476                        this._nativeSelect(rowIndex, newValue);
477                }
478                this.lastClickRowIdx = rowIndex;
479        },
480        getValue: function(rowIndex){
481                // summary:
482                //              Overwritten
483                if(rowIndex == -1){//header selector
484                        var g = this.grid;
485                        return g.rowCount > 0 && g.rowCount <= g.selection.getSelectedCount();
486                }
487                return this.inherited(arguments);
488        },
489        _addHeaderSelector: function(){
490                // summary:
491                //              Add selector in column header for selecting|deselecting all
492                var headerCellNode = this.view.getHeaderCellNode(this.index);
493                if(!headerCellNode){ return; }
494                html.empty(headerCellNode);
495                var g = this.grid;
496                var selector = headerCellNode.appendChild(html.create("div", {
497                        'aria-label': g._nls["selectAll"],
498                        "tabindex": -1, "id": g.id + "_rowSelector_-1", "class": this.baseClass, "role": "Checkbox",
499                        "innerHTML": "<span class = '" + this.statusTextClass +
500                                "'></span><span style='height: 0; width: 0; overflow: hidden; display: block;'>" +
501                                g._nls["selectAll"] + "</span>"
502                }));
503                this.map[-1] = selector;
504                var idx = this._headerSelectorConnectIdx;
505                if(idx !== undefined){
506                        connect.disconnect(this._connects[idx]);
507                        this._connects.splice(idx, 1);
508                }
509                this._headerSelectorConnectIdx = this._connects.length;
510                this._connects.push(connect.connect(selector, 'onclick', this, '_toggletHeader'));
511                this._onSelectionChanged();
512        },
513        _toggletHeader: function(){
514                // summary:
515                //              Toggle state for head selector
516                if(!!this.disabledMap[-1]){ return; }
517                this.grid._selectingRange = true;
518                this.toggleAllSelection(!this.getValue(-1));
519                this._onSelectionChanged();
520                this.grid._selectingRange = false;
521        },
522        _onSelectionChanged: function(){
523                // summary:
524                //              Update header selector anytime selection changed
525                var g = this.grid;
526                if(!this.map[-1] || g._selectingRange){ return; }
527                g.allItemsSelected = this.getValue(-1);
528                this._toggleCheckedStyle(-1, g.allItemsSelected);
529        },
530        _toggleDisabledStyle: function(index, disabled){
531                // summary:
532                //              Overwritten
533                this.inherited(arguments);
534                if(this.headerSelector){
535                        var allDisabled = (this.grid.rowCount == this.disabledCount);
536                        if(allDisabled != !!this.disabledMap[-1]){//only if needed
537                                arguments[0] = -1;
538                                arguments[1] = allDisabled;
539                                this.inherited(arguments);
540                        }
541                }
542        }
543});
544
545var IndirectSelection = declare("dojox.grid.enhanced.plugins.IndirectSelection", _Plugin, {
546        // summary:
547        //              A handy way for adding check boxe/radio button for rows, and selecting rows by swiping(or keyboard)
548
549        // description:
550        //              For better rendering performance, div(images) are used to simulate radio button|check boxes
551        //
552        // example:
553        // |    <div dojoType="dojox.grid.EnhancedGrid" plugins="{indirectSelection: true}" ...></div>
554        //              or
555        // |    <div dojoType="dojox.grid.EnhancedGrid" plugins="{indirectSelection: {name: 'xxx', width:'30px', styles:'text-align: center;'}}" ...></div>
556
557        // name: String
558        //              Plugin name
559        name: "indirectSelection",
560       
561        constructor: function(){
562                // Hook layout.setStructure(), so that indirectSelection is always included
563                var layout = this.grid.layout;
564                this.connect(layout, 'setStructure', lang.hitch(layout, this.addRowSelectCell, this.option));
565        },
566        addRowSelectCell: function(option){
567                // summary:
568                //              Add indirectSelection cell(mapped to a column of radio button|check boxes)
569                if(!this.grid.indirectSelection || this.grid.selectionMode == 'none'){
570                        return;
571                }
572                var rowSelectCellAdded = false, inValidFields = ['get', 'formatter', 'field', 'fields'],
573                defaultCellDef = {type: MultipleRowSelector, name: '', width:'30px', styles:'text-align: center;'};
574                if(option.headerSelector){ option.name = ''; }//mutual conflicting attrs
575
576                if(this.grid.rowSelectCell){//remove the existed one
577                        this.grid.rowSelectCell.destroy();
578                }
579               
580                array.forEach(this.structure, function(view){
581                        var cells = view.cells;
582                        if(cells && cells.length > 0 && !rowSelectCellAdded){
583                                var firstRow = cells[0];
584                                if(firstRow[0] && firstRow[0].isRowSelector){
585                                        console.debug('addRowSelectCell() - row selector cells already added, return.');
586                                        rowSelectCellAdded = true;
587                                        return;
588                                }
589                                var selectDef, cellType = this.grid.selectionMode == 'single' ? SingleRowSelector : MultipleRowSelector;
590                                selectDef = lang.mixin(defaultCellDef, option, {type: cellType, editable: false, notselectable: true, filterable: false, navigatable: true, nosort: true});
591                                array.forEach(inValidFields, function(field){//remove invalid fields
592                                        if(field in selectDef){ delete selectDef[field]; }
593                                });
594                                if(cells.length > 1){ selectDef.rowSpan = cells.length; }//for complicate layout
595                                array.forEach(this.cells, function(cell, i){
596                                        if(cell.index >= 0){
597                                                cell.index += 1;
598                                                //console.debug('cell '+ (cell.index - 1) +  ' is updated to index ' + cell.index);
599                                        }else{
600                                                console.warn('Error:IndirectSelection.addRowSelectCell()-  cell ' + i + ' has no index!');
601                                        }
602                                });
603                                var rowSelectCell = this.addCellDef(0, 0, selectDef);
604                                rowSelectCell.index = 0;
605                                firstRow.unshift(rowSelectCell);
606                                this.cells.unshift(rowSelectCell);
607                                this.grid.rowSelectCell = rowSelectCell;
608                                rowSelectCellAdded = true;
609                        }
610                }, this);
611                this.cellCount = this.cells.length;
612        },
613        destroy: function(){
614                this.grid.rowSelectCell.destroy();
615                delete this.grid.rowSelectCell;
616                this.inherited(arguments);
617        }
618});
619
620EnhancedGrid.registerPlugin(IndirectSelection/*name:'indirectSelection'*/, {"preInit": true});
621
622return IndirectSelection;
623});
Note: See TracBrowser for help on using the repository browser.