EnhancedGrid.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  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.EnhancedGrid"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.grid.EnhancedGrid"] = true;
  8. dojo.provide("dojox.grid.EnhancedGrid");
  9. dojo.require("dojox.grid.DataGrid");
  10. dojo.require("dojox.grid.enhanced._PluginManager");
  11. dojo.requireLocalization("dojox.grid.enhanced", "EnhancedGrid", null, "ROOT,ar,bg,ca,cs,da,de,el,es,fi,fr,he,hr,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw");
  12. dojo.experimental("dojox.grid.EnhancedGrid");
  13. dojo.declare("dojox.grid.EnhancedGrid", dojox.grid.DataGrid, {
  14. // summary:
  15. // Provides enhanced features based on DataGrid
  16. //
  17. // description:
  18. // EnhancedGrid features are implemented as plugins that could be loaded on demand.
  19. // Explicit dojo.require() is needed to use these feature plugins.
  20. //
  21. // example:
  22. // A quick sample to use EnhancedGrid features:
  23. //
  24. // Step 1. Load EnhancedGrid and required features
  25. // | <script type="text/javascript">
  26. // | dojo.require("dojox.grid.EnhancedGrid");
  27. // | dojo.require("dojox.grid.enhanced.plugins.DnD");
  28. // | dojo.require("dojox.grid.enhanced.plugins.Menu");
  29. // | dojo.require("dojox.grid.enhanced.plugins.NestedSorting");
  30. // | dojo.require("dojox.grid.enhanced.plugins.IndirectSelection");
  31. // | </script>
  32. //
  33. // Step 2. Use EnhancedGrid
  34. // - Via HTML markup
  35. // | <div dojoType="dojox.grid.EnhancedGrid" ...
  36. // | plugins="{nestedSorting: true, dnd: true, indirectSelection: true,
  37. // | menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",
  38. // | selectedRegionMenu:"selectedRegionMenuId"}}">
  39. // | ...
  40. // | </div>
  41. //
  42. // - Or via JavaScript
  43. // | <script type="text/javascript">
  44. // | var grid = new dojox.grid.EnhancedGrid({plugins : {nestedSorting: true, dnd: true, indirectSelection: true,
  45. // | menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",selectedRegionMenu:"selectedRegionMenuId"}},
  46. // | ... }, dojo.byId('gridDiv'));
  47. // | grid.startup();
  48. // | </script>
  49. //
  50. //
  51. // Plugin Support
  52. // [Note: Plugin support is still experimental]
  53. //
  54. // You can either customize the default plugins or add new ones, more details please see
  55. // - dojox.grid.enhanced._PluginManager
  56. // - dojox.grid.enhanced._Plugin
  57. // - dojox.grid.enhanced.plugins.*
  58. //plugins: Object
  59. // Plugin properties, e.g. {nestedSorting: true, dnd: true, ...}
  60. plugins: null,
  61. //pluginMgr: Object
  62. // Singleton plugin manager
  63. pluginMgr: null,
  64. //keepSelection: Boolean
  65. // Whether keep selection after sort, filter, pagination etc.
  66. keepSelection: false,
  67. //_pluginMgrClass: Object
  68. // Default plugin manager class
  69. _pluginMgrClass: dojox.grid.enhanced._PluginManager,
  70. postMixInProperties: function(){
  71. //load nls bundle
  72. this._nls = dojo.i18n.getLocalization("dojox.grid.enhanced", "EnhancedGrid", this.lang);
  73. this.inherited(arguments);
  74. },
  75. postCreate: function(){
  76. //create plugin manager
  77. this.pluginMgr = new this._pluginMgrClass(this);
  78. this.pluginMgr.preInit();
  79. this.inherited(arguments);
  80. this.pluginMgr.postInit();
  81. },
  82. plugin: function(/*String*/name){
  83. // summary:
  84. // An easier way for getting a plugin, e.g. grid.plugin('dnd')
  85. return this.pluginMgr.getPlugin(name);
  86. },
  87. startup: function(){
  88. this.inherited(arguments);
  89. this.pluginMgr.startup();
  90. },
  91. createSelection: function(){
  92. this.selection = new dojox.grid.enhanced.DataSelection(this);
  93. },
  94. canSort: function(colIndex, field){
  95. // summary:
  96. // Overwritten
  97. return true;
  98. },
  99. doKeyEvent: function(e){
  100. // summary:
  101. // Overwritten, see _Grid.doKeyEvent()
  102. try{
  103. var view = this.focus.focusView;
  104. view.content.decorateEvent(e);
  105. if(!e.cell){ view.header.decorateEvent(e); }
  106. }catch(e){}
  107. this.inherited(arguments);
  108. },
  109. doApplyCellEdit: function(inValue, inRowIndex, inAttrName){
  110. // summary:
  111. // Overwritten, see DataGrid.doApplyCellEdit()
  112. if(!inAttrName){
  113. this.invalidated[inRowIndex] = true;
  114. return;
  115. }
  116. this.inherited(arguments);
  117. },
  118. mixin: function(target, source){
  119. var props = {};
  120. for(var p in source){
  121. if(p == '_inherited' || p == 'declaredClass' || p == 'constructor' ||
  122. source['privates'] && source['privates'][p]){
  123. continue;
  124. }
  125. props[p] = source[p];
  126. }
  127. dojo.mixin(target, props);
  128. },
  129. _copyAttr: function(idx, attr){
  130. // summary:
  131. // Overwritten, see DataGrid._copyAttr()
  132. // Fix cell TAB navigation for single click editing
  133. if(!attr){ return; }
  134. return this.inherited(arguments);
  135. },
  136. _getHeaderHeight: function(){
  137. // summary:
  138. // Overwritten, see _Grid._getHeaderHeight()
  139. // Should include borders/margins of this.viewsHeaderNode
  140. this.inherited(arguments);
  141. return dojo.marginBox(this.viewsHeaderNode).h;
  142. },
  143. _fetch: function(start, isRender){
  144. // summary:
  145. // Overwritten, see DataGrid._fetch()
  146. if(this.items){
  147. return this.inherited(arguments);
  148. }
  149. start = start || 0;
  150. if(this.store && !this._pending_requests[start]){
  151. if(!this._isLoaded && !this._isLoading){
  152. this._isLoading = true;
  153. this.showMessage(this.loadingMessage);
  154. }
  155. this._pending_requests[start] = true;
  156. try{
  157. var req = {
  158. start: start,
  159. count: this.rowsPerPage,
  160. query: this.query,
  161. sort: this.getSortProps(),
  162. queryOptions: this.queryOptions,
  163. isRender: isRender,
  164. onBegin: dojo.hitch(this, "_onFetchBegin"),
  165. onComplete: dojo.hitch(this, "_onFetchComplete"),
  166. onError: dojo.hitch(this, "_onFetchError")
  167. };
  168. this._storeLayerFetch(req);
  169. }catch(e){
  170. this._onFetchError(e, {start: start, count: this.rowsPerPage});
  171. }
  172. }
  173. return 0;
  174. },
  175. _storeLayerFetch: function(req){
  176. // summary:
  177. // Extracted fetch specifically for store layer use
  178. this.store.fetch(req);
  179. },
  180. getCellByField: function(field){
  181. return dojo.filter(this.layout.cells, function(cell){
  182. return cell.field == field;
  183. })[0];
  184. },
  185. onMouseUp: function(e){ },
  186. createView: function(){
  187. // summary
  188. // Overwrite: rewrite getCellX of view.header
  189. var view = this.inherited(arguments);
  190. if(dojo.isMoz){
  191. var ascendDom = function(inNode, inWhile){
  192. for(var n = inNode; n && inWhile(n); n = n.parentNode){}
  193. return n;
  194. };//copied from dojox.grid._Builder
  195. var makeNotTagName = function(inTagName){
  196. var name = inTagName.toUpperCase();
  197. return function(node){ return node.tagName != name; };
  198. };//copied from dojox.grid._Builder
  199. var func = view.header.getCellX;
  200. view.header.getCellX = function(e){
  201. var x = func.call(view.header, e);
  202. var n = ascendDom(e.target, makeNotTagName("th"));
  203. if(n && n !== e.target && dojo.isDescendant(e.target, n)){ x += n.firstChild.offsetLeft; }
  204. return x;
  205. };
  206. }
  207. return view;
  208. },
  209. destroy: function(){
  210. // summary:
  211. // Destroy all resources
  212. delete this._nls;
  213. this.selection.destroy();
  214. this.pluginMgr.destroy();
  215. this.inherited(arguments);
  216. }
  217. });
  218. dojo.provide("dojox.grid.enhanced.DataSelection");
  219. dojo.require("dojox.grid.enhanced.plugins._SelectionPreserver");//default loaded plugin
  220. dojo.declare("dojox.grid.enhanced.DataSelection", dojox.grid.DataSelection, {
  221. constructor: function(grid){
  222. if(grid.keepSelection){
  223. this.preserver = new dojox.grid.enhanced.plugins._SelectionPreserver(this);
  224. }
  225. },
  226. _range: function(inFrom, inTo){
  227. this.grid._selectingRange = true;
  228. this.inherited(arguments);
  229. this.grid._selectingRange = false;
  230. this.onChanged();
  231. },
  232. deselectAll: function(inItemOrIndex){
  233. this.grid._selectingRange = true;
  234. this.inherited(arguments);
  235. this.grid._selectingRange = false;
  236. this.onChanged();
  237. },
  238. destroy: function(){
  239. if(this.preserver){
  240. this.preserver.destroy();
  241. }
  242. }
  243. });
  244. dojox.grid.EnhancedGrid.markupFactory = function(props, node, ctor, cellFunc){
  245. return dojox.grid._Grid.markupFactory(props, node, ctor,
  246. dojo.partial(dojox.grid.DataGrid.cell_markupFactory, cellFunc));
  247. };
  248. dojox.grid.EnhancedGrid.registerPlugin = function(clazz, props){
  249. dojox.grid.enhanced._PluginManager.registerPlugin(clazz, props);
  250. };
  251. }