PageRenderTime 51ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/dojo-release-1.5.0-src/release/mfu-dojo-embedded/dojox/grid/enhanced/_Plugin.js

https://github.com/samokk/mfu
JavaScript | 374 lines | 197 code | 49 blank | 128 comment | 69 complexity | 5111cb11145aab292d994bce04a3dd5c MD5 | raw file
  1. /*
  2. Copyright (c) 2004-2010, 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._Plugin"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.grid.enhanced._Plugin"] = true;
  8. dojo.provide("dojox.grid.enhanced._Plugin");
  9. dojo.require("dojox.grid.enhanced._Builder");
  10. dojo.require("dojox.grid.enhanced._Events");
  11. dojo.declare("dojox.grid.enhanced._Plugin", null, {
  12. // summary:
  13. // Singleton plugin manager
  14. //
  15. // description:
  16. // Plugin manager is responsible for
  17. // 1. Loading required plugins
  18. // 2. Handling collaboration and dependencies among plugins
  19. // 3. Overwriting some default behavior of DataGrid
  20. //
  21. // Note: Mixin and method caching are used for #3, this might be refined once
  22. // an overall plugin architecture is set up for DataGrid.
  23. //
  24. // Some plugin dependencies:
  25. // - DnD plugin depends on NestedSorting plugin
  26. // - RowSelector should be used for DnD plugin.
  27. // e.g. <div dojoType="dojox.grid.EnhancedGrid" plugins='{dnd: true, ...}}' rowSelector="20px" .../>
  28. // - "columnReordering" attribute won't work when either DnD or Indirect Selections plugin is on.
  29. //fixedCellNum: Integer
  30. // Number of fixed cells(columns), e.g. cell(column) of indirect selection is fixed and can't be moved
  31. fixedCellNum: -1,
  32. //funcMap: Object
  33. // Map for caching default DataGrid methods.
  34. funcMap:{},
  35. constructor: function(inGrid){
  36. this.grid = inGrid;
  37. this._parseProps(this.grid);
  38. },
  39. _parseProps: function(grid){
  40. // summary:
  41. // Parse plugins properties
  42. // grid: Grid
  43. // Grid this plugin manager belongs to
  44. //mixin all plugin properties into Grid
  45. grid.plugins && dojo.mixin(grid, grid.plugins);
  46. //cell(column) of indirect selection
  47. grid.rowSelectCell = null;
  48. //DnD plugin depends on NestedSorting plugin
  49. grid.dnd && (grid.nestedSorting = true);
  50. //"columnReordering" attribute won't work when either DnD or Indirect Selections plugin is used.
  51. (grid.dnd || grid.indirectSelection) && (grid.columnReordering = false);
  52. },
  53. preInit: function(){
  54. // summary:
  55. // Pre initialization, some plugins must be loaded before DataGrid.postCreate().
  56. // See EnhancedGrid.postCreate()
  57. var grid = this.grid;
  58. //load Indirect Selection plugin
  59. grid.indirectSelection && (new (this.getPluginClazz('dojox.grid.enhanced.plugins.IndirectSelection'))(grid));
  60. if(grid.dnd && (!grid.rowSelector || grid.rowSelector=="false")) {
  61. //RowSelector should be used for DnD plugin.
  62. grid.rowSelector = "20px";
  63. }
  64. //overwrite header and content builders
  65. if(grid.nestedSorting){
  66. dojox.grid._View.prototype._headerBuilderClass = dojox.grid.enhanced._HeaderBuilder;
  67. }
  68. dojox.grid._View.prototype._contentBuilderClass = dojox.grid.enhanced._ContentBuilder;
  69. },
  70. postInit: function(){
  71. // summary:
  72. // Post initialization, by default, plugins are loaded after DataGrid.postCreate().
  73. // See EnhancedGrid.postCreate()
  74. var grid = this.grid;
  75. //overwrite some default events of DataGrid
  76. new dojox.grid.enhanced._Events(grid);
  77. //load Menu plugin
  78. grid.menus && (new (this.getPluginClazz('dojox.grid.enhanced.plugins.Menu'))(grid));
  79. //load NestedSorting plugin
  80. grid.nestedSorting && (new (this.getPluginClazz('dojox.grid.enhanced.plugins.NestedSorting'))(grid));
  81. //load DnD plugin
  82. if(grid.dnd){
  83. grid.isDndSelectEnable = grid.dnd;
  84. //by default disable cell selection for EnhancedGrid M1
  85. grid.dndDisabledTypes = ["cell"];
  86. //new dojox.grid.enhanced.dnd._DndMovingManager(grid);
  87. new (this.getPluginClazz('dojox.grid.enhanced.plugins.DnD'))(grid);
  88. }
  89. //TODO - see if any better ways for this
  90. //fix inherit issue for mixin, an null/undefined exception will be thrown from the "this.inherited(...)" in
  91. //the following functions, like saying there is no "startup" in "this" scope
  92. dojo.isChrome < 3 && (grid.constructor.prototype.startup = grid.startup);
  93. //grid.constructor.prototype.onStyleRow = grid.onStyleRow;
  94. //get fixed cell(column) number
  95. this.fixedCellNum = this.getFixedCellNumber();
  96. //overwrite some default methods of DataGrid by method caching
  97. this.grid.plugins && this._bindFuncs();
  98. },
  99. getPluginClazz: function(clazzStr){
  100. //summary:
  101. // Load target plugin which must be already required (dojo.require(..))
  102. //clazzStr: String
  103. // Plugin class name
  104. var clazz = dojo.getObject(clazzStr);
  105. if(clazz){
  106. return clazz;
  107. }
  108. throw new Error('Please make sure class "' + clazzStr + '" is required.');
  109. },
  110. isFixedCell: function(cell) {
  111. //summary:
  112. // See if target cell(column) is fixed or not.
  113. //cell: Object
  114. // Target cell(column)
  115. //return: Boolean
  116. // True - fixed| False - not fixed
  117. //target cell can use Boolean attributes named "isRowSelector" or "positionFixed" to mark it's a fixed cell(column)
  118. return cell && (cell.isRowSelector || cell.positionFixed);
  119. },
  120. getFixedCellNumber: function(){
  121. //summary:
  122. // See if target cell(column) is fixed or not.
  123. //return: Number
  124. // True - fixed| False - not fixed
  125. if(this.fixedCellNum >= 0){
  126. return this.fixedCellNum;
  127. }
  128. var i = 0;
  129. dojo.forEach(this.grid.layout.cells, dojo.hitch(this, function(cell){
  130. this.isFixedCell(cell) && (i++);
  131. }));
  132. return i;
  133. },
  134. inSingleSelection: function(){
  135. //summary:
  136. // See if Grid is in single selection mode
  137. //return: Boolean
  138. // True - in single selection mode | False - not in single selection mode
  139. return this.grid.selectionMode && this.grid.selectionMode == 'single';
  140. },
  141. needUpdateRow: function(){
  142. //summary:
  143. // See if needed to update row. See this.updateRow()
  144. //return: Boolean
  145. // True - need update row | False - don't update row
  146. //always true when either indirect selection or DnD disabled
  147. return ((this.grid.indirectSelection || this.grid.isDndSelectEnable) ? this.grid.edit.isEditing() : true);
  148. },
  149. _bindFuncs: function(){
  150. //summary:
  151. // Overwrite some default methods of DataGrid by method caching
  152. dojo.forEach(this.grid.views.views, dojo.hitch(this, function(view){
  153. //add more events handler - _View
  154. dojox.grid.util.funnelEvents(view.contentNode, view, "doContentEvent", ['mouseup', 'mousemove']);
  155. dojox.grid.util.funnelEvents(view.headerNode, view, "doHeaderEvent", ['mouseup']);
  156. //overwrite _View.setColumnsWidth()
  157. this.funcMap[view.id + '-' +'setColumnsWidth'] = view.setColumnsWidth;
  158. view.setColumnsWidth = this.setColumnsWidth;
  159. //overwrite _View._getHeaderContent()
  160. this.grid.nestedSorting && (view._getHeaderContent = this.grid._getNestedSortHeaderContent);
  161. //overwrite _View.setScrollTop(),
  162. //#10273 fix of base DataGrid seems to bring some side effects to Enhanced Grid,
  163. //TODO - need a more close look post v.1.4 rather than simply overwrite it
  164. this.grid.dnd && (view.setScrollTop = this.setScrollTop);
  165. }));
  166. //overwrite _FocusManager.nextKey()
  167. this.funcMap['nextKey'] = this.grid.focus.nextKey;
  168. this.grid.focus.nextKey = this.nextKey;
  169. //overwrite _FocusManager.previousKey()
  170. this.funcMap['previousKey'] = this.grid.focus.previousKey;
  171. this.grid.focus.previousKey = this.previousKey;
  172. //overwrite _Scroller.renderPage()
  173. if(this.grid.indirectSelection){
  174. this.funcMap['renderPage'] = this.grid.scroller.renderPage;
  175. this.grid.scroller.renderPage = this.renderPage;
  176. this.funcMap['measurePage'] = this.grid.scroller.measurePage;
  177. this.grid.scroller.measurePage = this.measurePage;
  178. }
  179. //overwrite _Grid.updateRow()
  180. this.funcMap['updateRow'] = this.grid.updateRow;
  181. this.grid.updateRow = this.updateRow;
  182. if(this.grid.nestedSorting && dojox.grid.cells._Widget){
  183. dojox.grid.cells._Widget.prototype.sizeWidget = this.sizeWidget;
  184. }
  185. dojox.grid.cells._Base.prototype.getEditNode = this.getEditNode;
  186. dojox.grid._EditManager.prototype.styleRow = function(inRow){};
  187. },
  188. setColumnsWidth: function(width){
  189. //summary:
  190. // Overwrite _View.setColumnsWidth(), "this" - _View scope
  191. // Fix rtl issue in IE.
  192. if(dojo.isIE && !dojo._isBodyLtr()) {
  193. this.headerContentNode.style.width = width + 'px';
  194. this.headerContentNode.parentNode.style.width = width + 'px';
  195. }
  196. //invoke _View.setColumnsWidth()
  197. dojo.hitch(this, this.grid.pluginMgr.funcMap[this.id + '-' +'setColumnsWidth'])(width);
  198. },
  199. previousKey: function(e){
  200. //summary:
  201. // Overwrite _FocusManager.previousKey(), "this" - _FocusManager scope
  202. var isEditing = this.grid.edit.isEditing();
  203. if(!isEditing && !this.isNavHeader() && !this._isHeaderHidden()) {
  204. if(!this.grid.isDndSelectEnable){
  205. this.focusHeader();
  206. }else{
  207. if(!this.isRowBar()){
  208. this.focusRowBar();
  209. } else {
  210. this._blurRowBar();
  211. this.focusHeader();
  212. }
  213. }
  214. dojo.stopEvent(e);
  215. return;
  216. }
  217. //invoke _FocusManager.previousKey()
  218. dojo.hitch(this, this.grid.pluginMgr.funcMap['previousKey'])(e);
  219. },
  220. nextKey: function(e) {
  221. //summary:
  222. // Overwrite _FocusManager.nextKey(), "this" - _FocusManager scope
  223. var isEmpty = this.grid.rowCount == 0;
  224. var isRootEvt = (e.target === this.grid.domNode);
  225. if(!isRootEvt && this.grid.isDndSelectEnable && this.isNavHeader()){
  226. // if tabbing from col header, then go to grid proper. If grid is empty this.grid.rowCount == 0
  227. this._colHeadNode = this._colHeadFocusIdx= null;
  228. this.focusRowBar();
  229. return;
  230. }else if(!isRootEvt && (!this.grid.isDndSelectEnable && this.isNavHeader()) || (this.grid.isDndSelectEnable && this.isRowBar())){
  231. this._colHeadNode = this._colHeadFocusIdx= null;
  232. if (this.grid.isDndSelectEnable) {
  233. this._blurRowBar();
  234. }
  235. if(this.isNoFocusCell() && !isEmpty){
  236. this.setFocusIndex(0, 0);
  237. }else if(this.cell && !isEmpty){
  238. if(this.focusView && !this.focusView.rowNodes[this.rowIndex]){
  239. // if rowNode for current index is undefined (likely as a result of a sort and because of #7304)
  240. // scroll to that row
  241. this.grid.scrollToRow(this.rowIndex);
  242. }
  243. this.focusGrid();
  244. }else if(!this.findAndFocusGridCell()){
  245. this.tabOut(this.grid.lastFocusNode);
  246. }
  247. return;
  248. }
  249. //invoke _FocusManager.nextKey()
  250. dojo.hitch(this, this.grid.pluginMgr.funcMap['nextKey'])(e);
  251. },
  252. renderPage: function(inPageIndex){
  253. //summary:
  254. // Overwrite _Scroller.renderPage(), "this" - _Scroller scope
  255. // To add progress cursor when rendering the indirect selection cell(column) with checkbox
  256. for(var i=0, j=inPageIndex*this.rowsPerPage; (i<this.rowsPerPage)&&(j<this.rowCount); i++, j++){}
  257. this.grid.lastRenderingRowIdx = --j;
  258. dojo.addClass(this.grid.domNode, 'dojoxGridSortInProgress');
  259. //invoke _Scroller.renderPage()
  260. dojo.hitch(this, this.grid.pluginMgr.funcMap['renderPage'])(inPageIndex);
  261. },
  262. measurePage: function(inPageIndex){
  263. //summary:
  264. // Overwrite _Scroller.measurePage(), "this" - _Scroller scope
  265. // Fix a regression similar as #5552
  266. // invoke _Scroller.measurePage()
  267. var pageHeight = dojo.hitch(this, this.grid.pluginMgr.funcMap['measurePage'])(inPageIndex);
  268. return (!dojo.isIE || this.grid.rowHeight || pageHeight > this.rowsPerPage * this.grid.minRowHeight) ? pageHeight : undefined;
  269. },
  270. updateRow: function(inRowIndex){
  271. //summary:
  272. // Overwrite _Scroller.renderPage(), "this" - _Grid scope
  273. var caller = arguments.callee.caller;
  274. if(caller.nom == "move" && /* caller.ctor.prototype.declaredClass == "dojox.grid._FocusManager" && */ !this.pluginMgr.needUpdateRow()){
  275. //if is called from dojox.grid._FocusManager.move(), and no need to update row, then return
  276. return;
  277. }
  278. //invoke _Grid.updateRow()
  279. dojo.hitch(this, this.pluginMgr.funcMap['updateRow'])(inRowIndex);
  280. },
  281. getEditNode: function(inRowIndex) {
  282. //summary:
  283. // Overwrite dojox.grid.cells._Base.getEditNode, "this" - _Base scope
  284. return ((this.getNode(inRowIndex) || 0).firstChild || 0).firstChild || 0;
  285. },
  286. sizeWidget: function(inNode, inDatum, inRowIndex){
  287. //summary:
  288. // Overwrite dojox.grid.cells._Widget.sizeWidget, "this" - _Widget scope
  289. var p = this.getNode(inRowIndex).firstChild,
  290. box = dojo.contentBox(p);
  291. dojo.marginBox(this.widget.domNode, {w: box.w});
  292. },
  293. setScrollTop: function(inTop){
  294. //summary:
  295. // Overwrite dojox.grid._View.setScrollTop, "this" - _View scope
  296. this.lastTop = inTop;
  297. this.scrollboxNode.scrollTop = inTop;
  298. return this.scrollboxNode.scrollTop;
  299. },
  300. getViewByCellIdx: function(cellIdx){
  301. //summary:
  302. // Find view that contains the cell with 'cellIdx'
  303. //cellIdx: Integer
  304. // Index of target cell
  305. //return: Object
  306. // Matched view
  307. var cellMatched = function(cells){
  308. var j = 0, matched = false;
  309. for(; j < cells.length; j++){
  310. if(dojo.isArray(cells[j])){
  311. if(cellMatched(cells[j])){ return true;}
  312. }else if(cells[j].index == cellIdx){
  313. return true;
  314. }
  315. }
  316. };
  317. var i = 0, views = this.grid.views.views;
  318. for(; i < views.length; i++){
  319. cells = views[i].structure.cells;
  320. if(cellMatched(cells)){ return views[i]; }
  321. }
  322. return null;
  323. }
  324. });
  325. }