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

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

Added Dojo 1.9.3 release.

File size: 10.2 KB
Line 
1define([
2        "dojo/_base/declare",
3        "dojo/_base/array",
4        "dojo/_base/lang",
5        "dojo/_base/sniff",
6        "dojo/_base/html",
7        "dojo/_base/json",
8        "dojo/_base/window",
9        "dojo/_base/unload",
10        "dojo/cookie",
11        "../_Plugin",
12        "../../_RowSelector",
13        "../../EnhancedGrid",
14        "../../cells/_base"
15], function(declare, array, lang, has, html, json, win, unload, cookie, _Plugin, _RowSelector, EnhancedGrid){
16
17        var gridCells = lang.getObject("dojox.grid.cells");
18
19        // Generate a cookie key for the given grid.
20        var _cookieKeyBuilder = function(grid){
21                return window.location + "/" + grid.id;
22        };
23       
24        //Utilities:
25        var _getCellsFromStructure = function(structure){
26                var cells = [];
27                if(!lang.isArray(structure)){
28                        structure = [structure];
29                }
30                array.forEach(structure,function(viewDef){
31                        if(lang.isArray(viewDef)){
32                                viewDef = {"cells" : viewDef};
33                        }
34                        var rows = viewDef.rows || viewDef.cells;
35                        if(lang.isArray(rows)){
36                                if(!lang.isArray(rows[0])){
37                                        rows = [rows];
38                                }
39                                array.forEach(rows, function(row){
40                                        if(lang.isArray(row)){
41                                                array.forEach(row, function(cell){
42                                                        cells.push(cell);
43                                                });
44                                        }
45                                });
46                        }
47                });
48                return cells;
49        };
50       
51        // Persist column width
52        var _loadColWidth = function(colWidths, grid){
53                if(lang.isArray(colWidths)){
54                        var oldFunc = grid._setStructureAttr;
55                        grid._setStructureAttr = function(structure){
56                                if(!grid._colWidthLoaded){
57                                        grid._colWidthLoaded = true;
58                                        var cells = _getCellsFromStructure(structure);
59                                        for(var i = cells.length - 1; i >= 0; --i){
60                                                if(typeof colWidths[i] == "number"){
61                                                        cells[i].width = colWidths[i] + "px";
62                                                }else if(colWidths[i] == 'hidden'){
63                                                        cells[i].hidden = true;
64                                                }
65                                        }
66                                }
67                                oldFunc.call(grid, structure);
68                                grid._setStructureAttr = oldFunc;
69                        };
70                }
71        };
72       
73
74        var _saveColWidth = function(grid){
75                return array.map(array.filter(grid.layout.cells, function(cell){
76                        return !(cell.isRowSelector || cell instanceof gridCells.RowIndex);
77                }), function(cell){
78                        return cell.hidden ? 'hidden' : html[has('webkit') ? "marginBox" : "contentBox"](cell.getHeaderNode()).w;
79                });
80        };
81       
82        // Persist column order
83        var _loadColumnOrder = function(colOrder, grid){
84                if(colOrder && array.every(colOrder, function(viewInfo){
85                        return lang.isArray(viewInfo) && array.every(viewInfo, function(subrowInfo){
86                                return lang.isArray(subrowInfo) && subrowInfo.length > 0;
87                        });
88                })){
89                        var oldFunc = grid._setStructureAttr;
90                        var isCell = function(def){
91                                return ("name" in def || "field" in def || "get" in def);
92                        };
93                        var isView = function(def){
94                                return (def !== null && lang.isObject(def) &&
95                                                ("cells" in def || "rows" in def || ("type" in def && !isCell(def))));
96                        };
97                        grid._setStructureAttr = function(structure){
98                                if(!grid._colOrderLoaded){
99                                        grid._colOrderLoaded = true;
100                                        grid._setStructureAttr = oldFunc;
101                                        structure = lang.clone(structure);
102                                        if(lang.isArray(structure) && !array.some(structure, isView)){
103                                                structure = [{ cells: structure }];
104                                        }else if(isView(structure)){
105                                                structure = [structure];
106                                        }
107                                        var cells = _getCellsFromStructure(structure);
108                                        array.forEach(lang.isArray(structure) ? structure : [structure], function(viewDef, viewIdx){
109                                                var cellArray = viewDef;
110                                                if(lang.isArray(viewDef)){
111                                                        viewDef.splice(0, viewDef.length);
112                                                }else{
113                                                        delete viewDef.rows;
114                                                        cellArray = viewDef.cells = [];
115                                                }
116                                                array.forEach(colOrder[viewIdx], function(subrow){
117                                                        array.forEach(subrow, function(cellInfo){
118                                                                var i, cell;
119                                                                for(i = 0; i < cells.length; ++i){
120                                                                        cell = cells[i];
121                                                                        if(json.toJson({'name':cell.name,'field':cell.field}) == json.toJson(cellInfo)){
122                                                                                break;
123                                                                        }
124                                                                }
125                                                                if(i < cells.length){
126                                                                        cellArray.push(cell);
127                                                                }
128                                                        });
129                                                });
130                                        });
131                                }
132                                oldFunc.call(grid, structure);
133                        };
134                }
135        };
136       
137        var _saveColumnOrder = function(grid){
138                var colOrder = array.map(array.filter(grid.views.views, function(view){
139                        return !(view instanceof _RowSelector);
140                }), function(view){
141                        return array.map(view.structure.cells, function(subrow){
142                                return array.map(array.filter(subrow, function(cell){
143                                        return !(cell.isRowSelector || cell instanceof gridCells.RowIndex);
144                                }), function(cell){
145                                        return {
146                                                "name": cell.name,
147                                                "field": cell.field
148                                        };
149                                });
150                        });
151                });
152                return colOrder;
153        };
154       
155        // Persist sorting order
156        var _loadSortOrder = function(sortOrder, grid){
157                try{
158                        if(sortOrder && lang.isObject(sortOrder)){
159                                grid.setSortIndex(sortOrder.idx, sortOrder.asc);
160                        }
161                }catch(e){
162                        //setSortIndex will finally call _fetch, some exceptions will be throw
163                        //'cause the grid hasn't be fully loaded now. Just ignore them.
164                }
165        };
166       
167        var _saveSortOrder = function(grid){
168                return {
169                        idx: grid.getSortIndex(),
170                        asc: grid.getSortAsc()
171                };
172        };
173       
174        if(!has('ie')){
175                // Now in non-IE, widgets are no longer destroyed on page unload,
176                // so we have to destroy it manually to trigger saving cookie.
177                unload.addOnWindowUnload(function(){
178                        array.forEach(dijit.findWidgets(win.body()), function(widget){
179                                if(widget instanceof EnhancedGrid && !widget._destroyed){
180                                        widget.destroyRecursive();
181                                }
182                        });
183                });
184        }
185       
186        var Cookie = declare("dojox.grid.enhanced.plugins.Cookie", _Plugin, {
187                // summary:
188                //              This plugin provides a way to persist some grid features in cookie.
189                //              Default persistable features are:
190                //              column width:   "columnWidth" (handler name)
191                //              column order:   "columnOrder"
192                //              sorting order:  "sortOrder"
193                //
194                //              Grid users can define new persistable features
195                //              by calling the following before grid is initialized (that is, during "preInit");
196                //              |       grid.addCookieHandler({
197                //              |               name: "a name for the new persistable feature",
198                //              |               onLoad: function(savedObject, grid){
199                //              |                       //load the cookie.
200                //              |               },
201                //              |               onSave: function(grid){
202                //              |                       //save the cookie.
203                //              |               }
204                //              |       });
205               
206                // name: String
207                //              Plugin name
208                name: "cookie",
209               
210                _cookieEnabled: true,
211               
212                constructor: function(grid, args){
213                        this.grid = grid;
214                        args = (args && lang.isObject(args)) ? args : {};
215                        this.cookieProps = args.cookieProps;
216                        this._cookieHandlers = [];
217                        this._mixinGrid();
218                       
219                        //Column width & simple sorting & column reorder are base grid features, so they must be supported.
220                        this.addCookieHandler({
221                                name: "columnWidth",
222                                onLoad: _loadColWidth,
223                                onSave: _saveColWidth
224                        });
225                        this.addCookieHandler({
226                                name: "columnOrder",
227                                onLoad: _loadColumnOrder,
228                                onSave: _saveColumnOrder
229                        });
230                        this.addCookieHandler({
231                                name: "sortOrder",
232                                onLoad: _loadSortOrder,
233                                onSave: _saveSortOrder
234                        });
235                       
236                        array.forEach(this._cookieHandlers, function(handler){
237                                if(args[handler.name] === false){
238                                        handler.enable = false;
239                                }
240                        }, this);
241                },
242                destroy:function(){
243                        this._saveCookie();
244                        this._cookieHandlers = null;
245                        this.inherited(arguments);
246                },
247                _mixinGrid: function(){
248                        var g = this.grid;
249                        g.addCookieHandler = lang.hitch(this, "addCookieHandler");
250                        g.removeCookie = lang.hitch(this, "removeCookie");
251                        g.setCookieEnabled = lang.hitch(this, "setCookieEnabled");
252                        g.getCookieEnabled = lang.hitch(this, "getCookieEnabled");
253                },
254                _saveCookie: function(){
255                        if(this.getCookieEnabled()){
256                                var ck = {},
257                                        chs = this._cookieHandlers,
258                                        cookieProps = this.cookieProps,
259                                        cookieKey = _cookieKeyBuilder(this.grid);
260                                for(var i = chs.length-1; i >= 0; --i){
261                                        if(chs[i].enabled){
262                                                //Do the real saving work here.
263                                                ck[chs[i].name] = chs[i].onSave(this.grid);
264                                        }
265                                }
266                                cookieProps = lang.isObject(this.cookieProps) ? this.cookieProps : {};
267                                cookie(cookieKey, json.toJson(ck), cookieProps);
268                        }else{
269                                this.removeCookie();
270                        }
271                },
272                onPreInit: function(){
273                        var grid = this.grid,
274                                chs = this._cookieHandlers,
275                                cookieKey = _cookieKeyBuilder(grid),
276                                ck = cookie(cookieKey);
277                        if(ck){
278                                ck = json.fromJson(ck);
279                                for(var i = 0; i < chs.length; ++i){
280                                        if(chs[i].name in ck && chs[i].enabled){
281                                                //Do the real loading work here.
282                                                chs[i].onLoad(ck[chs[i].name], grid);
283                                        }
284                                }
285                        }
286                        this._cookie = ck || {};
287                        this._cookieStartedup = true;
288                },
289                addCookieHandler: function(args){
290                        // summary:
291                        //              If a grid plugin wants cookie service, call this.
292                        //              This must be called during preInit.
293                        // args: Object
294                        //              An object with the following structure:
295                        //      |       {
296                        //      |               name: "some-string",
297                        //      |               onLoad: /* void */ function(/* object */partOfCookie, /* EDG */grid){...},
298                        //      |               onSave: /* object */ function(/* EDG */grid){...}
299                        //      |       }
300                        if(args.name){
301                                var dummy = function(){};
302                                args.onLoad = args.onLoad || dummy;
303                                args.onSave = args.onSave || dummy;
304                                if(!("enabled" in args)){
305                                        args.enabled = true;
306                                }
307                                for(var i = this._cookieHandlers.length - 1; i >= 0; --i){
308                                        if(this._cookieHandlers[i].name == args.name){
309                                                this._cookieHandlers.splice(i, 1);
310                                        }
311                                }
312                                this._cookieHandlers.push(args);
313                                if(this._cookieStartedup && args.name in this._cookie){
314                                        args.onLoad(this._cookie[args.name], this.grid);
315                                }
316                        }
317                },
318                removeCookie: function(){
319                        // summary:
320                        //              Remove cookie for this grid.
321                        var key = _cookieKeyBuilder(this.grid);
322                        cookie(key, null, {expires: -1});
323                },
324                setCookieEnabled: function(cookieName, enabled){
325                        // summary:
326                        //              A setter to enable|disable cookie support for a particular Grid feature.
327                        // cookieName: String?
328                        //              Name of a cookie handler if provided, otherwise for all cookies.
329                        // enabled: Boolean
330                        if(typeof cookieName == 'string'){
331                                var chs = this._cookieHandlers;
332                                for(var i = chs.length - 1; i >= 0; --i){
333                                        if(chs[i].name === cookieName){
334                                                chs[i].enabled = !!enabled;
335                                        }
336                                }
337                        }else{
338                                this._cookieEnabled = !!cookieName;
339                                if(!this._cookieEnabled){ this.removeCookie(); }
340                        }
341                },
342                getCookieEnabled: function(cookieName){
343                        // summary:
344                        //              A getter to check cookie support of a particular Grid feature.
345                        // cookieName: String?
346                        //              Name of a cookie handler if provided, otherwise for all cookies.
347                        if(lang.isString(cookieName)){
348                                var chs = this._cookieHandlers;
349                                for(var i = chs.length - 1; i >= 0; --i){
350                                        if(chs[i].name == cookieName){ return chs[i].enabled; }
351                                }
352                                return false;
353                        }
354                        return this._cookieEnabled;
355                }
356        });
357
358        EnhancedGrid.registerPlugin(Cookie, {"preInit": true});
359
360        return Cookie;
361});
Note: See TracBrowser for help on using the repository browser.