Ext version tested:
  • Ext 3.2.1

Adapter used:
  • ext

css used:
  • only default ext-all.css

Browser versions tested against:
  • Chromium 7
  • FF3 (firebug 1.3.0.10 installed)

Operating System:
  • Ubuntu 10.04

Description:
  • When using GroupSummary with hideGroupedColumn: true and after "show in groups" has been deselected, the next time you choose to group by a column, that column is hidden but no grouping takes place. You have to click "Group by this field" a second time to make it happen.

Test Case:

Code:
<html> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    <title>Custom Group Summary Plugin Example</title> 
 
    <!-- ** CSS ** --> 
    <!-- base library --> 
    <link rel="stylesheet" type="text/css" href="http://dev.sencha.com/deploy/dev/resources/css/ext-all.css" /> 
 
    <!-- overrides to base library --> 
    <link rel="stylesheet" type="text/css" href="http://dev.sencha.com/deploy/dev/examples/ux/css/GroupSummary.css" /> 
 
    <!-- page specific --> 
    <link rel="stylesheet" type="text/css" href="http://dev.sencha.com/deploy/dev/examples/shared/examples.css" /> 
    <link rel="stylesheet" type="text/css" href="http://dev.sencha.com/deploy/dev/examples/grid/grid-examples.css" /> 
 
    <style type="text/css"> 
        .x-grid3-cell-inner {
            font-family:"segoe ui",tahoma, arial, sans-serif;
        }
        .x-grid-group-hd div {
            font-family:"segoe ui",tahoma, arial, sans-serif;
        }
        .x-grid3-hd-inner {
            font-family:"segoe ui",tahoma, arial, sans-serif;
            font-size:12px;
        }
        .x-grid3-body .x-grid3-td-cost {
            background-color:#f1f2f4;
        }
        .x-grid3-summary-row .x-grid3-td-cost {
            background-color:#e1e2e4;
        }
        .icon-grid {
            background-image:url(http://dev.sencha.com/deploy/dev/examples/shared/icons/fam/grid.png) !important;
        }
        .x-grid3-dirty-cell {
            background-image:none;
        }
    </style> 
 
    <!-- ** Javascript ** --> 
    <!-- ExtJS library: base/adapter --> 
    <script type="text/javascript" src="http://dev.sencha.com/deploy/dev/adapter/ext/ext-base.js"></script> 
 
    <!-- ExtJS library: all widgets --> 
    <script type="text/javascript" src="http://dev.sencha.com/deploy/dev/ext-all.js"></script> 
 
    <!-- overrides to base library --> 
 
    <!-- extensions --> 
    <script type="text/javascript" src="http://dev.sencha.com/deploy/dev/examples/ux/GroupSummary.js"></script> 
 
    <!-- page specific --> 
    <script type="text/javascript">
/*!
 * Ext JS Library 3.2.1
 * Copyright(c) 2006-2010 Ext JS, Inc.
 * licensing@extjs.com
 * http://www.extjs.com/license
 */
Ext.onReady(function(){

    Ext.QuickTips.init();

    var xg = Ext.grid;

    var reader = new Ext.data.JsonReader({
        idProperty: 'taskId',
        fields: [
            {name: 'projectId', type: 'int'},
            {name: 'project', type: 'string'},
            {name: 'taskId', type: 'int'},
            {name: 'description', type: 'string'},
            {name: 'estimate', type: 'float'},
            {name: 'rate', type: 'float'},
            {name: 'cost', type: 'float'},
            {name: 'due', type: 'date', dateFormat:'m/d/Y'}
        ]

    });

    // define a custom summary function
    Ext.ux.grid.GroupSummary.Calculations['totalCost'] = function(v, record, field){
        return v + (record.data.estimate * record.data.rate);
    };

	// utilize custom extension for Group Summary
    var summary = new Ext.ux.grid.GroupSummary();

    var grid = new xg.EditorGridPanel({
        ds: new Ext.data.GroupingStore({
            reader: reader,
			// use local data
            data: app.grid.dummyData,
            sortInfo: {field: 'due', direction: 'ASC'},
            groupField: 'project'
        }),
        columns: [
            {
                id: 'description',
                header: 'Task',
                width: 80,
                sortable: true,
                dataIndex: 'description',
                summaryType: 'count',
                hideable: false,
                summaryRenderer: function(v, params, data){
                    return ((v === 0 || v > 1) ? '(' + v +' Tasks)' : '(1 Task)');
                },
                editor: new Ext.form.TextField({
                   allowBlank: false
                })
            },{
                header: 'Project',
                width: 20,
                sortable: true,
                dataIndex: 'project'
            },{
                header: 'Due Date',
                width: 25,
                sortable: true,
                dataIndex: 'due',
                summaryType: 'max',
                renderer: Ext.util.Format.dateRenderer('m/d/Y'),
                editor: new Ext.form.DateField({
                    format: 'm/d/Y'
                })
            },{
                header: 'Estimate',
                width: 20,
                sortable: true,
                dataIndex: 'estimate',
                summaryType: 'sum',
                renderer : function(v){
                    return v +' hours';
                },
                editor: new Ext.form.NumberField({
                   allowBlank: false,
                   allowNegative: false,
                   style: 'text-align:left'
                })
            },{
                header: 'Rate',
                width: 20,
                sortable: true,
                renderer: Ext.util.Format.usMoney,
                dataIndex: 'rate',
                summaryType: 'average',
                editor: new Ext.form.NumberField({
                    allowBlank: false,
                    allowNegative: false,
                    style: 'text-align:left'
                })
            },{
                id: 'cost',
                header: 'Cost',
                width: 20,
                sortable: false,
                groupable: false,
                renderer: function(v, params, record){
                    return Ext.util.Format.usMoney(record.data.estimate * record.data.rate);
                },
                dataIndex: 'cost',
                summaryType: 'totalCost',
                summaryRenderer: Ext.util.Format.usMoney
            }
        ],

        view: new Ext.grid.GroupingView({
            forceFit: true,
            showGroupName: false,
//            enableNoGroups: false,
//            enableGroupingMenu: false,
//TODO FIX: Bug in GroupSummary.doHidden: gs[i].childrenNodes[2] doesn't exist when no groups.
            hideGroupedColumn: true   // If you set this to false the bug goes away!!!
        }),

        plugins: summary,

        tbar : [{
            text: 'Toggle',
            tooltip: 'Toggle the visibility of summary row',
            handler: function(){summary.toggleSummaries();}
        }],

        frame: true,
        width: 800,
        height: 450,
        clicksToEdit: 1,
        collapsible: true,
        animCollapse: false,
        trackMouseOver: false,
        //enableColumnMove: false,
        title: 'Sponsored Projects',
        iconCls: 'icon-grid',
        renderTo: document.body
    });

});

// set up namespace for application
Ext.ns('app.grid');
// store dummy data in the app namespace
app.grid.dummyData = [
    {projectId: 100, project: 'Ext Forms: Field Anchoring', taskId: 112, description: 'Integrate 2.0 Forms with 2.0 Layouts', estimate: 6, rate: 150, due:'06/24/2007'},
    {projectId: 100, project: 'Ext Forms: Field Anchoring', taskId: 113, description: 'Implement AnchorLayout', estimate: 4, rate: 150, due:'06/25/2007'},
    {projectId: 100, project: 'Ext Forms: Field Anchoring', taskId: 114, description: 'Add support for multiple types of anchors', estimate: 4, rate: 150, due:'06/27/2007'},
    {projectId: 100, project: 'Ext Forms: Field Anchoring', taskId: 115, description: 'Testing and debugging', estimate: 8, rate: 0, due:'06/29/2007'},
    {projectId: 101, project: 'Ext Grid: Single-level Grouping', taskId: 101, description: 'Add required rendering "hooks" to GridView', estimate: 6, rate: 100, due:'07/01/2007'},
    {projectId: 101, project: 'Ext Grid: Single-level Grouping', taskId: 102, description: 'Extend GridView and override rendering functions', estimate: 6, rate: 100, due:'07/03/2007'},
    {projectId: 101, project: 'Ext Grid: Single-level Grouping', taskId: 103, description: 'Extend Store with grouping functionality', estimate: 4, rate: 100, due:'07/04/2007'},
    {projectId: 101, project: 'Ext Grid: Single-level Grouping', taskId: 121, description: 'Default CSS Styling', estimate: 2, rate: 100, due:'07/05/2007'},
    {projectId: 101, project: 'Ext Grid: Single-level Grouping', taskId: 104, description: 'Testing and debugging', estimate: 6, rate: 100, due:'07/06/2007'},
    {projectId: 102, project: 'Ext Grid: Summary Rows', taskId: 105, description: 'Ext Grid plugin integration', estimate: 4, rate: 125, due:'07/01/2007'},
    {projectId: 102, project: 'Ext Grid: Summary Rows', taskId: 106, description: 'Summary creation during rendering phase', estimate: 4, rate: 125, due:'07/02/2007'},
    {projectId: 102, project: 'Ext Grid: Summary Rows', taskId: 107, description: 'Dynamic summary updates in editor grids', estimate: 6, rate: 125, due:'07/05/2007'},
    {projectId: 102, project: 'Ext Grid: Summary Rows', taskId: 108, description: 'Remote summary integration', estimate: 4, rate: 125, due:'07/05/2007'},
    {projectId: 102, project: 'Ext Grid: Summary Rows', taskId: 109, description: 'Summary renderers and calculators', estimate: 4, rate: 125, due:'07/06/2007'},
    {projectId: 102, project: 'Ext Grid: Summary Rows', taskId: 110, description: 'Integrate summaries with GroupingView', estimate: 10, rate: 125, due:'07/11/2007'},
    {projectId: 102, project: 'Ext Grid: Summary Rows', taskId: 111, description: 'Testing and debugging', estimate: 8, rate: 125, due:'07/15/2007'}
];
    </script> 
 
</head> 
<body> 
    <h1>Custom Group Summary Plugin Example</h1> 
    <p>Demonstrates the custom <a href="http://dev.sencha.com/deploy/dev/examples/ux/GroupSummary.js">Ext.ux.grid.GroupSummary</a> class.</p> 
    <p>Note that the js is not minified so it is readable. See <a href="grouping/totals.js">totals.js</a>.</p> 
</body> 
</html>
Steps to reproduce the problem:
  • Execute code above.
  • Untick "Show in groups" in any header menu.
  • Click "Group by this field" in any header menu.

The result that was expected:
  • Groups are displayed.

The result that occurs instead:
  • Column is hidden, no groups displayed, menu doesn't go away.
  • Click "Group by this field" a second time to get the desired result.

Debugging already done:
  • A lot.

Possible fix:
  • The bug is in GroupSummary, in the method doHidden (line 185): gs[i].childrenNodes[2] doesn't exist when no groups.
  • gs is an array with all the rows in the table.
  • I guess childrenNodes[2] is supposed to be the row element to be shrunk/stretched when a column is displayed/hidden
  • The worst part is that this process doesn't seem to be necessary since it's already done in GridView.updateColumnHidden (which triggers that doHidden method). And when the grid is already grouped, switching the grouping to another column or disabling groups works perfectly, because in that case gs is empty and so the last portion of the method is skipped without errors.
  • After debugging it a little bit more, this error appears also in the method GroupSummary.doAllWidths. So maybe the problem is in the getGroups() method, and probably because these two methods (doHidden and doAllWidths) are called before 'something else' that should have been executed already.