123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>The source code</title>
- <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
- <style type="text/css">
- .highlight { display: block; background-color: #ddd; }
- </style>
- <script type="text/javascript">
- function highlight() {
- document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
- }
- </script>
- </head>
- <body onload="prettyPrint(); highlight();">
- <pre class="prettyprint lang-js"><span id='Ext-grid-feature-Grouping'>/**
- </span> * This feature allows to display the grid rows aggregated into groups as specified by the {@link Ext.data.Store#groupers}
- * specified on the Store. The group will show the title for the group name and then the appropriate records for the group
- * underneath. The groups can also be expanded and collapsed.
- *
- * ## Extra Events
- *
- * This feature adds several extra events that will be fired on the grid to interact with the groups:
- *
- * - {@link #groupclick}
- * - {@link #groupdblclick}
- * - {@link #groupcontextmenu}
- * - {@link #groupexpand}
- * - {@link #groupcollapse}
- *
- * ## Menu Augmentation
- *
- * This feature adds extra options to the grid column menu to provide the user with functionality to modify the grouping.
- * This can be disabled by setting the {@link #enableGroupingMenu} option. The option to disallow grouping from being turned off
- * by the user is {@link #enableNoGroups}.
- *
- * ## Controlling Group Text
- *
- * The {@link #groupHeaderTpl} is used to control the rendered title for each group. It can modified to customized
- * the default display.
- *
- * ## Example Usage
- *
- * @example
- * var store = Ext.create('Ext.data.Store', {
- * storeId:'employeeStore',
- * fields:['name', 'seniority', 'department'],
- * groupField: 'department',
- * data: {'employees':[
- * { "name": "Michael Scott", "seniority": 7, "department": "Management" },
- * { "name": "Dwight Schrute", "seniority": 2, "department": "Sales" },
- * { "name": "Jim Halpert", "seniority": 3, "department": "Sales" },
- * { "name": "Kevin Malone", "seniority": 4, "department": "Accounting" },
- * { "name": "Angela Martin", "seniority": 5, "department": "Accounting" }
- * ]},
- * proxy: {
- * type: 'memory',
- * reader: {
- * type: 'json',
- * root: 'employees'
- * }
- * }
- * });
- *
- * Ext.create('Ext.grid.Panel', {
- * title: 'Employees',
- * store: Ext.data.StoreManager.lookup('employeeStore'),
- * columns: [
- * { text: 'Name', dataIndex: 'name' },
- * { text: 'Seniority', dataIndex: 'seniority' }
- * ],
- * features: [{ftype:'grouping'}],
- * width: 200,
- * height: 275,
- * renderTo: Ext.getBody()
- * });
- *
- * **Note:** To use grouping with a grid that has {@link Ext.grid.column.Column#locked locked columns}, you need to supply
- * the grouping feature as a config object - so the grid can create two instances of the grouping feature.
- *
- * @author Nicolas Ferrero
- */
- Ext.define('Ext.grid.feature.Grouping', {
- extend: 'Ext.grid.feature.Feature',
- alias: 'feature.grouping',
- eventPrefix: 'group',
- eventSelector: '.' + Ext.baseCSSPrefix + 'grid-group-hd',
- bodySelector: '.' + Ext.baseCSSPrefix + 'grid-group-body',
- constructor: function() {
- var me = this;
- me.collapsedState = {};
- me.callParent(arguments);
- },
-
- <span id='Ext-grid-feature-Grouping-event-groupclick'> /**
- </span> * @event groupclick
- * @param {Ext.view.Table} view
- * @param {HTMLElement} node
- * @param {String} group The name of the group
- * @param {Ext.EventObject} e
- */
- <span id='Ext-grid-feature-Grouping-event-groupdblclick'> /**
- </span> * @event groupdblclick
- * @param {Ext.view.Table} view
- * @param {HTMLElement} node
- * @param {String} group The name of the group
- * @param {Ext.EventObject} e
- */
- <span id='Ext-grid-feature-Grouping-event-groupcontextmenu'> /**
- </span> * @event groupcontextmenu
- * @param {Ext.view.Table} view
- * @param {HTMLElement} node
- * @param {String} group The name of the group
- * @param {Ext.EventObject} e
- */
- <span id='Ext-grid-feature-Grouping-event-groupcollapse'> /**
- </span> * @event groupcollapse
- * @param {Ext.view.Table} view
- * @param {HTMLElement} node
- * @param {String} group The name of the group
- */
- <span id='Ext-grid-feature-Grouping-event-groupexpand'> /**
- </span> * @event groupexpand
- * @param {Ext.view.Table} view
- * @param {HTMLElement} node
- * @param {String} group The name of the group
- */
- <span id='Ext-grid-feature-Grouping-cfg-groupHeaderTpl'> /**
- </span> * @cfg {String/Array/Ext.Template} groupHeaderTpl
- * A string Template snippet, an array of strings (optionally followed by an object containing Template methods) to be used to construct a Template, or a Template instance.
- *
- * - Example 1 (Template snippet):
- *
- * groupHeaderTpl: 'Group: {name}'
- *
- * - Example 2 (Array):
- *
- * groupHeaderTpl: [
- * 'Group: ',
- * '<div>{name:this.formatName}</div>',
- * {
- * formatName: function(name) {
- * return Ext.String.trim(name);
- * }
- * }
- * ]
- *
- * - Example 3 (Template Instance):
- *
- * groupHeaderTpl: Ext.create('Ext.XTemplate',
- * 'Group: ',
- * '<div>{name:this.formatName}</div>',
- * {
- * formatName: function(name) {
- * return Ext.String.trim(name);
- * }
- * }
- * )
- *
- * @cfg {String} groupHeaderTpl.groupField The field name being grouped by.
- * @cfg {String} groupHeaderTpl.columnName The column header associated with the field being grouped by *if there is a column for the field*, falls back to the groupField name.
- * @cfg {Mixed} groupHeaderTpl.groupValue The value of the {@link Ext.data.Store#groupField groupField} for the group header being rendered.
- * @cfg {String} groupHeaderTpl.renderedGroupValue The rendered value of the {@link Ext.data.Store#groupField groupField} for the group header being rendered, as produced by the column renderer.
- * @cfg {String} groupHeaderTpl.name An alias for renderedGroupValue
- * @cfg {Object[]} groupHeaderTpl.rows An array of child row data objects as returned by the View's {@link Ext.view.AbstractView#prepareData prepareData} method.
- * @cfg {Ext.data.Model[]} groupHeaderTpl.children An array containing the child records for the group being rendered.
- */
- groupHeaderTpl: '{columnName}: {name}',
-
- <span id='Ext-grid-feature-Grouping-cfg-depthToIndent'> /**
- </span> * @cfg {Number} [depthToIndent=17]
- * Number of pixels to indent per grouping level
- */
- depthToIndent: 17,
- collapsedCls: Ext.baseCSSPrefix + 'grid-group-collapsed',
- hdCollapsedCls: Ext.baseCSSPrefix + 'grid-group-hd-collapsed',
- hdCollapsibleCls: Ext.baseCSSPrefix + 'grid-group-hd-collapsible',
- //<locale>
- <span id='Ext-grid-feature-Grouping-cfg-groupByText'> /**
- </span> * @cfg {String} [groupByText="Group by this field"]
- * Text displayed in the grid header menu for grouping by header.
- */
- groupByText : 'Group by this field',
- //</locale>
- //<locale>
- <span id='Ext-grid-feature-Grouping-cfg-showGroupsText'> /**
- </span> * @cfg {String} [showGroupsText="Show in groups"]
- * Text displayed in the grid header for enabling/disabling grouping.
- */
- showGroupsText : 'Show in groups',
- //</locale>
- <span id='Ext-grid-feature-Grouping-cfg-hideGroupedHeader'> /**
- </span> * @cfg {Boolean} [hideGroupedHeader=false]
- * True to hide the header that is currently grouped.
- */
- hideGroupedHeader : false,
- <span id='Ext-grid-feature-Grouping-cfg-startCollapsed'> /**
- </span> * @cfg {Boolean} [startCollapsed=false]
- * True to start all groups collapsed.
- */
- startCollapsed : false,
- <span id='Ext-grid-feature-Grouping-cfg-enableGroupingMenu'> /**
- </span> * @cfg {Boolean} [enableGroupingMenu=true]
- * True to enable the grouping control in the header menu.
- */
- enableGroupingMenu : true,
- <span id='Ext-grid-feature-Grouping-cfg-enableNoGroups'> /**
- </span> * @cfg {Boolean} [enableNoGroups=true]
- * True to allow the user to turn off grouping.
- */
- enableNoGroups : true,
- <span id='Ext-grid-feature-Grouping-cfg-collapsible'> /**
- </span> * @cfg {Boolean} [collapsible=true]
- * Set to `falsee` to disable collapsing groups from the UI.
- *
- * This is set to `false` when the associated {@link Ext.data.Store store} is
- * {@link Ext.data.Store#buffered buffered}.
- */
- collapsible: true,
- enable: function() {
- var me = this,
- view = me.view,
- store = view.store,
- groupToggleMenuItem;
- me.lastGroupField = me.getGroupField();
- if (me.lastGroupIndex) {
- me.block();
- store.group(me.lastGroupIndex);
- me.unblock();
- }
- me.callParent();
- groupToggleMenuItem = me.view.headerCt.getMenu().down('#groupToggleMenuItem');
- groupToggleMenuItem.setChecked(true, true);
- me.refreshIf();
- },
- disable: function() {
- var me = this,
- view = me.view,
- store = view.store,
- remote = store.remoteGroup,
- groupToggleMenuItem,
- lastGroup;
- lastGroup = store.groupers.first();
- if (lastGroup) {
- me.lastGroupIndex = lastGroup.property;
- me.block();
- store.clearGrouping();
- me.unblock();
- }
- me.callParent();
- groupToggleMenuItem = me.view.headerCt.getMenu().down('#groupToggleMenuItem');
- groupToggleMenuItem.setChecked(true, true);
- groupToggleMenuItem.setChecked(false, true);
- me.refreshIf();
- },
- refreshIf: function() {
- var ownerCt = this.grid.ownerCt,
- view = this.view;
-
- if (!view.store.remoteGroup && !this.blockRefresh) {
- // We are one side of a lockable grid, so refresh the locking view
- if (ownerCt && ownerCt.lockable) {
- ownerCt.view.refresh();
- } else {
- view.refresh();
- }
- }
- },
- getFeatureTpl: function(values, parent, x, xcount) {
- return [
- '<tpl if="typeof rows !== \'undefined\'">',
- // group row tpl
- '<tr id="{groupHeaderId}" class="' + Ext.baseCSSPrefix + 'grid-group-hd {hdCollapsedCls} {collapsibleClass}"><td class="' + Ext.baseCSSPrefix + 'grid-cell" colspan="' + parent.columns.length + '" {[this.indentByDepth(values)]}><div class="' + Ext.baseCSSPrefix + 'grid-cell-inner"><div class="' + Ext.baseCSSPrefix + 'grid-group-title">{collapsed}{[this.renderGroupHeaderTpl(values, parent)]}</div></div></td></tr>',
- // this is the rowbody
- '<tr id="{groupBodyId}" class="' + Ext.baseCSSPrefix + 'grid-group-body {collapsedCls}"><td colspan="' + parent.columns.length + '">{[this.recurse(values)]}</td></tr>',
- '</tpl>'
- ].join('');
- },
- getFragmentTpl: function() {
- var me = this;
- return {
- indentByDepth: me.indentByDepth,
- depthToIndent: me.depthToIndent,
- renderGroupHeaderTpl: function(values, parent) {
- return Ext.XTemplate.getTpl(me, 'groupHeaderTpl').apply(values, parent);
- }
- };
- },
- indentByDepth: function(values) {
- return 'style="padding-left:'+ ((values.depth || 0) * this.depthToIndent) + 'px;"';
- },
- // Containers holding these components are responsible for
- // destroying them, we are just deleting references.
- destroy: function() {
- delete this.view;
- delete this.prunedHeader;
- },
- // perhaps rename to afterViewRender
- attachEvents: function() {
- var me = this,
- view = me.view;
- view.on({
- scope: me,
- groupclick: me.onGroupClick,
- rowfocus: me.onRowFocus
- });
- view.mon(view.store, {
- scope: me,
- groupchange: me.onGroupChange,
- remove: me.onRemove,
- add: me.onAdd,
- update: me.onUpdate
- });
- if (me.enableGroupingMenu) {
- me.injectGroupingMenu();
- }
- me.pruneGroupedHeader();
- me.lastGroupField = me.getGroupField();
- me.block();
- me.onGroupChange();
- me.unblock();
- },
- // If we add a new item that doesn't belong to a rendered group, refresh the view
- onAdd: function(store, records){
- var me = this,
- view = me.view,
- groupField = me.getGroupField(),
- i = 0,
- len = records.length,
- activeGroups,
- addedGroups,
- groups,
- needsRefresh,
- group;
- if (view.rendered) {
- addedGroups = {};
- activeGroups = {};
- for (; i < len; ++i) {
- group = records[i].get(groupField);
- if (addedGroups[group] === undefined) {
- addedGroups[group] = 0;
- }
- addedGroups[group] += 1;
- }
- groups = store.getGroups();
- for (i = 0, len = groups.length; i < len; ++i) {
- group = groups[i];
- activeGroups[group.name] = group.children.length;
- }
- for (group in addedGroups) {
- if (addedGroups[group] === activeGroups[group]) {
- needsRefresh = true;
- break;
- }
- }
-
- if (needsRefresh) {
- view.refresh();
- }
- }
- },
- onUpdate: function(store, record, type, changedFields){
- var view = this.view;
- if (view.rendered && !changedFields || Ext.Array.contains(changedFields, this.getGroupField())) {
- view.refresh();
- }
- },
- onRemove: function(store, record) {
- var me = this,
- groupField = me.getGroupField(),
- removedGroup = record.get(groupField),
- view = me.view;
- if (view.rendered) {
- // If that was the last one in the group, force a refresh
- if (store.findExact(groupField, removedGroup) === -1) {
- me.view.refresh();
- }
- }
- },
- injectGroupingMenu: function() {
- var me = this,
- headerCt = me.view.headerCt;
- headerCt.showMenuBy = me.showMenuBy;
- headerCt.getMenuItems = me.getMenuItems();
- },
- showMenuBy: function(t, header) {
- var menu = this.getMenu(),
- groupMenuItem = menu.down('#groupMenuItem'),
- groupableMth = header.groupable === false ? 'disable' : 'enable';
-
- groupMenuItem[groupableMth]();
- Ext.grid.header.Container.prototype.showMenuBy.apply(this, arguments);
- },
- getMenuItems: function() {
- var me = this,
- groupByText = me.groupByText,
- disabled = me.disabled || !me.getGroupField(),
- showGroupsText = me.showGroupsText,
- enableNoGroups = me.enableNoGroups,
- getMenuItems = me.view.headerCt.getMenuItems;
- // runs in the scope of headerCt
- return function() {
- // We cannot use the method from HeaderContainer's prototype here
- // because other plugins or features may already have injected an implementation
- var o = getMenuItems.call(this);
- o.push('-', {
- iconCls: Ext.baseCSSPrefix + 'group-by-icon',
- itemId: 'groupMenuItem',
- text: groupByText,
- handler: me.onGroupMenuItemClick,
- scope: me
- });
- if (enableNoGroups) {
- o.push({
- itemId: 'groupToggleMenuItem',
- text: showGroupsText,
- checked: !disabled,
- checkHandler: me.onGroupToggleMenuItemClick,
- scope: me
- });
- }
- return o;
- };
- },
- <span id='Ext-grid-feature-Grouping-method-onGroupMenuItemClick'> /**
- </span> * Group by the header the user has clicked on.
- * @private
- */
- onGroupMenuItemClick: function(menuItem, e) {
- var me = this,
- menu = menuItem.parentMenu,
- hdr = menu.activeHeader,
- view = me.view,
- store = view.store;
- delete me.lastGroupIndex;
- me.block();
- me.enable();
- store.group(hdr.dataIndex);
- me.pruneGroupedHeader();
- me.unblock();
- me.refreshIf();
- },
- block: function(){
- this.blockRefresh = this.view.blockRefresh = true;
- },
- unblock: function(){
- this.blockRefresh = this.view.blockRefresh = false;
- },
- <span id='Ext-grid-feature-Grouping-method-onGroupToggleMenuItemClick'> /**
- </span> * Turn on and off grouping via the menu
- * @private
- */
- onGroupToggleMenuItemClick: function(menuItem, checked) {
- this[checked ? 'enable' : 'disable']();
- },
- <span id='Ext-grid-feature-Grouping-method-pruneGroupedHeader'> /**
- </span> * Prunes the grouped header from the header container
- * @private
- */
- pruneGroupedHeader: function() {
- var me = this,
- header = me.getGroupedHeader();
- if (me.hideGroupedHeader && header) {
- if (me.prunedHeader) {
- me.prunedHeader.show();
- }
- me.prunedHeader = header;
- header.hide();
- }
- },
- getGroupedHeader: function(){
- var groupField = this.getGroupField(),
- headerCt = this.view.headerCt;
- return groupField ? headerCt.down('[dataIndex=' + groupField + ']') : null;
- },
- getGroupField: function(){
- var group = this.view.store.groupers.first();
- if (group) {
- return group.property;
- }
- return '';
- },
- <span id='Ext-grid-feature-Grouping-method-onRowFocus'> /**
- </span> * When a row gains focus, expand the groups above it
- * @private
- */
- onRowFocus: function(rowIdx) {
- var node = this.view.getNode(rowIdx),
- groupBd = Ext.fly(node).up('.' + this.collapsedCls);
- if (groupBd) {
- // for multiple level groups, should expand every groupBd
- // above
- this.expand(groupBd);
- }
- },
- <span id='Ext-grid-feature-Grouping-method-isExpanded'> /**
- </span> * Returns `true` if the named group is expanded.
- * @param {String} groupName The group name as returned from {@link Ext.data.Store#getGroupString getGroupString}. This is usually the value of
- * the {@link Ext.data.Store#groupField groupField}.
- * @return {Boolean} `true` if the group defined by that value is expanded.
- */
- isExpanded: function(groupName) {
- return (this.collapsedState[groupName] === false);
- },
- <span id='Ext-grid-feature-Grouping-method-expand'> /**
- </span> * Expand a group
- * @param {String/Ext.Element} groupName The group name, or the element that contains the group body
- * @param {Boolean} focus Pass `true` to focus the group after expand.
- */
- expand: function(groupName, focus, /*private*/ preventSizeCalculation) {
- var me = this,
- view = me.view,
- groupHeader,
- groupBody,
- lockingPartner = me.lockingPartner;
- // We've been passed the group name
- if (Ext.isString(groupName)) {
- groupBody = Ext.fly(me.getGroupBodyId(groupName), '_grouping');
- }
- // We've been passed an element
- else {
- groupBody = Ext.fly(groupName, '_grouping')
- groupName = me.getGroupName(groupBody);
- }
- groupHeader = Ext.get(me.getGroupHeaderId(groupName));
- // If we are collapsed...
- if (me.collapsedState[groupName]) {
- groupBody.removeCls(me.collapsedCls);
- groupBody.prev().removeCls(me.hdCollapsedCls);
- if (preventSizeCalculation !== true) {
- view.refreshSize();
- }
- view.fireEvent('groupexpand', view, groupHeader, groupName);
- me.collapsedState[groupName] = false;
- // If we are one side of a locking view, the other side has to stay in sync
- if (lockingPartner) {
- lockingPartner.expand(groupName, focus, preventSizeCalculation);
- }
- if (focus) {
- groupBody.scrollIntoView(view.el, null, true);
- }
- }
- },
- <span id='Ext-grid-feature-Grouping-method-expandAll'> /**
- </span> * Expand all groups
- */
- expandAll: function(){
- var me = this,
- view = me.view,
- els = view.el.select(me.eventSelector).elements,
- e,
- eLen = els.length;
- for (e = 0; e < eLen; e++) {
- me.expand(Ext.fly(els[e]).next(), false, true);
- }
- view.refreshSize();
- },
- <span id='Ext-grid-feature-Grouping-method-collapse'> /**
- </span> * Collapse a group
- * @param {String/Ext.Element} groupName The group name, or the element that contains group body
- * @param {Boolean} focus Pass `true` to focus the group after expand.
- */
- collapse: function(groupName, focus, /*private*/ preventSizeCalculation) {
- var me = this,
- view = me.view,
- groupHeader,
- groupBody,
- lockingPartner = me.lockingPartner;
- // We've been passed the group name
- if (Ext.isString(groupName)) {
- groupBody = Ext.fly(me.getGroupBodyId(groupName), '_grouping');
- }
- // We've been passed an element
- else {
- groupBody = Ext.fly(groupName, '_grouping')
- groupName = me.getGroupName(groupBody);
- }
- groupHeader = Ext.get(me.getGroupHeaderId(groupName));
-
- // If we are not collapsed...
- if (!me.collapsedState[groupName]) {
- groupBody.addCls(me.collapsedCls);
- groupBody.prev().addCls(me.hdCollapsedCls);
- if (preventSizeCalculation !== true) {
- view.refreshSize();
- }
- view.fireEvent('groupcollapse', view, groupHeader, groupName);
- me.collapsedState[groupName] = true;
- // If we are one side of a locking view, the other side has to stay in sync
- if (lockingPartner) {
- lockingPartner.collapse(groupName, focus, preventSizeCalculation);
- }
- if (focus) {
- groupHeader.scrollIntoView(view.el, null, true);
- }
- }
- },
- <span id='Ext-grid-feature-Grouping-method-collapseAll'> /**
- </span> * Collapse all groups
- */
- collapseAll: function() {
- var me = this,
- view = me.view,
- els = view.el.select(me.eventSelector).elements,
- e,
- eLen = els.length;
- for (e = 0; e < eLen; e++) {
- me.collapse(Ext.fly(els[e]).next(), false, true);
- }
- view.refreshSize();
- },
- onGroupChange: function(){
- var me = this,
- field = me.getGroupField(),
- menuItem,
- visibleGridColumns,
- groupingByLastVisibleColumn;
- if (me.hideGroupedHeader) {
- if (me.lastGroupField) {
- menuItem = me.getMenuItem(me.lastGroupField);
- if (menuItem) {
- menuItem.setChecked(true);
- }
- }
- if (field) {
- visibleGridColumns = me.view.headerCt.getVisibleGridColumns();
- // See if we are being asked to group by the sole remaining visible column.
- // If so, then do not hide that column.
- groupingByLastVisibleColumn = ((visibleGridColumns.length === 1) && (visibleGridColumns[0].dataIndex == field));
- menuItem = me.getMenuItem(field);
- if (menuItem && !groupingByLastVisibleColumn) {
- menuItem.setChecked(false);
- }
- }
- }
- me.refreshIf();
- me.lastGroupField = field;
- },
- <span id='Ext-grid-feature-Grouping-method-getMenuItem'> /**
- </span> * Gets the related menu item for a dataIndex
- * @private
- * @return {Ext.grid.header.Container} The header
- */
- getMenuItem: function(dataIndex){
- var view = this.view,
- header = view.headerCt.down('gridcolumn[dataIndex=' + dataIndex + ']'),
- menu = view.headerCt.getMenu();
- return header ? menu.down('menuitem[headerId='+ header.id +']') : null;
- },
- <span id='Ext-grid-feature-Grouping-method-onGroupClick'> /**
- </span> * Toggle between expanded/collapsed state when clicking on
- * the group.
- * @private
- */
- onGroupClick: function(view, rowElement, groupName, e) {
- var me = this;
- if (me.collapsible) {
- if (me.collapsedState[groupName]) {
- me.expand(groupName);
- } else {
- me.collapse(groupName);
- }
- }
- },
- // Injects isRow and closeRow into the metaRowTpl.
- getMetaRowTplFragments: function() {
- return {
- isRow: this.isRow,
- closeRow: this.closeRow
- };
- },
- // injected into rowtpl and wrapped around metaRowTpl
- // becomes part of the standard tpl
- isRow: function() {
- return '<tpl if="typeof rows === \'undefined\'">';
- },
- // injected into rowtpl and wrapped around metaRowTpl
- // becomes part of the standard tpl
- closeRow: function() {
- return '</tpl>';
- },
- // isRow and closeRow are injected via getMetaRowTplFragments
- mutateMetaRowTpl: function(metaRowTpl) {
- metaRowTpl.unshift('{[this.isRow()]}');
- metaRowTpl.push('{[this.closeRow()]}');
- },
- // injects an additional style attribute via tdAttrKey with the proper
- // amount of padding
- getAdditionalData: function(data, idx, record, orig) {
- var view = this.view,
- hCt = view.headerCt,
- col = hCt.items.getAt(0),
- o = {},
- tdAttrKey;
- // If there *are* any columne in this grid (possible empty side of a locking grid)...
- // Add the padding-left style to indent the row according to grouping depth.
- // Preserve any current tdAttr that a user may have set.
- if (col) {
- tdAttrKey = col.id + '-tdAttr';
- o[tdAttrKey] = this.indentByDepth(data) + " " + (orig[tdAttrKey] ? orig[tdAttrKey] : '');
- o.collapsed = 'true';
- o.data = record.getData();
- }
- return o;
- },
- // return matching preppedRecords
- getGroupRows: function(group, records, preppedRecords, fullWidth) {
- var me = this,
- children = group.children,
- rows = group.rows = [],
- view = me.view,
- header = me.getGroupedHeader(),
- groupField = me.getGroupField(),
- index = -1,
- r,
- rLen = records.length,
- record;
-
- // Buffered rendering implies that user collapsing is disabled.
- if (view.store.buffered) {
- me.collapsible = false;
- }
-
- group.viewId = view.id;
- for (r = 0; r < rLen; r++) {
- record = records[r];
- if (record.get(groupField) == group.name) {
- index = r;
- }
- if (Ext.Array.indexOf(children, record) != -1) {
- rows.push(Ext.apply(preppedRecords[r], {
- depth : 1
- }));
- }
- }
- group.groupField = groupField,
- group.groupHeaderId = me.getGroupHeaderId(group.name);
- group.groupBodyId = me.getGroupBodyId(group.name);
- group.fullWidth = fullWidth;
- group.columnName = header ? header.text : groupField;
- group.groupValue = group.name;
- // Here we attempt to overwrite the group name value from the Store with
- // the get the rendered value of the column from the *prepped* record
- if (header && index > -1) {
- group.name = group.renderedValue = preppedRecords[index][header.id];
- }
- if (me.collapsedState[group.name]) {
- group.collapsedCls = me.collapsedCls;
- group.hdCollapsedCls = me.hdCollapsedCls;
- } else {
- group.collapsedCls = group.hdCollapsedCls = '';
- }
- // Collapsibility of groups may be disabled.
- if (me.collapsible) {
- group.collapsibleClass = me.hdCollapsibleCls;
- } else {
- group.collapsibleClass = '';
- }
- return group;
- },
- // Create an associated DOM id for the group's header element given the group name
- getGroupHeaderId: function(groupName) {
- return this.view.id + '-hd-' + groupName;
- },
- // Create an associated DOM id for the group's body element given the group name
- getGroupBodyId: function(groupName) {
- return this.view.id + '-bd-' + groupName;
- },
- // Get the group name from an associated element whether it's within a header or a body
- getGroupName: function(element) {
- var me = this,
- targetEl;
-
- // See if element is, or is within a group header. If so, we can extract its name
- targetEl = Ext.fly(element).findParent(me.eventSelector);
- if (targetEl) {
- return targetEl.id.split(this.view.id + '-hd-')[1];
- }
- // See if element is, or is within a group body. If so, we can extract its name
- targetEl = Ext.fly(element).findParent(me.bodySelector);
- if (targetEl) {
- return targetEl.id.split(this.view.id + '-bd-')[1];
- }
- },
- // return the data in a grouped format.
- collectData: function(records, preppedRecords, startIndex, fullWidth, o) {
- var me = this,
- store = me.view.store,
- collapsedState = me.collapsedState,
- collapseGroups,
- g,
- groups, gLen, group;
- if (me.startCollapsed) {
- // If we start collapse, we'll set the state of the groups here
- // and unset the flag so any subsequent expand/collapse is
- // managed by the feature
- me.startCollapsed = false;
- collapseGroups = true;
- }
- if (!me.disabled && store.isGrouped()) {
- o.rows = groups = store.getGroups();
- gLen = groups.length;
- for (g = 0; g < gLen; g++) {
- group = groups[g];
-
- if (collapseGroups) {
- collapsedState[group.name] = true;
- }
- me.getGroupRows(group, records, preppedRecords, fullWidth);
- }
- }
- return o;
- },
- // adds the groupName to the groupclick, groupdblclick, groupcontextmenu
- // events that are fired on the view. Chose not to return the actual
- // group itself because of its expense and because developers can simply
- // grab the group via store.getGroups(groupName)
- getFireEventArgs: function(type, view, targetEl, e) {
- return [type, view, targetEl, this.getGroupName(targetEl), e];
- }
- });
- </pre>
- </body>
- </html>
|