Summary.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. Ext.define('Ext.overrides.grid.feature.Summary', {
  2. override: 'Ext.grid.feature.Summary',
  3. // override
  4. fixed: undefined,
  5. fixedSummaryCls: Ext.baseCSSPrefix + 'fixed-summary',
  6. init: function (grid) {
  7. var me = this,
  8. view = me.view,
  9. dock = me.dock,
  10. fixed = me.fixed;
  11. // when 'fixed' is true, 'dock' must be a defined value, default 'bottom'
  12. if(fixed) {
  13. dock = me.dock = dock || 'bottom';
  14. }
  15. me.callParent([grid]);
  16. if (dock) {
  17. grid.addBodyCls(me.panelBodyCls + dock);
  18. grid.headerCt.on({
  19. add: me.onStoreUpdate,
  20. // we need to fire onStoreUpdate afterlayout for docked items
  21. // to re-run the renderSummaryRow on show/hide columns.
  22. afterlayout: me.onStoreUpdate,
  23. remove: me.onStoreUpdate,
  24. scope: me
  25. });
  26. grid.on({
  27. beforerender: function () {
  28. var tableCls = [me.summaryTableCls];
  29. if (view.columnLines) {
  30. tableCls[tableCls.length] = view.ownerCt.colLinesCls;
  31. }
  32. me.summaryBar = grid.addDocked({
  33. childEls: ['innerCt', 'item'],
  34. renderTpl: [
  35. '<div id="{id}-innerCt" data-ref="innerCt" role="presentation">',
  36. '<table id="{id}-item" data-ref="item" cellPadding="0" cellSpacing="0" class="' + tableCls.join(' ') + '">',
  37. '<tr class="' + me.summaryRowCls + '"></tr>',
  38. '</table>',
  39. '</div>'
  40. ],
  41. scrollable: {
  42. x: false,
  43. y: false
  44. },
  45. hidden: !me.showSummaryRow,
  46. itemId: 'summaryBar',
  47. cls: [me.dockedSummaryCls, me.dockedSummaryCls + '-' + dock, (fixed ? me.fixedSummaryCls : '')],
  48. xtype: 'component',
  49. dock: dock,
  50. weight: 10000000
  51. })[0];
  52. },
  53. afterrender: function () {
  54. grid.getView().getScrollable().addPartner(me.summaryBar.getScrollable(), 'x');
  55. me.onStoreUpdate();
  56. me.columnSizer = me.summaryBar.el;
  57. },
  58. single: true
  59. });
  60. } else {
  61. if (grid.bufferedRenderer) {
  62. me.wrapsItem = true;
  63. view.addRowTpl(me.fullSummaryTpl).summaryFeature = me;
  64. view.on('refresh', me.onViewRefresh, me);
  65. } else {
  66. me.wrapsItem = false;
  67. me.view.addFooterFn(me.renderSummaryRow);
  68. }
  69. }
  70. grid.headerCt.on({
  71. afterlayout: me.afterHeaderCtLayout,
  72. scope: me
  73. });
  74. grid.ownerGrid.on({
  75. beforereconfigure: me.onBeforeReconfigure,
  76. columnmove: me.onStoreUpdate,
  77. scope: me
  78. });
  79. me.bindStore(grid, grid.getStore());
  80. },
  81. bindStore: function(grid, store) {
  82. var me = this;
  83. Ext.destroy(me.storeListeners);
  84. me.storeListeners = store.on({
  85. scope: me,
  86. destroyable: true,
  87. update: me.onStoreUpdate,
  88. datachanged: me.onStoreUpdate
  89. });
  90. if(me.remoteRoot) {
  91. store.on({
  92. scope: me,
  93. beforeload: me.onStoreBeforeLoad
  94. });
  95. }
  96. me.callParent([grid, store]);
  97. },
  98. onStoreBeforeLoad: function(store, operation, eOpts) {
  99. var me = this,
  100. view = me.view,
  101. columns = view.getVisibleColumnManager().getColumns(),
  102. params = {},
  103. summaryFields = [];
  104. for(var i = 0; i < columns.length; i++) {
  105. var c = columns[i];
  106. if(c.summaryType) {
  107. summaryFields.push({
  108. property: c.dataIndex,
  109. type: c.summaryType
  110. });
  111. }
  112. }
  113. if(summaryFields.length > 0) {
  114. params.summary = JSON.stringify(summaryFields);
  115. }
  116. Ext.apply(store.proxy.extraParams, params);
  117. },
  118. onStoreUpdate: function () {
  119. var me = this,
  120. view = me.view,
  121. selector = me.summaryRowSelector,
  122. dock = me.dock,
  123. fixed = me.fixed,
  124. record, newRowDom, oldRowDom, newCellDoms, p;
  125. if (!view.rendered) {
  126. return;
  127. }
  128. record = me.createSummaryRecord(view);
  129. newRowDom = Ext.fly(view.createRowElement(record, -1)).down(selector, true);
  130. if (!newRowDom) {
  131. return;
  132. }
  133. if(fixed) {
  134. newCellDoms = newRowDom.children;
  135. for(let i = newCellDoms.length - 1; i >= 0 ; i--) {
  136. let innerText = newCellDoms[i].innerText.trim();
  137. if(innerText.length === 0) {
  138. newRowDom.removeChild(newCellDoms[i])
  139. }else {
  140. newCellDoms[i].style.removeProperty('width');
  141. }
  142. }
  143. }
  144. // Summary row is inside the docked summaryBar Component
  145. if (dock) {
  146. p = me.summaryBar.item.dom.firstChild;
  147. oldRowDom = p.firstChild;
  148. p.insertBefore(newRowDom, oldRowDom);
  149. p.removeChild(oldRowDom);
  150. }
  151. // Summary row is a regular row in a THEAD inside the View.
  152. // Downlinked through the summary record's ID
  153. else {
  154. oldRowDom = view.el.down(selector, true);
  155. p = oldRowDom && oldRowDom.parentNode;
  156. if (p) {
  157. p.removeChild(oldRowDom);
  158. }
  159. // We're always inserting the new summary row into the last rendered row,
  160. // unless no rows exist. In that case we will be appending to the special
  161. // placeholder in the node container.
  162. p = view.getRow(view.all.last());
  163. if (p) {
  164. p = p.parentElement;
  165. }
  166. // View might not have nodeContainer yet.
  167. else {
  168. p = me.getSummaryRowPlaceholder(view);
  169. p = p && p.tBodies && p.tBodies[0];
  170. }
  171. if (p) {
  172. p.appendChild(newRowDom);
  173. }
  174. }
  175. },
  176. // Synchronize column widths in the docked summary Component or the inline summary row
  177. // depending on whether we are docked or not.
  178. afterHeaderCtLayout: function (headerCt) {
  179. var me = this,
  180. view = me.view,
  181. columns = view.getVisibleColumnManager().getColumns(),
  182. column,
  183. len = columns.length,
  184. i,
  185. summaryEl,
  186. el, width, innerCt;
  187. if (me.showSummaryRow && view.refreshCounter) {
  188. if(me.fixed) {
  189. return;
  190. }
  191. if (me.dock) {
  192. summaryEl = me.summaryBar.el;
  193. width = headerCt.getTableWidth();
  194. innerCt = me.summaryBar.innerCt;
  195. // Stretch the innerCt of the summary bar upon headerCt layout
  196. me.summaryBar.item.setWidth(width);
  197. // headerCt's tooNarrow flag is set by its layout if the columns overflow.
  198. // Must not measure+set in after layout phase, this is a write phase.
  199. if (headerCt.tooNarrow) {
  200. width += Ext.getScrollbarSize().width;
  201. }
  202. innerCt.setWidth(width);
  203. } else {
  204. summaryEl = Ext.fly(Ext.fly(view.getNodeContainer()).down('.' + me.summaryItemCls, true));
  205. }
  206. // If the layout was in response to a clearView, there'll be no summary element
  207. if (summaryEl) {
  208. for (i = 0; i < len; i++) {
  209. column = columns[i];
  210. el = summaryEl.down(view.getCellSelector(column), true);
  211. if (el) {
  212. Ext.fly(el).setWidth(column.width || (column.lastBox ? column.lastBox.width : 100));
  213. }
  214. }
  215. }
  216. }
  217. },
  218. });