Cookie.js 10 KB

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