1 | define([ |
---|
2 | "dojo/_base/declare", |
---|
3 | "dojo/_base/lang", |
---|
4 | "dojo/_base/connect", |
---|
5 | '../../_SelectionPreserver' |
---|
6 | ], function(declare, lang, connect, _SelectionPreserver){ |
---|
7 | |
---|
8 | return declare("dojox.grid.enhanced.plugins._SelectionPreserver", _SelectionPreserver, { |
---|
9 | // summary: |
---|
10 | // Preserve selections across various user actions. |
---|
11 | // |
---|
12 | // description: |
---|
13 | // Extends dojox.grid._SelectionPreserver adding a bit more support to make selection persistence working well |
---|
14 | // with various EnhancedGrid features, e.g. filtering, nested sorting, pagination, select all etc. |
---|
15 | // |
---|
16 | // Precondition - Identifier(id) is required for store, as id is used for differentiating row items. |
---|
17 | // Known issue - The preserved selections might be inaccurate if some unloaded rows are previously selected by range(e.g.SHIFT + click) |
---|
18 | // |
---|
19 | // example: |
---|
20 | // | //To turn on this - set 'keepSelection' attribute to true |
---|
21 | // | <div dojoType="dojox.grid.EnhancedGrid" keepSelection = true .../> |
---|
22 | |
---|
23 | constructor: function(selection){ |
---|
24 | var grid = this.grid; |
---|
25 | grid.onSelectedById = this.onSelectedById; |
---|
26 | this._oldClearData = grid._clearData; |
---|
27 | var self = this; |
---|
28 | grid._clearData = function(){ |
---|
29 | self._updateMapping(!grid._noInternalMapping); |
---|
30 | self._trustSelection = []; |
---|
31 | self._oldClearData.apply(grid, arguments); |
---|
32 | }; |
---|
33 | this._connects.push( |
---|
34 | connect.connect(selection, 'selectRange', lang.hitch(this, '_updateMapping', true, true, false)), |
---|
35 | connect.connect(selection, 'deselectRange', lang.hitch(this, '_updateMapping', true, false, false)), |
---|
36 | connect.connect(selection, 'deselectAll', lang.hitch(this, '_updateMapping', true, false, true)) |
---|
37 | ); |
---|
38 | }, |
---|
39 | destroy: function(){ |
---|
40 | this.inherited(arguments); |
---|
41 | this.grid._clearData = this._oldClearData; |
---|
42 | }, |
---|
43 | reset: function(){ |
---|
44 | this.inherited(arguments); |
---|
45 | this._idMap = []; |
---|
46 | this._trustSelection = []; |
---|
47 | this._defaultSelected = false; |
---|
48 | }, |
---|
49 | _reSelectById: function(item, index){ |
---|
50 | // summary: |
---|
51 | // Overwritten |
---|
52 | var s = this.selection, g = this.grid; |
---|
53 | if(item && g._hasIdentity){ |
---|
54 | var id = g.store.getIdentity(item); |
---|
55 | if(this._selectedById[id] === undefined){ |
---|
56 | if(!this._trustSelection[index]){ |
---|
57 | s.selected[index] = this._defaultSelected; |
---|
58 | } |
---|
59 | }else{ |
---|
60 | s.selected[index] = this._selectedById[id]; |
---|
61 | } |
---|
62 | this._idMap.push(id); |
---|
63 | g.onSelectedById(id, index, s.selected[index]); |
---|
64 | } |
---|
65 | }, |
---|
66 | _selectById: function(toSelect, inItemOrIndex){ |
---|
67 | // summary: |
---|
68 | // Overwritten |
---|
69 | if(!this.inherited(arguments)){ |
---|
70 | this._trustSelection[inItemOrIndex] = true; |
---|
71 | } |
---|
72 | }, |
---|
73 | onSelectedById: function(id, rowIndex, value){}, |
---|
74 | |
---|
75 | _updateMapping: function(trustSelection, isSelect, isForAll, from, to){ |
---|
76 | // summary: |
---|
77 | // This function try to keep the selection info updated when range selection is performed. |
---|
78 | // |
---|
79 | // 1. Calculate how many unloaded rows are there; |
---|
80 | // 2. update _selectedById data if grid.selection._selected can be trusted, so loaded but unselected rows can |
---|
81 | // be properly recorded. |
---|
82 | var s = this.selection, g = this.grid, flag = 0, unloaded = 0, i, id; |
---|
83 | for(i = g.rowCount - 1; i >= 0; --i){ |
---|
84 | if(!g._by_idx[i]){ |
---|
85 | ++unloaded; |
---|
86 | flag += s.selected[i] ? 1 : -1; |
---|
87 | }else{ |
---|
88 | id = g._by_idx[i].idty; |
---|
89 | if(id && (trustSelection || this._selectedById[id] === undefined)){ |
---|
90 | this._selectedById[id] = !!s.selected[i]; |
---|
91 | } |
---|
92 | } |
---|
93 | } |
---|
94 | if(unloaded){ |
---|
95 | this._defaultSelected = flag > 0; |
---|
96 | } |
---|
97 | if(!isForAll && from !== undefined && to !== undefined){ |
---|
98 | isForAll = !g.usingPagination && Math.abs(to - from + 1) === g.rowCount; |
---|
99 | } |
---|
100 | // When deselectAll, make sure every thing is deselected, even if it was selected but not loaded now. |
---|
101 | // This occurs only when pagination's "All" is used. |
---|
102 | if(isForAll && (!g.usingPagination || g.selectionMode === 'single')){ |
---|
103 | for(i = this._idMap.length - 1; i >= 0; --i){ |
---|
104 | this._selectedById[this._idMap[i]] = isSelect; |
---|
105 | } |
---|
106 | } |
---|
107 | } |
---|
108 | }); |
---|
109 | }); |
---|