123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- /*
- 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._SelectionPreserver"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
- dojo._hasResource["dojox.grid.enhanced.plugins._SelectionPreserver"] = true;
- dojo.provide("dojox.grid.enhanced.plugins._SelectionPreserver");
- dojo.declare("dojox.grid.enhanced.plugins._SelectionPreserver", null, {
- // summary:
- // Preserve selections across various user actions.
- //
- // description:
- // When this feature turned on, Grid will try to preserve selections across various user actions, e.g. sorting, filtering etc.
- // Precondition - Identifier(id) is required for store, as id is used for differentiating row items.
- // Known issue - The preserved selections might be inaccurate if some unloaded rows are selected by range previously(e.g.SHIFT + click)
- //
- // example:
- // | //To turn on this - set 'keepSelection' attribute to true
- // | <div dojoType="dojox.grid.EnhancedGrid" keepSelection = true .../>
-
- //_connects: Array
- // List of all connections.
- _connects: [],
-
- constructor: function(selection){
- this.selection = selection;
- var grid = this.grid = selection.grid;
- grid.onSelectedById = this.onSelectedById;
- this.reset();
- var oldClearData = grid._clearData;
- var _this = this;
- grid._clearData = function(){
- _this._updateMapping(!grid._noInternalMapping);
- _this._trustSelection = [];
- oldClearData.apply(grid, arguments);
- };
- this.connect(grid, '_setStore', 'reset');
- this.connect(grid, '_addItem', '_reSelectById');
- this.connect(selection, 'addToSelection', dojo.hitch(this, '_selectById', true));
- this.connect(selection, 'deselect', dojo.hitch(this, '_selectById', false));
- this.connect(selection, 'selectRange', dojo.hitch(this, '_updateMapping', true, true, false));
- this.connect(selection, 'deselectRange', dojo.hitch(this, '_updateMapping', true, false, false));
- this.connect(selection, 'deselectAll', dojo.hitch(this, '_updateMapping', true, false, true));
- },
- destroy: function(){
- this.reset();
- dojo.forEach(this._connects, dojo.disconnect);
- delete this._connects;
- },
- connect: function(obj, event, method){
- // summary:
- // Connects specified obj/event to specified method of this object.
- var conn = dojo.connect(obj, event, this, method);
- this._connects.push(conn);
- return conn;
- },
- reset: function(){
- this._idMap = [];
- this._selectedById = {};
- this._trustSelection = [];
- this._defaultSelected = false;
- },
- _reSelectById: function(item, index){
- // summary:
- // When some rows is fetched, determine whether it should be selected.
- // When this function is called, grid.selection.selected[] is not trustable.
- var s = this.selection, g = this.grid;
- if(item && g._hasIdentity){
- var id = g.store.getIdentity(item);
- if(this._selectedById[id] === undefined){
- if(!this._trustSelection[index]){
- s.selected[index] = this._defaultSelected;
- }
- }else{
- s.selected[index] = this._selectedById[id];
- }
- this._idMap.push(id);
- g.onSelectedById(id, index, s.selected[index]);
- }
- },
- _selectById: function(toSelect, inItemOrIndex){
- // summary:
- // Record selected rows by ID.
- if(this.selection.mode == 'none' || !this.grid._hasIdentity){ return; }
- var item = inItemOrIndex;
- if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
- var entry = this.grid._by_idx[inItemOrIndex];
- item = entry && entry.item;
- }
- if(item){
- var id = this.grid.store.getIdentity(item);
- this._selectedById[id] = !!toSelect;
- }else{
- this._trustSelection[inItemOrIndex] = true;
- }
- },
- onSelectedById: function(id, rowIndex, value){},
-
- _updateMapping: function(trustSelection, isSelect, isForAll, from, to){
- // summary:
- // This function trys to keep the selection info updated when range selection is performed.
- // 1. Calculate how many unloaded rows are there;
- // 2. update _selectedById data if grid.selection._selected can be trusted, so loaded but unselected rows can
- // be properly recorded.
- var s = this.selection, g = this.grid, flag = 0, unloaded = 0, i, id;
- for(i = g.rowCount - 1; i >= 0; --i){
- if(!g._by_idx[i]){
- ++unloaded;
- flag += s.selected[i] ? 1 : -1;
- }else{
- id = g._by_idx[i].idty;
- if(id && (trustSelection || this._selectedById[id] === undefined)){
- this._selectedById[id] = !!s.selected[i];
- }
- }
- }
- if(unloaded){
- this._defaultSelected = flag > 0;
- }
- if(!isForAll && from !== undefined && to !== undefined){
- isForAll = !g.usingPagination && Math.abs(to - from + 1) === g.rowCount;
- }
- // When deselectAll, make sure every thing is deselected, even if it was selected but not loaded now.
- // This occurs only when pagination's "All" is used.
- if(isForAll && !g.usingPagination){
- for(i = this._idMap.length; i >= 0; --i){
- this._selectedById[this._idMap[i]] = isSelect;
- }
- }
- }
- });
- }
|