[FIXED] [#740] [3.2.0] Grid Group: Show/Hide column that is grouped

  1. #1

    [FIXED] [#740] [3.2.0] Grid Group: Show/Hide column that is grouped

    In the grid feature ext:Grouping there is an attribute HideGroupedHeader that will hide or show the column that is being grouped. I would like to control this based on certain columns. The reason why is that when I group a date column I group it my Month and Year, so it is still important to show this column when being grouped, but not the other columns.

    Reading the Sencha docs there should be a GroupChange event on the grid that I think would help do the trick, but it is not available. It this an oversight?

    Any other suggestions?

    See the related threads:



    <%@ Page Language="C#" %>
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!X.IsAjaxRequest)
            {
                DateTime today = DateTime.Today;
                DateTime later = DateTime.Today.AddMonths(1);
    
                Store store = this.GridPanel1.GetStore();
                store.DataSource = new object[] 
                { 
                    new object[] { today.AddHours(1), "1", "1" },
                    new object[] { today.AddHours(2), "11", "11" },
                    new object[] { today.AddHours(3), "111", "111" },
                    new object[] { later.AddHours(1), "2", "2" },
                    new object[] { later.AddHours(2), "22", "22" },
                    new object[] { later.AddHours(3), "222", "222" }
                };
            }
        }
    </script>
    
    <!DOCTYPE html>
    
    <html>
    <head runat="server">
        <title>Ext.NET v2 Example</title>
    
        <script>
            var getGroupString = function getGroupString(rec) {
                return Ext.Date.format(rec.get('datetime'), 'F Y');
            };
    
            var group = function (groupers, direction) {
                var grouper;
    
                if (Ext.isString(groupers) && (groupers === "datetime")) {
                    grouper = this.groupers.get(groupers);
    
                    if (!grouper) { // If it is not currently grouped by the datetime field
                        groupers = {
                            direction: "DESC",
                            property: "datetime",
                            getGroupString: getGroupString
                        }
                    }
                }
    
                Ext.data.Store.prototype.group.apply(this, [groupers, direction]);
            };
        </script>
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
    
            <ext:GridPanel ID="GridPanel1" runat="server">
                <Store>
                    <ext:Store runat="server">
                        <Model>
                            <ext:Model runat="server">
                                <Fields>
                                    <ext:ModelField Name="datetime" Type="Date" />
                                    <ext:ModelField Name="test1" />
                                    <ext:ModelField Name="test2" />
                                </Fields>
                            </ext:Model>
                        </Model>
                        <Groupers>
                            <ext:DataSorter Property="datetime" Direction="DESC">
                                <CustomConfig>
                                    <ext:ConfigItem Name="getGroupString" Value="getGroupString" Mode="Raw" />
                                </CustomConfig>
                            </ext:DataSorter>
                        </Groupers>
                        <CustomConfig>
                            <ext:ConfigItem Name="group" Value="group" Mode="Raw" />
                        </CustomConfig>
                    </ext:Store>
                </Store>
                <ColumnModel runat="server">
                    <Columns>
                        <ext:DateColumn runat="server" Text="DateTime" DataIndex="datetime" Format="yyyy-MM-dd hh:mm" />
                        <ext:Column runat="server" Text="Test1" DataIndex="test1" />
                        <ext:Column runat="server" Text="Test2" DataIndex="test2" />
                    </Columns>
                </ColumnModel>
                <Features>
                    <ext:Grouping runat="server" HideGroupedHeader="true" />
                </Features>
            </ext:GridPanel>
        </form>
    </body>
    </html>
    Last edited by cwolcott; Mar 02, 2015 at 11:32 PM.
  2. #2
    Hi Chris,

    Thank you for the report! Yes, it is in the ExtJS 4 docs, but it appears to be not fired in ExtJS 4.2.1, at least.

    So, with Ext.NET v2 please use a Store's GroupChange event.

    As for Ext.NET v3, both - Store's and GridPanel's - GroupChange events fire.

    Created an Issue for v3 - GridPanel misses the GroupChange event.

    Added in the revision 6393. It goes to 3.2.0.
  3. #3
    Trying to work through this to meet my requirement. The sample above has 3 columns (datetime, test1 and test2) [My application has 10 columns]. What I would like is when I group on the datetime column the column should still be shown in the list, but if test1 or test2 is grouped the associated column should be hidden.

    The attribute HideGroupedHeader on ext:Grouping is strictly a true/false and thus the group column is either hidden or not. I was hoping that the GroupChange event on Grid would allow me to catch the change and decide to not hide a certain column.

    My first attempt was to set HideGroupedHeader="true" and catch the GroupChange via the store listener (since v2 doesn't fire or support the GroupChange on the grid). I can test the groupers.items[0].property == "datetime" and tell the column to show(), but I believe that after I do this the code is continuing and hiding the column because of the HideGroupedHeader="true".

    So any hints/solutions that you can think of?
  4. #4
    Personally, I would attempt to override a Grouping's pruneGroupedHeader method.

    Here is the original code that you might try to adjust.
    Ext.grid.feature.Grouping.override({
        pruneGroupedHeader: function() {
            var me = this,
                header = me.getGroupedHeader();
    
            if (me.hideGroupedHeader && header) {
                Ext.suspendLayouts();
                if (me.prunedHeader && me.prunedHeader !== header) {
                    me.prunedHeader.show();
                }
                me.prunedHeader = header;
                header.hide();
                Ext.resumeLayouts(true);
            }
        }
    });
  5. #5
    Thanks for the suggestion. I added an attribute showWhenGrouped="true" on the column and checked for it within the pruneGroupedHeader. This worked great when I changed the column that is being grouped, but it did not stop the column from being hidden on the initial display.

    I looked elsewhere in the Ext.grid.feature.Grouping code and could only find one other reference to hideGroupedHeader in onGroupChange. The method is executed during initialization and when this line is called menuItem.setChecked(false) it will eventually cause the initial column to be hidden (because if I comment out the line the column is not hidden).

    Do you have any guidance on where else I can look to add a check to not hide the column during setup?
    Last edited by cwolcott; Mar 09, 2015 at 2:15 AM.
  6. #6
    Could you, please, provide an updated test case and steps to reproduce the issue with it?
  7. #7
    Initially when the GridPanel is displayed it is grouped by the datetime column, and the datetime column is hidden. But if I group by the Test1 column and then regroup by the DateTime column the DateTime column stays showing because of the the overload to pruneGroupedHeader.

    I was trying to find a way that the DateTime column is shown initially even though it is grouped.

    I guess the easy way is to add:
       <Listeners>
          <AfterLayout Handler="#{DT}.show()" />
       </Listeners>
    <%@ Page Language="C#" %>
    
     You can close the thread unless there is a better suggestion.
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!X.IsAjaxRequest)
            {
                DateTime today = DateTime.Today;
                DateTime later = DateTime.Today.AddMonths(1);
    
                Store store = this.GridPanel1.GetStore();
                store.DataSource = new object[] 
                { 
                    new object[] { today.AddHours(1), "1", "1" },
                    new object[] { today.AddHours(2), "11", "11" },
                    new object[] { today.AddHours(3), "111", "111" },
                    new object[] { later.AddHours(1), "2", "2" },
                    new object[] { later.AddHours(2), "22", "22" },
                    new object[] { later.AddHours(3), "222", "222" }
                };
            }
        }
    </script>
    
    <!DOCTYPE html>
    
    <html>
    <head runat="server">
        <title>Ext.NET v2 Example</title>
    
        <script>
    
            Ext.grid.feature.Grouping.override({
                pruneGroupedHeader: function () {
                    var me = this,
                        header = me.getGroupedHeader();
    
                    if (me.hideGroupedHeader && header) {
                        Ext.suspendLayouts();
                        if (me.prunedHeader && me.prunedHeader !== header) {
                            me.prunedHeader.show();
                        }
                        me.prunedHeader = header;
                        if (!header.showWhenGrouped) header.hide();
                        Ext.resumeLayouts(true);
                    }
                }
            });
    
            var getGroupString = function getGroupString(rec) {
                return Ext.Date.format(rec.get('datetime'), 'F Y');
            };
    
            var group = function (groupers, direction) {
                var grouper;
    
                if (Ext.isString(groupers) && (groupers === "datetime")) {
                    grouper = this.groupers.get(groupers);
    
                    if (!grouper) { // If it is not currently grouped by the datetime field
                        groupers = {
                            direction: "DESC",
                            property: "datetime",
                            getGroupString: getGroupString
                        }
                    }
                }
    
                Ext.data.Store.prototype.group.apply(this, [groupers, direction]);
            };
        </script>
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
    
            <ext:GridPanel ID="GridPanel1" runat="server">
                <Store>
                    <ext:Store runat="server">
                        <Model>
                            <ext:Model runat="server">
                                <Fields>
                                    <ext:ModelField Name="datetime" Type="Date" />
                                    <ext:ModelField Name="test1" />
                                    <ext:ModelField Name="test2" />
                                </Fields>
                            </ext:Model>
                        </Model>
                        <Groupers>
                            <ext:DataSorter Property="datetime" Direction="DESC">
                                <CustomConfig>
                                    <ext:ConfigItem Name="getGroupString" Value="getGroupString" Mode="Raw" />
                                </CustomConfig>
                            </ext:DataSorter>
                        </Groupers>
                        <CustomConfig>
                            <ext:ConfigItem Name="group" Value="group" Mode="Raw" />
                        </CustomConfig>
                    </ext:Store>
                </Store>
                <ColumnModel runat="server">
                    <Columns>
                        <ext:DateColumn ID="DT" runat="server" Text="DateTime" DataIndex="datetime" Format="yyyy-MM-dd hh:mm" showWhenGrouped="true" />
                        <ext:Column runat="server" Text="Test1" DataIndex="test1" />
                        <ext:Column runat="server" Text="Test2" DataIndex="test2" />
                    </Columns>
                </ColumnModel>
                <Features>
                    <ext:Grouping runat="server" HideGroupedHeader="true" />
                </Features>
            </ext:GridPanel>
        </form>
    </body>
    </html>
    Last edited by cwolcott; Mar 09, 2015 at 10:08 PM.
  8. #8
    There is also onGroupChange that should be overridden. Also I did a couple of changes in pruneGroupedHeader override.
    Ext.grid.feature.Grouping.override({
        pruneGroupedHeader: function () {
            var me = this,
                header = me.getGroupedHeader();
    
            if (me.hideGroupedHeader && header) {
                Ext.suspendLayouts();
                if (me.prunedHeader && me.prunedHeader !== header) {
                    me.prunedHeader.show();
                }
    
                if (!header.showWhenGrouped) {
                    me.prunedHeader = header;
                    header.hide();
                } else {
                    delete me.prunedHeader;
                }
    
                Ext.resumeLayouts(true);
            }
        },
    
        onGroupChange: function () {
            var me = this,
                field = me.getGroupField(),
                menuItem,
                visibleGridColumns,
                groupingByLastVisibleColumn,
                groupedHeader = me.view.headerCt.child(Ext.String.format("[dataIndex={0}]", field));
    
            if (me.hideGroupedHeader && !groupedHeader.showWhenGrouped) { // the only addition
                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;
        }
    });

Similar Threads

  1. [CLOSED] Grid Group: Show full datetime but group by month day year
    By cwolcott in forum 2.x Legacy Premium Help
    Replies: 7
    Last Post: Feb 06, 2015, 1:29 PM
  2. Replies: 3
    Last Post: Jul 07, 2014, 5:16 AM
  3. Replies: 0
    Last Post: Feb 17, 2014, 5:19 AM
  4. Replies: 0
    Last Post: Mar 03, 2011, 1:08 PM
  5. [CLOSED] [1.0] GridPanel Group Command (Menu Type ) show/hide on demand
    By webclouder in forum 1.x Legacy Premium Help
    Replies: 1
    Last Post: Dec 10, 2010, 5:04 PM

Posting Permissions