Cookie.js 10 KB

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