/ext-4.1.0_b3/docs/source/RowExpander.html

https://bitbucket.org/srogerf/javascript · HTML · 250 lines · 220 code · 30 blank · 0 comment · 0 complexity · bdcc43cb14efa6c8b4da1bddfc7974dd MD5 · raw file

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>The source code</title>
  6. <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  7. <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  8. <style type="text/css">
  9. .highlight { display: block; background-color: #ddd; }
  10. </style>
  11. <script type="text/javascript">
  12. function highlight() {
  13. document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
  14. }
  15. </script>
  16. </head>
  17. <body onload="prettyPrint(); highlight();">
  18. <pre class="prettyprint lang-js">// feature idea to enable Ajax loading and then the content
  19. // cache would actually make sense. Should we dictate that they use
  20. // data or support raw html as well?
  21. <span id='Ext-ux-RowExpander'>/**
  22. </span> * @class Ext.ux.RowExpander
  23. * @extends Ext.AbstractPlugin
  24. * Plugin (ptype = 'rowexpander') that adds the ability to have a Column in a grid which enables
  25. * a second row body which expands/contracts. The expand/contract behavior is configurable to react
  26. * on clicking of the column, double click of the row, and/or hitting enter while a row is selected.
  27. *
  28. * @ptype rowexpander
  29. */
  30. Ext.define('Ext.ux.RowExpander', {
  31. extend: 'Ext.AbstractPlugin',
  32. requires: [
  33. 'Ext.grid.feature.RowBody',
  34. 'Ext.grid.feature.RowWrap'
  35. ],
  36. alias: 'plugin.rowexpander',
  37. rowBodyTpl: null,
  38. <span id='Ext-ux-RowExpander-cfg-expandOnEnter'> /**
  39. </span> * @cfg {Boolean} expandOnEnter
  40. * &lt;tt&gt;true&lt;/tt&gt; to toggle selected row(s) between expanded/collapsed when the enter
  41. * key is pressed (defaults to &lt;tt&gt;true&lt;/tt&gt;).
  42. */
  43. expandOnEnter: true,
  44. <span id='Ext-ux-RowExpander-cfg-expandOnDblClick'> /**
  45. </span> * @cfg {Boolean} expandOnDblClick
  46. * &lt;tt&gt;true&lt;/tt&gt; to toggle a row between expanded/collapsed when double clicked
  47. * (defaults to &lt;tt&gt;true&lt;/tt&gt;).
  48. */
  49. expandOnDblClick: true,
  50. <span id='Ext-ux-RowExpander-cfg-selectRowOnExpand'> /**
  51. </span> * @cfg {Boolean} selectRowOnExpand
  52. * &lt;tt&gt;true&lt;/tt&gt; to select a row when clicking on the expander icon
  53. * (defaults to &lt;tt&gt;false&lt;/tt&gt;).
  54. */
  55. selectRowOnExpand: false,
  56. rowBodyTrSelector: '.x-grid-rowbody-tr',
  57. rowBodyHiddenCls: 'x-grid-row-body-hidden',
  58. rowCollapsedCls: 'x-grid-row-collapsed',
  59. renderer: function(value, metadata, record, rowIdx, colIdx) {
  60. if (colIdx === 0) {
  61. metadata.tdCls = 'x-grid-td-expander';
  62. }
  63. return '&lt;div class=&quot;x-grid-row-expander&quot;&gt;&amp;#160;&lt;/div&gt;';
  64. },
  65. <span id='Ext-ux-RowExpander-event-expandbody'> /**
  66. </span> * @event expandbody
  67. * &lt;b&lt;Fired through the grid's View&lt;/b&gt;
  68. * @param {HTMLElement} rowNode The &amp;lt;tr&gt; element which owns the expanded row.
  69. * @param {Ext.data.Model} record The record providing the data.
  70. * @param {HTMLElement} expandRow The &amp;lt;tr&gt; element containing the expanded data.
  71. */
  72. <span id='Ext-ux-RowExpander-event-collapsebody'> /**
  73. </span> * @event collapsebody
  74. * &lt;b&lt;Fired through the grid's View.&lt;/b&gt;
  75. * @param {HTMLElement} rowNode The &amp;lt;tr&gt; element which owns the expanded row.
  76. * @param {Ext.data.Model} record The record providing the data.
  77. * @param {HTMLElement} expandRow The &amp;lt;tr&gt; element containing the expanded data.
  78. */
  79. constructor: function() {
  80. this.callParent(arguments);
  81. var grid = this.getCmp();
  82. this.recordsExpanded = {};
  83. // &lt;debug&gt;
  84. if (!this.rowBodyTpl) {
  85. Ext.Error.raise(&quot;The 'rowBodyTpl' config is required and is not defined.&quot;);
  86. }
  87. // &lt;/debug&gt;
  88. // TODO: if XTemplate/Template receives a template as an arg, should
  89. // just return it back!
  90. var rowBodyTpl = Ext.create('Ext.XTemplate', this.rowBodyTpl),
  91. features = [{
  92. ftype: 'rowbody',
  93. columnId: this.getHeaderId(),
  94. recordsExpanded: this.recordsExpanded,
  95. rowBodyHiddenCls: this.rowBodyHiddenCls,
  96. rowCollapsedCls: this.rowCollapsedCls,
  97. getAdditionalData: this.getRowBodyFeatureData,
  98. getRowBodyContents: function(data) {
  99. return rowBodyTpl.applyTemplate(data);
  100. }
  101. },{
  102. ftype: 'rowwrap'
  103. }];
  104. if (grid.features) {
  105. grid.features = features.concat(grid.features);
  106. } else {
  107. grid.features = features;
  108. }
  109. // NOTE: features have to be added before init (before Table.initComponent)
  110. },
  111. init: function(grid) {
  112. this.callParent(arguments);
  113. // Columns have to be added in init (after columns has been used to create the
  114. // headerCt). Otherwise, shared column configs get corrupted, e.g., if put in the
  115. // prototype.
  116. grid.headerCt.insert(0, this.getHeaderConfig());
  117. grid.on('render', this.bindView, this, {single: true});
  118. },
  119. getHeaderId: function() {
  120. if (!this.headerId) {
  121. this.headerId = Ext.id();
  122. }
  123. return this.headerId;
  124. },
  125. getRowBodyFeatureData: function(data, idx, record, orig) {
  126. var o = Ext.grid.feature.RowBody.prototype.getAdditionalData.apply(this, arguments),
  127. id = this.columnId;
  128. o.rowBodyColspan = o.rowBodyColspan - 1;
  129. o.rowBody = this.getRowBodyContents(data);
  130. o.rowCls = this.recordsExpanded[record.internalId] ? '' : this.rowCollapsedCls;
  131. o.rowBodyCls = this.recordsExpanded[record.internalId] ? '' : this.rowBodyHiddenCls;
  132. o[id + '-tdAttr'] = ' valign=&quot;top&quot; rowspan=&quot;2&quot; ';
  133. if (orig[id+'-tdAttr']) {
  134. o[id+'-tdAttr'] += orig[id+'-tdAttr'];
  135. }
  136. return o;
  137. },
  138. bindView: function() {
  139. var view = this.getCmp().getView(),
  140. viewEl;
  141. if (!view.rendered) {
  142. view.on('render', this.bindView, this, {single: true});
  143. } else {
  144. viewEl = view.getEl();
  145. if (this.expandOnEnter) {
  146. this.keyNav = Ext.create('Ext.KeyNav', viewEl, {
  147. 'enter' : this.onEnter,
  148. scope: this
  149. });
  150. }
  151. if (this.expandOnDblClick) {
  152. view.on('itemdblclick', this.onDblClick, this);
  153. }
  154. this.view = view;
  155. }
  156. },
  157. onEnter: function(e) {
  158. var view = this.view,
  159. ds = view.store,
  160. sm = view.getSelectionModel(),
  161. sels = sm.getSelection(),
  162. ln = sels.length,
  163. i = 0,
  164. rowIdx;
  165. for (; i &lt; ln; i++) {
  166. rowIdx = ds.indexOf(sels[i]);
  167. this.toggleRow(rowIdx);
  168. }
  169. },
  170. toggleRow: function(rowIdx) {
  171. var rowNode = this.view.getNode(rowIdx),
  172. row = Ext.get(rowNode),
  173. nextBd = Ext.get(row).down(this.rowBodyTrSelector),
  174. record = this.view.getRecord(rowNode),
  175. grid = this.getCmp();
  176. if (row.hasCls(this.rowCollapsedCls)) {
  177. row.removeCls(this.rowCollapsedCls);
  178. nextBd.removeCls(this.rowBodyHiddenCls);
  179. this.recordsExpanded[record.internalId] = true;
  180. this.view.fireEvent('expandbody', rowNode, record, nextBd.dom);
  181. } else {
  182. row.addCls(this.rowCollapsedCls);
  183. nextBd.addCls(this.rowBodyHiddenCls);
  184. this.recordsExpanded[record.internalId] = false;
  185. this.view.fireEvent('collapsebody', rowNode, record, nextBd.dom);
  186. }
  187. },
  188. onDblClick: function(view, cell, rowIdx, cellIndex, e) {
  189. this.toggleRow(rowIdx);
  190. },
  191. getHeaderConfig: function() {
  192. var me = this,
  193. toggleRow = Ext.Function.bind(me.toggleRow, me),
  194. selectRowOnExpand = me.selectRowOnExpand;
  195. return {
  196. id: this.getHeaderId(),
  197. width: 24,
  198. sortable: false,
  199. resizable: false,
  200. draggable: false,
  201. hideable: false,
  202. menuDisabled: true,
  203. cls: Ext.baseCSSPrefix + 'grid-header-special',
  204. renderer: function(value, metadata) {
  205. metadata.tdCls = Ext.baseCSSPrefix + 'grid-cell-special';
  206. return '&lt;div class=&quot;' + Ext.baseCSSPrefix + 'grid-row-expander&quot;&gt;&amp;#160;&lt;/div&gt;';
  207. },
  208. processEvent: function(type, view, cell, recordIndex, cellIndex, e) {
  209. if (type == &quot;mousedown&quot; &amp;&amp; e.getTarget('.x-grid-row-expander')) {
  210. var row = e.getTarget('.x-grid-row');
  211. toggleRow(row);
  212. return selectRowOnExpand;
  213. }
  214. }
  215. };
  216. }
  217. });
  218. </pre>
  219. </body>
  220. </html>