/ext-4.0.7/docs/source/Container2.html

https://bitbucket.org/srogerf/javascript · HTML · 916 lines · 813 code · 103 blank · 0 comment · 0 complexity · 0713f695e50d4f7f9819a43f9f33f8d3 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"><span id='Ext-grid-header-Container'>/**
  19. </span> * @class Ext.grid.header.Container
  20. * @extends Ext.container.Container
  21. *
  22. * Container which holds headers and is docked at the top or bottom of a TablePanel.
  23. * The HeaderContainer drives resizing/moving/hiding of columns within the TableView.
  24. * As headers are hidden, moved or resized the headercontainer is responsible for
  25. * triggering changes within the view.
  26. */
  27. Ext.define('Ext.grid.header.Container', {
  28. extend: 'Ext.container.Container',
  29. uses: [
  30. 'Ext.grid.ColumnLayout',
  31. 'Ext.grid.column.Column',
  32. 'Ext.menu.Menu',
  33. 'Ext.menu.CheckItem',
  34. 'Ext.menu.Separator',
  35. 'Ext.grid.plugin.HeaderResizer',
  36. 'Ext.grid.plugin.HeaderReorderer'
  37. ],
  38. border: true,
  39. alias: 'widget.headercontainer',
  40. baseCls: Ext.baseCSSPrefix + 'grid-header-ct',
  41. dock: 'top',
  42. <span id='Ext-grid-header-Container-cfg-weight'> /**
  43. </span> * @cfg {Number} weight
  44. * HeaderContainer overrides the default weight of 0 for all docked items to 100.
  45. * This is so that it has more priority over things like toolbars.
  46. */
  47. weight: 100,
  48. defaultType: 'gridcolumn',
  49. <span id='Ext-grid-header-Container-cfg-defaultWidth'> /**
  50. </span> * @cfg {Number} defaultWidth
  51. * Width of the header if no width or flex is specified. Defaults to 100.
  52. */
  53. defaultWidth: 100,
  54. sortAscText: 'Sort Ascending',
  55. sortDescText: 'Sort Descending',
  56. sortClearText: 'Clear Sort',
  57. columnsText: 'Columns',
  58. lastHeaderCls: Ext.baseCSSPrefix + 'column-header-last',
  59. firstHeaderCls: Ext.baseCSSPrefix + 'column-header-first',
  60. headerOpenCls: Ext.baseCSSPrefix + 'column-header-open',
  61. // private; will probably be removed by 4.0
  62. triStateSort: false,
  63. ddLock: false,
  64. dragging: false,
  65. <span id='Ext-grid-header-Container-property-isGroupHeader'> /**
  66. </span> * &lt;code&gt;true&lt;/code&gt; if this HeaderContainer is in fact a group header which contains sub headers.
  67. * @type Boolean
  68. * @property isGroupHeader
  69. */
  70. <span id='Ext-grid-header-Container-cfg-sortable'> /**
  71. </span> * @cfg {Boolean} sortable
  72. * Provides the default sortable state for all Headers within this HeaderContainer.
  73. * Also turns on or off the menus in the HeaderContainer. Note that the menu is
  74. * shared across every header and therefore turning it off will remove the menu
  75. * items for every header.
  76. */
  77. sortable: true,
  78. initComponent: function() {
  79. var me = this;
  80. me.headerCounter = 0;
  81. me.plugins = me.plugins || [];
  82. // TODO: Pass in configurations to turn on/off dynamic
  83. // resizing and disable resizing all together
  84. // Only set up a Resizer and Reorderer for the topmost HeaderContainer.
  85. // Nested Group Headers are themselves HeaderContainers
  86. if (!me.isHeader) {
  87. me.resizer = Ext.create('Ext.grid.plugin.HeaderResizer');
  88. me.reorderer = Ext.create('Ext.grid.plugin.HeaderReorderer');
  89. if (!me.enableColumnResize) {
  90. me.resizer.disable();
  91. }
  92. if (!me.enableColumnMove) {
  93. me.reorderer.disable();
  94. }
  95. me.plugins.push(me.reorderer, me.resizer);
  96. }
  97. // Base headers do not need a box layout
  98. if (me.isHeader &amp;&amp; !me.items) {
  99. me.layout = 'auto';
  100. }
  101. // HeaderContainer and Group header needs a gridcolumn layout.
  102. else {
  103. me.layout = {
  104. type: 'gridcolumn',
  105. availableSpaceOffset: me.availableSpaceOffset,
  106. align: 'stretchmax',
  107. resetStretch: true
  108. };
  109. }
  110. me.defaults = me.defaults || {};
  111. Ext.applyIf(me.defaults, {
  112. width: me.defaultWidth,
  113. triStateSort: me.triStateSort,
  114. sortable: me.sortable
  115. });
  116. me.callParent();
  117. me.addEvents(
  118. <span id='Ext-grid-header-Container-event-columnresize'> /**
  119. </span> * @event columnresize
  120. * @param {Ext.grid.header.Container} ct The grid's header Container which encapsulates all column headers.
  121. * @param {Ext.grid.column.Column} column The Column header Component which provides the column definition
  122. * @param {Number} width
  123. */
  124. 'columnresize',
  125. <span id='Ext-grid-header-Container-event-headerclick'> /**
  126. </span> * @event headerclick
  127. * @param {Ext.grid.header.Container} ct The grid's header Container which encapsulates all column headers.
  128. * @param {Ext.grid.column.Column} column The Column header Component which provides the column definition
  129. * @param {Ext.EventObject} e
  130. * @param {HTMLElement} t
  131. */
  132. 'headerclick',
  133. <span id='Ext-grid-header-Container-event-headertriggerclick'> /**
  134. </span> * @event headertriggerclick
  135. * @param {Ext.grid.header.Container} ct The grid's header Container which encapsulates all column headers.
  136. * @param {Ext.grid.column.Column} column The Column header Component which provides the column definition
  137. * @param {Ext.EventObject} e
  138. * @param {HTMLElement} t
  139. */
  140. 'headertriggerclick',
  141. <span id='Ext-grid-header-Container-event-columnmove'> /**
  142. </span> * @event columnmove
  143. * @param {Ext.grid.header.Container} ct The grid's header Container which encapsulates all column headers.
  144. * @param {Ext.grid.column.Column} column The Column header Component which provides the column definition
  145. * @param {Number} fromIdx
  146. * @param {Number} toIdx
  147. */
  148. 'columnmove',
  149. <span id='Ext-grid-header-Container-event-columnhide'> /**
  150. </span> * @event columnhide
  151. * @param {Ext.grid.header.Container} ct The grid's header Container which encapsulates all column headers.
  152. * @param {Ext.grid.column.Column} column The Column header Component which provides the column definition
  153. */
  154. 'columnhide',
  155. <span id='Ext-grid-header-Container-event-columnshow'> /**
  156. </span> * @event columnshow
  157. * @param {Ext.grid.header.Container} ct The grid's header Container which encapsulates all column headers.
  158. * @param {Ext.grid.column.Column} column The Column header Component which provides the column definition
  159. */
  160. 'columnshow',
  161. <span id='Ext-grid-header-Container-event-sortchange'> /**
  162. </span> * @event sortchange
  163. * @param {Ext.grid.header.Container} ct The grid's header Container which encapsulates all column headers.
  164. * @param {Ext.grid.column.Column} column The Column header Component which provides the column definition
  165. * @param {String} direction
  166. */
  167. 'sortchange',
  168. <span id='Ext-grid-header-Container-event-menucreate'> /**
  169. </span> * @event menucreate
  170. * Fired immediately after the column header menu is created.
  171. * @param {Ext.grid.header.Container} ct This instance
  172. * @param {Ext.menu.Menu} menu The Menu that was created
  173. */
  174. 'menucreate'
  175. );
  176. },
  177. onDestroy: function() {
  178. Ext.destroy(this.resizer, this.reorderer);
  179. this.callParent();
  180. },
  181. applyDefaults: function(config){
  182. /*
  183. * Ensure header.Container defaults don't get applied to a RowNumberer
  184. * if an xtype is supplied. This isn't an ideal solution however it's
  185. * much more likely that a RowNumberer with no options will be created,
  186. * wanting to use the defaults specified on the class as opposed to
  187. * those setup on the Container.
  188. */
  189. if (config &amp;&amp; !config.isComponent &amp;&amp; config.xtype == 'rownumberer') {
  190. return config;
  191. }
  192. return this.callParent([config]);
  193. },
  194. applyColumnsState: function(columns) {
  195. if (!columns || !columns.length) {
  196. return;
  197. }
  198. var me = this,
  199. i = 0,
  200. index,
  201. col;
  202. Ext.each(columns, function (columnState) {
  203. col = me.down('gridcolumn[headerId=' + columnState.id + ']');
  204. if (col) {
  205. index = me.items.indexOf(col);
  206. if (i !== index) {
  207. me.moveHeader(index, i);
  208. }
  209. if (col.applyColumnState) {
  210. col.applyColumnState(columnState);
  211. }
  212. ++i;
  213. }
  214. });
  215. },
  216. getColumnsState: function () {
  217. var me = this,
  218. columns = [],
  219. state;
  220. me.items.each(function (col) {
  221. state = col.getColumnState &amp;&amp; col.getColumnState();
  222. if (state) {
  223. columns.push(state);
  224. }
  225. });
  226. return columns;
  227. },
  228. // Invalidate column cache on add
  229. // We cannot refresh the View on every add because this method is called
  230. // when the HeaderDropZone moves Headers around, that will also refresh the view
  231. onAdd: function(c) {
  232. var me = this;
  233. if (!c.headerId) {
  234. c.headerId = c.initialConfig.id || ('h' + (++me.headerCounter));
  235. }
  236. //&lt;debug warn&gt;
  237. if (Ext.global.console &amp;&amp; Ext.global.console.warn) {
  238. if (!me._usedIDs) me._usedIDs = {};
  239. if (me._usedIDs[c.headerId]) {
  240. Ext.global.console.warn(this.$className, 'attempted to reuse an existing id', c.headerId);
  241. }
  242. me._usedIDs[c.headerId] = true;
  243. }
  244. //&lt;/debug&gt;
  245. me.callParent(arguments);
  246. me.purgeCache();
  247. },
  248. // Invalidate column cache on remove
  249. // We cannot refresh the View on every remove because this method is called
  250. // when the HeaderDropZone moves Headers around, that will also refresh the view
  251. onRemove: function(c) {
  252. var me = this;
  253. me.callParent(arguments);
  254. me.purgeCache();
  255. },
  256. afterRender: function() {
  257. this.callParent();
  258. var store = this.up('[store]').store,
  259. sorters = store.sorters,
  260. first = sorters.first(),
  261. hd;
  262. if (first) {
  263. hd = this.down('gridcolumn[dataIndex=' + first.property +']');
  264. if (hd) {
  265. hd.setSortState(first.direction, false, true);
  266. }
  267. }
  268. },
  269. afterLayout: function() {
  270. if (!this.isHeader) {
  271. var me = this,
  272. topHeaders = me.query('&gt;gridcolumn:not([hidden])'),
  273. viewEl,
  274. firstHeaderEl,
  275. lastHeaderEl;
  276. me.callParent(arguments);
  277. if (topHeaders.length) {
  278. firstHeaderEl = topHeaders[0].el;
  279. if (firstHeaderEl !== me.pastFirstHeaderEl) {
  280. if (me.pastFirstHeaderEl) {
  281. me.pastFirstHeaderEl.removeCls(me.firstHeaderCls);
  282. }
  283. firstHeaderEl.addCls(me.firstHeaderCls);
  284. me.pastFirstHeaderEl = firstHeaderEl;
  285. }
  286. lastHeaderEl = topHeaders[topHeaders.length - 1].el;
  287. if (lastHeaderEl !== me.pastLastHeaderEl) {
  288. if (me.pastLastHeaderEl) {
  289. me.pastLastHeaderEl.removeCls(me.lastHeaderCls);
  290. }
  291. lastHeaderEl.addCls(me.lastHeaderCls);
  292. me.pastLastHeaderEl = lastHeaderEl;
  293. }
  294. }
  295. }
  296. },
  297. onHeaderShow: function(header, preventLayout) {
  298. // Pass up to the GridSection
  299. var me = this,
  300. gridSection = me.ownerCt,
  301. menu = me.getMenu(),
  302. topItems, topItemsVisible,
  303. colCheckItem,
  304. itemToEnable,
  305. len, i;
  306. if (menu) {
  307. colCheckItem = menu.down('menucheckitem[headerId=' + header.id + ']');
  308. if (colCheckItem) {
  309. colCheckItem.setChecked(true, true);
  310. }
  311. // There's more than one header visible, and we've disabled some checked items... re-enable them
  312. topItems = menu.query('#columnItem&gt;menucheckitem[checked]');
  313. topItemsVisible = topItems.length;
  314. if ((me.getVisibleGridColumns().length &gt; 1) &amp;&amp; me.disabledMenuItems &amp;&amp; me.disabledMenuItems.length) {
  315. if (topItemsVisible == 1) {
  316. Ext.Array.remove(me.disabledMenuItems, topItems[0]);
  317. }
  318. for (i = 0, len = me.disabledMenuItems.length; i &lt; len; i++) {
  319. itemToEnable = me.disabledMenuItems[i];
  320. if (!itemToEnable.isDestroyed) {
  321. itemToEnable[itemToEnable.menu ? 'enableCheckChange' : 'enable']();
  322. }
  323. }
  324. if (topItemsVisible == 1) {
  325. me.disabledMenuItems = topItems;
  326. } else {
  327. me.disabledMenuItems = [];
  328. }
  329. }
  330. }
  331. // Only update the grid UI when we are notified about base level Header shows;
  332. // Group header shows just cause a layout of the HeaderContainer
  333. if (!header.isGroupHeader) {
  334. if (me.view) {
  335. me.view.onHeaderShow(me, header, true);
  336. }
  337. if (gridSection) {
  338. gridSection.onHeaderShow(me, header);
  339. }
  340. }
  341. me.fireEvent('columnshow', me, header);
  342. // The header's own hide suppresses cascading layouts, so lay the headers out now
  343. if (preventLayout !== true) {
  344. me.doLayout();
  345. }
  346. },
  347. doComponentLayout: function(){
  348. var me = this;
  349. if (me.view &amp;&amp; me.view.saveScrollState) {
  350. me.view.saveScrollState();
  351. }
  352. me.callParent(arguments);
  353. if (me.view &amp;&amp; me.view.restoreScrollState) {
  354. me.view.restoreScrollState();
  355. }
  356. },
  357. onHeaderHide: function(header, suppressLayout) {
  358. // Pass up to the GridSection
  359. var me = this,
  360. gridSection = me.ownerCt,
  361. menu = me.getMenu(),
  362. colCheckItem;
  363. if (menu) {
  364. // If the header was hidden programmatically, sync the Menu state
  365. colCheckItem = menu.down('menucheckitem[headerId=' + header.id + ']');
  366. if (colCheckItem) {
  367. colCheckItem.setChecked(false, true);
  368. }
  369. me.setDisabledItems();
  370. }
  371. // Only update the UI when we are notified about base level Header hides;
  372. if (!header.isGroupHeader) {
  373. if (me.view) {
  374. me.view.onHeaderHide(me, header, true);
  375. }
  376. if (gridSection) {
  377. gridSection.onHeaderHide(me, header);
  378. }
  379. // The header's own hide suppresses cascading layouts, so lay the headers out now
  380. if (!suppressLayout) {
  381. me.doLayout();
  382. }
  383. }
  384. me.fireEvent('columnhide', me, header);
  385. },
  386. setDisabledItems: function(){
  387. var me = this,
  388. menu = me.getMenu(),
  389. i = 0,
  390. len,
  391. itemsToDisable,
  392. itemToDisable;
  393. // Find what to disable. If only one top level item remaining checked, we have to disable stuff.
  394. itemsToDisable = menu.query('#columnItem&gt;menucheckitem[checked]');
  395. if ((itemsToDisable.length === 1)) {
  396. if (!me.disabledMenuItems) {
  397. me.disabledMenuItems = [];
  398. }
  399. // If down to only one column visible, also disable any descendant checkitems
  400. if ((me.getVisibleGridColumns().length === 1) &amp;&amp; itemsToDisable[0].menu) {
  401. itemsToDisable = itemsToDisable.concat(itemsToDisable[0].menu.query('menucheckitem[checked]'));
  402. }
  403. len = itemsToDisable.length;
  404. // Disable any further unchecking at any level.
  405. for (i = 0; i &lt; len; i++) {
  406. itemToDisable = itemsToDisable[i];
  407. if (!Ext.Array.contains(me.disabledMenuItems, itemToDisable)) {
  408. // If we only want to disable check change: it might be a disabled item, so enable it prior to
  409. // setting its correct disablement level.
  410. itemToDisable.disabled = false;
  411. itemToDisable[itemToDisable.menu ? 'disableCheckChange' : 'disable']();
  412. me.disabledMenuItems.push(itemToDisable);
  413. }
  414. }
  415. }
  416. },
  417. <span id='Ext-grid-header-Container-method-tempLock'> /**
  418. </span> * Temporarily lock the headerCt. This makes it so that clicking on headers
  419. * don't trigger actions like sorting or opening of the header menu. This is
  420. * done because extraneous events may be fired on the headers after interacting
  421. * with a drag drop operation.
  422. * @private
  423. */
  424. tempLock: function() {
  425. this.ddLock = true;
  426. Ext.Function.defer(function() {
  427. this.ddLock = false;
  428. }, 200, this);
  429. },
  430. onHeaderResize: function(header, w, suppressFocus) {
  431. this.tempLock();
  432. if (this.view &amp;&amp; this.view.rendered) {
  433. this.view.onHeaderResize(header, w, suppressFocus);
  434. }
  435. },
  436. onHeaderClick: function(header, e, t) {
  437. this.fireEvent(&quot;headerclick&quot;, this, header, e, t);
  438. },
  439. onHeaderTriggerClick: function(header, e, t) {
  440. // generate and cache menu, provide ability to cancel/etc
  441. if (this.fireEvent(&quot;headertriggerclick&quot;, this, header, e, t) !== false) {
  442. this.showMenuBy(t, header);
  443. }
  444. },
  445. showMenuBy: function(t, header) {
  446. var menu = this.getMenu(),
  447. ascItem = menu.down('#ascItem'),
  448. descItem = menu.down('#descItem'),
  449. sortableMth;
  450. menu.activeHeader = menu.ownerCt = header;
  451. menu.setFloatParent(header);
  452. // TODO: remove coupling to Header's titleContainer el
  453. header.titleContainer.addCls(this.headerOpenCls);
  454. // enable or disable asc &amp; desc menu items based on header being sortable
  455. sortableMth = header.sortable ? 'enable' : 'disable';
  456. if (ascItem) {
  457. ascItem[sortableMth]();
  458. }
  459. if (descItem) {
  460. descItem[sortableMth]();
  461. }
  462. menu.showBy(t);
  463. },
  464. // remove the trigger open class when the menu is hidden
  465. onMenuDeactivate: function() {
  466. var menu = this.getMenu();
  467. // TODO: remove coupling to Header's titleContainer el
  468. menu.activeHeader.titleContainer.removeCls(this.headerOpenCls);
  469. },
  470. moveHeader: function(fromIdx, toIdx) {
  471. // An automatically expiring lock
  472. this.tempLock();
  473. this.onHeaderMoved(this.move(fromIdx, toIdx), fromIdx, toIdx);
  474. },
  475. purgeCache: function() {
  476. var me = this;
  477. // Delete column cache - column order has changed.
  478. delete me.gridDataColumns;
  479. delete me.hideableColumns;
  480. // Menu changes when columns are moved. It will be recreated.
  481. if (me.menu) {
  482. me.menu.destroy();
  483. delete me.menu;
  484. }
  485. },
  486. onHeaderMoved: function(header, fromIdx, toIdx) {
  487. var me = this,
  488. gridSection = me.ownerCt;
  489. if (gridSection &amp;&amp; gridSection.onHeaderMove) {
  490. gridSection.onHeaderMove(me, header, fromIdx, toIdx);
  491. }
  492. me.fireEvent(&quot;columnmove&quot;, me, header, fromIdx, toIdx);
  493. },
  494. <span id='Ext-grid-header-Container-method-getMenu'> /**
  495. </span> * Gets the menu (and will create it if it doesn't already exist)
  496. * @private
  497. */
  498. getMenu: function() {
  499. var me = this;
  500. if (!me.menu) {
  501. me.menu = Ext.create('Ext.menu.Menu', {
  502. hideOnParentHide: false, // Persists when owning ColumnHeader is hidden
  503. items: me.getMenuItems(),
  504. listeners: {
  505. deactivate: me.onMenuDeactivate,
  506. scope: me
  507. }
  508. });
  509. me.setDisabledItems();
  510. me.fireEvent('menucreate', me, me.menu);
  511. }
  512. return me.menu;
  513. },
  514. <span id='Ext-grid-header-Container-method-getMenuItems'> /**
  515. </span> * Returns an array of menu items to be placed into the shared menu
  516. * across all headers in this header container.
  517. * @returns {Array} menuItems
  518. */
  519. getMenuItems: function() {
  520. var me = this,
  521. menuItems = [],
  522. hideableColumns = me.enableColumnHide ? me.getColumnMenu(me) : null;
  523. if (me.sortable) {
  524. menuItems = [{
  525. itemId: 'ascItem',
  526. text: me.sortAscText,
  527. cls: Ext.baseCSSPrefix + 'hmenu-sort-asc',
  528. handler: me.onSortAscClick,
  529. scope: me
  530. },{
  531. itemId: 'descItem',
  532. text: me.sortDescText,
  533. cls: Ext.baseCSSPrefix + 'hmenu-sort-desc',
  534. handler: me.onSortDescClick,
  535. scope: me
  536. }];
  537. }
  538. if (hideableColumns &amp;&amp; hideableColumns.length) {
  539. menuItems.push('-', {
  540. itemId: 'columnItem',
  541. text: me.columnsText,
  542. cls: Ext.baseCSSPrefix + 'cols-icon',
  543. menu: hideableColumns
  544. });
  545. }
  546. return menuItems;
  547. },
  548. // sort asc when clicking on item in menu
  549. onSortAscClick: function() {
  550. var menu = this.getMenu(),
  551. activeHeader = menu.activeHeader;
  552. activeHeader.setSortState('ASC');
  553. },
  554. // sort desc when clicking on item in menu
  555. onSortDescClick: function() {
  556. var menu = this.getMenu(),
  557. activeHeader = menu.activeHeader;
  558. activeHeader.setSortState('DESC');
  559. },
  560. <span id='Ext-grid-header-Container-method-getColumnMenu'> /**
  561. </span> * Returns an array of menu CheckItems corresponding to all immediate children of the passed Container which have been configured as hideable.
  562. */
  563. getColumnMenu: function(headerContainer) {
  564. var menuItems = [],
  565. i = 0,
  566. item,
  567. items = headerContainer.query('&gt;gridcolumn[hideable]'),
  568. itemsLn = items.length,
  569. menuItem;
  570. for (; i &lt; itemsLn; i++) {
  571. item = items[i];
  572. menuItem = Ext.create('Ext.menu.CheckItem', {
  573. text: item.text,
  574. checked: !item.hidden,
  575. hideOnClick: false,
  576. headerId: item.id,
  577. menu: item.isGroupHeader ? this.getColumnMenu(item) : undefined,
  578. checkHandler: this.onColumnCheckChange,
  579. scope: this
  580. });
  581. if (itemsLn === 1) {
  582. menuItem.disabled = true;
  583. }
  584. menuItems.push(menuItem);
  585. // If the header is ever destroyed - for instance by dragging out the last remaining sub header,
  586. // then the associated menu item must also be destroyed.
  587. item.on({
  588. destroy: Ext.Function.bind(menuItem.destroy, menuItem)
  589. });
  590. }
  591. return menuItems;
  592. },
  593. onColumnCheckChange: function(checkItem, checked) {
  594. var header = Ext.getCmp(checkItem.headerId);
  595. header[checked ? 'show' : 'hide']();
  596. },
  597. <span id='Ext-grid-header-Container-method-getColumnsForTpl'> /**
  598. </span> * Get the columns used for generating a template via TableChunker.
  599. * Returns an array of all columns and their
  600. * - dataIndex
  601. * - align
  602. * - width
  603. * - id
  604. * - columnId - used to create an identifying CSS class
  605. * - cls The tdCls configuration from the Column object
  606. * @private
  607. */
  608. getColumnsForTpl: function(flushCache) {
  609. var cols = [],
  610. headers = this.getGridColumns(flushCache),
  611. headersLn = headers.length,
  612. i = 0,
  613. header,
  614. width;
  615. for (; i &lt; headersLn; i++) {
  616. header = headers[i];
  617. if (header.hidden || header.up('headercontainer[hidden=true]')) {
  618. width = 0;
  619. } else {
  620. width = header.getDesiredWidth();
  621. // IE6 and IE7 bug.
  622. // Setting the width of the first TD does not work - ends up with a 1 pixel discrepancy.
  623. // We need to increment the passed with in this case.
  624. if ((i === 0) &amp;&amp; (Ext.isIE6 || Ext.isIE7)) {
  625. width += 1;
  626. }
  627. }
  628. cols.push({
  629. dataIndex: header.dataIndex,
  630. align: header.align,
  631. width: width,
  632. id: header.id,
  633. cls: header.tdCls,
  634. columnId: header.getItemId()
  635. });
  636. }
  637. return cols;
  638. },
  639. <span id='Ext-grid-header-Container-method-getColumnCount'> /**
  640. </span> * Returns the number of &lt;b&gt;grid columns&lt;/b&gt; descended from this HeaderContainer.
  641. * Group Columns are HeaderContainers. All grid columns are returned, including hidden ones.
  642. */
  643. getColumnCount: function() {
  644. return this.getGridColumns().length;
  645. },
  646. <span id='Ext-grid-header-Container-method-getFullWidth'> /**
  647. </span> * Gets the full width of all columns that are visible.
  648. */
  649. getFullWidth: function(flushCache) {
  650. var fullWidth = 0,
  651. headers = this.getVisibleGridColumns(flushCache),
  652. headersLn = headers.length,
  653. i = 0;
  654. for (; i &lt; headersLn; i++) {
  655. if (!isNaN(headers[i].width)) {
  656. // use headers getDesiredWidth if its there
  657. if (headers[i].getDesiredWidth) {
  658. fullWidth += headers[i].getDesiredWidth();
  659. // if injected a diff cmp use getWidth
  660. } else {
  661. fullWidth += headers[i].getWidth();
  662. }
  663. }
  664. }
  665. return fullWidth;
  666. },
  667. // invoked internally by a header when not using triStateSorting
  668. clearOtherSortStates: function(activeHeader) {
  669. var headers = this.getGridColumns(),
  670. headersLn = headers.length,
  671. i = 0,
  672. oldSortState;
  673. for (; i &lt; headersLn; i++) {
  674. if (headers[i] !== activeHeader) {
  675. oldSortState = headers[i].sortState;
  676. // unset the sortstate and dont recurse
  677. headers[i].setSortState(null, true);
  678. //if (!silent &amp;&amp; oldSortState !== null) {
  679. // this.fireEvent('sortchange', this, headers[i], null);
  680. //}
  681. }
  682. }
  683. },
  684. <span id='Ext-grid-header-Container-method-getVisibleGridColumns'> /**
  685. </span> * Returns an array of the &lt;b&gt;visible&lt;/b&gt; columns in the grid. This goes down to the lowest column header
  686. * level, and does not return &lt;i&gt;grouped&lt;/i&gt; headers which contain sub headers.
  687. * @param {Boolean} refreshCache If omitted, the cached set of columns will be returned. Pass true to refresh the cache.
  688. * @returns {Array}
  689. */
  690. getVisibleGridColumns: function(refreshCache) {
  691. return Ext.ComponentQuery.query(':not([hidden])', this.getGridColumns(refreshCache));
  692. },
  693. <span id='Ext-grid-header-Container-method-getGridColumns'> /**
  694. </span> * Returns an array of all columns which map to Store fields. This goes down to the lowest column header
  695. * level, and does not return &lt;i&gt;grouped&lt;/i&gt; headers which contain sub headers.
  696. * @param {Boolean} refreshCache If omitted, the cached set of columns will be returned. Pass true to refresh the cache.
  697. * @returns {Array}
  698. */
  699. getGridColumns: function(refreshCache) {
  700. var me = this,
  701. result = refreshCache ? null : me.gridDataColumns;
  702. // Not already got the column cache, so collect the base columns
  703. if (!result) {
  704. me.gridDataColumns = result = [];
  705. me.cascade(function(c) {
  706. if ((c !== me) &amp;&amp; !c.isGroupHeader) {
  707. result.push(c);
  708. }
  709. });
  710. }
  711. return result;
  712. },
  713. <span id='Ext-grid-header-Container-method-getHideableColumns'> /**
  714. </span> * @private
  715. * For use by column headers in determining whether there are any hideable columns when deciding whether or not
  716. * the header menu should be disabled.
  717. */
  718. getHideableColumns: function(refreshCache) {
  719. var me = this,
  720. result = refreshCache ? null : me.hideableColumns;
  721. if (!result) {
  722. result = me.hideableColumns = me.query('[hideable]');
  723. }
  724. return result;
  725. },
  726. <span id='Ext-grid-header-Container-method-getHeaderIndex'> /**
  727. </span> * Get the index of a leaf level header regardless of what the nesting
  728. * structure is.
  729. */
  730. getHeaderIndex: function(header) {
  731. var columns = this.getGridColumns();
  732. return Ext.Array.indexOf(columns, header);
  733. },
  734. <span id='Ext-grid-header-Container-method-getHeaderAtIndex'> /**
  735. </span> * Get a leaf level header by index regardless of what the nesting
  736. * structure is.
  737. */
  738. getHeaderAtIndex: function(index) {
  739. var columns = this.getGridColumns();
  740. return columns[index];
  741. },
  742. <span id='Ext-grid-header-Container-method-prepareData'> /**
  743. </span> * Maps the record data to base it on the header id's.
  744. * This correlates to the markup/template generated by
  745. * TableChunker.
  746. */
  747. prepareData: function(data, rowIdx, record, view, panel) {
  748. var obj = {},
  749. headers = this.gridDataColumns || this.getGridColumns(),
  750. headersLn = headers.length,
  751. colIdx = 0,
  752. header,
  753. headerId,
  754. renderer,
  755. value,
  756. metaData,
  757. store = panel.store;
  758. for (; colIdx &lt; headersLn; colIdx++) {
  759. metaData = {
  760. tdCls: '',
  761. style: ''
  762. };
  763. header = headers[colIdx];
  764. headerId = header.id;
  765. renderer = header.renderer;
  766. value = data[header.dataIndex];
  767. // When specifying a renderer as a string, it always resolves
  768. // to Ext.util.Format
  769. if (typeof renderer === &quot;string&quot;) {
  770. header.renderer = renderer = Ext.util.Format[renderer];
  771. }
  772. if (typeof renderer === &quot;function&quot;) {
  773. value = renderer.call(
  774. header.scope || this.ownerCt,
  775. value,
  776. // metadata per cell passing an obj by reference so that
  777. // it can be manipulated inside the renderer
  778. metaData,
  779. record,
  780. rowIdx,
  781. colIdx,
  782. store,
  783. view
  784. );
  785. }
  786. // &lt;debug&gt;
  787. if (metaData.css) {
  788. // This warning attribute is used by the compat layer
  789. obj.cssWarning = true;
  790. metaData.tdCls = metaData.css;
  791. delete metaData.css;
  792. }
  793. // &lt;/debug&gt;
  794. obj[headerId+'-modified'] = record.isModified(header.dataIndex) ? Ext.baseCSSPrefix + 'grid-dirty-cell' : '';
  795. obj[headerId+'-tdCls'] = metaData.tdCls;
  796. obj[headerId+'-tdAttr'] = metaData.tdAttr;
  797. obj[headerId+'-style'] = metaData.style;
  798. if (value === undefined || value === null || value === '') {
  799. value = '&amp;#160;';
  800. }
  801. obj[headerId] = value;
  802. }
  803. return obj;
  804. },
  805. expandToFit: function(header) {
  806. if (this.view) {
  807. this.view.expandToFit(header);
  808. }
  809. }
  810. });
  811. </pre>
  812. </body>
  813. </html>