[FIXED] [#1254] [3.2.1] Problem getting GridPanel selection count when grouping

  1. #1

    [FIXED] [#1254] [3.2.1] Problem getting GridPanel selection count when grouping

    I have a gridpanel that is grouped and has a CheckboxSelectionModel.
    I am finding that if I select all the records after collapsing all but one group the selection count is off by the number of collapsed groups:

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Xml" %>
    <%@ Import Namespace="System.Collections.Generic" %>
    <!DOCTYPE html>
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e) {
            this.Store1.DataSource = new List<Company>
            {
                 new Company("Section 1","3m Co", 71.72, 0.02, 0.03),
                 new Company("Section 1","Alcoa Inc", 29.01, 0.42, 1.47),
                 new Company("Section 1","Altria Group Inc", 83.81, 0.28, 0.34),
                 new Company("Section 1","American Express Company", 52.55, 0.01, 0.02),
                 new Company("Section 1","American International Group, Inc.", 64.13, 0.31, 0.49),
                 new Company("Section 1","AT&T Inc.", 31.61, -0.48, -1.54),
                 new Company("Section 1","Boeing Co.", 75.43, 0.53, 0.71),
                 new Company("Section 1","Caterpillar Inc.", 67.27, 0.92, 1.39),
                 new Company("Section 1","Citigroup, Inc.", 49.37, 0.02, 0.04),
                 new Company("Section 2","E.I. du Pont de Nemours and Company", 40.48, 0.51, 1.28),
                 new Company("Section 2","Exxon Mobil Corp", 68.1, -0.43, -0.64),
                 new Company("Section 2","General Electric Company", 34.14, -0.08, -0.23),
                 new Company("Section 2","General Motors Corporation", 30.27, 1.09, 3.74),
                 new Company("Section 2","Hewlett-Packard Co.", 36.53, -0.03, -0.08),
                 new Company("Section 2","Honeywell Intl Inc", 38.77, 0.05, 0.13),
                 new Company("Section 2","Intel Corporation", 19.88, 0.31, 1.58),
                 new Company("Section 2","International Business Machines", 81.41, 0.44, 0.54),
                 new Company("Section 2","Johnson & Johnson", 64.72, 0.06, 0.09),
                 new Company("Section 2","JP Morgan & Chase & Co", 45.73, 0.07, 0.15),
                 new Company("Section 2","McDonald\"s Corporation", 36.76, 0.86, 2.40),
                 new Company("Section 2","Merck & Co., Inc.", 40.96, 0.41, 1.01),
                 new Company("Section 3","Microsoft Corporation", 25.84, 0.14, 0.54),
                 new Company("Section 3","Pfizer Inc", 27.96, 0.4, 1.45),
                 new Company("Section 3","The Coca-Cola Company", 45.07, 0.26, 0.58),
                 new Company("Section 3","The Home Depot, Inc.", 34.64, 0.35, 1.02),
                 new Company("Section 3","The Procter & Gamble Company", 61.91, 0.01, 0.02),
                 new Company("Section 3","United Technologies Corporation", 63.26, 0.55, 0.88),
                 new Company("Section 3","Verizon Communications", 35.57, 0.39, 1.11),
                 new Company("Section 3","Wal-Mart Stores, Inc.", 45.45, 0.73, 1.63)
             };
        }
        public class Company {
            public Company(string group, string name, double price, double change, double pctChange) {
                this.Group = group;
                this.Name = name;
                this.Price = price;
                this.Change = change;
                this.PctChange = pctChange;
            }
            public Company() {
            }
            public string Group { get; set; }
            public string Name { get; set; }
            public double Price { get; set; }
            public double Change { get; set; }
            public double PctChange { get; set; }
        }
    </script>
    <html>
    <head runat="server">
        <title>Row Selection Model</title>
        <script>
            var template = '<span style="color:{0};">{1}</span>';
            var change = function (value) {
                return Ext.String.format(template, (value > 0) ? "green" : "red", value);
            };
            var pctChange = function (value) {
                return Ext.String.format(template, (value > 0) ? "green" : "red", value + "%");
            };
            var CheckboxSelectionModel1_SelectionChange = function () {
                var totalCount = App.GridPanel1.store.getAllRange().length,
                    selectedCount = App.GridPanel1.getSelectionModel().getCount();
                Ext.Msg.notify("Counts ", "Total: " + totalCount + "<br/> Selected: " + selectedCount);
            };
            var GridPanel1_setup = function () {
                App.Grouping1.collapseAll();
                App.Grouping1.expand("Section 1", true);
                App.CheckboxSelectionModel1.selectAll(false);
                var totalCount = App.GridPanel1.store.getAllRange().length,
                    selectedCount = App.GridPanel1.getSelectionModel().getCount(); 
                Ext.Msg.alert("Counts ", "Total: " + totalCount + "<br/> Selected: " + selectedCount + " <-- should be 9");
            };
        </script>
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
            <ext:Store ID="Store1" runat="server" GroupField="Group">
                <Model>
                    <ext:Model runat="server" IDProperty="Name">
                        <Fields>
                            <ext:ModelField Name="Group" />
                            <ext:ModelField Name="Name" />
                            <ext:ModelField Name="Price" />
                            <ext:ModelField Name="Change" />
                            <ext:ModelField Name="PctChange" />
                        </Fields>
                    </ext:Model>
                </Model>
            </ext:Store>
            <ext:GridPanel
                runat="server"
                ID="GridPanel1"
                StoreID="Store1"
                Title="Company List"
                Collapsible="true"
                Width="600"
                Height="500">
                <ColumnModel runat="server">
                    <Columns>
                        <ext:Column runat="server" Text="Company" DataIndex="Name" Flex="1" />
                        <ext:Column runat="server" Text="Price" Width="75" DataIndex="Price">
                            <Renderer Format="UsMoney" />
                        </ext:Column>
                        <ext:Column runat="server" Text="Change" Width="75" DataIndex="Change">
                            <Renderer Fn="change" />
                        </ext:Column>
                        <ext:Column runat="server" Text="Change" Width="75" DataIndex="PctChange">
                            <Renderer Fn="pctChange" />
                        </ext:Column>
                    </Columns>
                </ColumnModel>
                <SelectionModel>
                    <ext:CheckboxSelectionModel runat="server" ID="CheckboxSelectionModel1" Mode="Multi" CheckOnly="true">
                        <Listeners>
                            <SelectionChange Fn="CheckboxSelectionModel1_SelectionChange"  />                     
                        </Listeners>
                    </ext:CheckboxSelectionModel>
                </SelectionModel>
                <Features>
                    <ext:Grouping
                        ID="Grouping1"
                        runat="server"
                        HideGroupedHeader="true"
                        GroupHeaderTplString='{columnName}: {name} ({children.length} Item{[values.children.length > 1 ? "s" : ""]})'>
                    </ext:Grouping>
                </Features>
                <Listeners>
                    <ViewReady fn="GridPanel1_setup" Delay="50" />
                </Listeners>
            </ext:GridPanel>
       </form>
    </body>
    </html>
    Is there a way to get the real number of selected records?
    Alternatively how would I go about creating a UI that would allow the user to select all the records in a group?
    Last edited by fabricio.murta; Feb 20, 2016 at 12:58 AM. Reason: meant 'fixed' not 'closed' on the bug status.
  2. #2
    Hello Nathan!

    Sorry for the delay replying to this. Your test case was excellent! That's really a bug, we are going to log this in minutes but I wanted to share with you a workaround for the problem, see if this works for you. We still have to double check if this change would work on other use case scenarios before implementing it difinitively to the code.

            Ext.define('Ext.selection.Model', {
                override: 'Ext.selection.Model',
                selectAll: function (suppressEvent) {
                    var me = this,
                        rawSelection = me.store.getRange(),
                        selections = [],
                        start = me.getSelection().length;
    
                    // Remove phantom records from what will be selected
                    for (var id in rawSelection) {
                        if (!rawSelection[id].phantom) {
                            selections.push(rawSelection[id]);
                        }
                    }
    
                    me.suspendChanges();
                    me.doSelect(selections, true, suppressEvent);
                    me.resumeChanges();
    
                    if (!suppressEvent && !me.isDestroyed) {
                        me.maybeFireSelectionChange(me.getSelection().length !== start);
                    }
                }
            });
    Add this to your javaScript block (between lines 60 and 81 of your sample test case) and give it a try. Seems it worked fine here. The error can also be triggered if I collapse the group and click the checkbox column header's checkbox. With the fix I was no longer able to reproduce the issue.
    Fabrício Murta
    Developer & Support Expert
  3. #3
    Hi Fabricio!

    Not a problem and thank-you.

    The error can also be triggered if I collapse the group and click the checkbox column header's checkbox. With the fix I was no longer able to reproduce the issue.
    My apologies, I forgot to mention that this was also a way to reproduce it (it was infact the way I discovered the issue).

    That's really a bug, we are going to log this in minutes but I wanted to share with you a workaround for the problem, see if this works for you. We still have to double check if this change would work on other use case scenarios before implementing it difinitively to the code.
    I have added this to my code base and it worked perfectly. My only concern is knowing when the real fix is implemented so I can remove the hotfix from my code.
  4. #4
    About your expectations on having this fixed, I have a good, and a not-so-good news to share.

    The good news is that our Ext.NET 4, implementing ExtJS 6.0.1 has a robust fix for this selection issue!

    Something that you'd probably not like much is, the fix of the collapsed group entry makes it so selectAll() really works as a select all entries mechanism. I.e. If you collapse a group, click the header check box, and expand the group again, you'll see that its inner entries are all selected,

    You'd have to select whole groups by iteracting thru the items and selecting them whenever the desired group's data pattern matches. As this is a specific need and selectAll() to select just the displayed entries might be misleading in the majority of cases.

    Maybe, since now, to avoid known breaking changes in the future, you should already avoid relying on this method, and do a pattern-selecting to the records instead.

    In other words, in this case, best you do is rely on your own code to select only the displayed groups.
    Fabrício Murta
    Developer & Support Expert
  5. #5
    About your expectations on having this fixed, I have a good, and a not-so-good news to share.


    The good news is that our Ext.NET 4, implementing ExtJS 6.0.1 has a robust fix for this selection issue!


    Something that you'd probably not like much is, the fix of the collapsed group entry makes it so selectAll() really works as a select all entries mechanism. I.e. If you collapse a group, click the header check box, and expand the group again, you'll see that its inner entries are all selected,


    You'd have to select whole groups by iteracting thru the items and selecting them whenever the desired group's data pattern matches. As this is a specific need and selectAll() to select just the displayed entries might be misleading in the majority of cases.


    Maybe, since now, to avoid known breaking changes in the future, you should already avoid relying on this method, and do a pattern-selecting to the records instead.


    In other words, in this case, best you do is rely on your own code to select only the displayed groups.
    This new behaviour is in Ext.NET 4 only I am correct?

    Will the patch you gave be applied to build of 3.x?

    I don't mind having to build a interface to support the selection of a single group I am a little lost as to how I can
    a) link it into the group header and b) support a dynamic selection of groups (my data consists of a variable number of groups).
  6. #6
    Here, this is my suggestion for you to handle this in the best way. I believe it will be much less likely to give you upgrade headaches in the future if you do like this:

    var selectShownEntries = function () {
        var store = App.GridPanel1.getStore(),
            groups = store.getGroups(),
            selectionModel = App.GridPanel1.getSelectionModel(),
            groupFeatureHandle = App.GridPanel1.groupingFeature,
            keepExistingSelection = true, // keep selected entries previously
            suppressEvent = false; // suppress 'select' event from batch selection
    
        // Grouping is disabled, just select all.
        if (!groups.grouped) {
            selectionModel.selectAll();
            return;
        }
    
        // Clear current selection -- so we can iteractively select all we want
        selectionModel.deselectAll();
    
        // Iterate thru groups, selecting their records if group is not collapsed
        for (var gid in groups.items) {
            var group = groups.items[gid];
            var metaGroup = groupFeatureHandle.getMetaGroup(group);
    
            // If the group is not collapsed, then select every record it encloses
            if (!metaGroup.isCollapsed) {
                selectionModel.select(group.items, keepExistingSelection, suppressEvent);
            }
        }
    }
    It was written in your very sample. You may remove the override I suggested previously -- but the 'select all' header check box will still break, you may want to just hide/disable it, make a proper fix to selectAll* -- or just wait until we release a proper fix from our side.

    I just added a button to the page to test that function, something like this:
    <ext:Button runat="server" Text="Select non-collapsed entries" OnClientClick="selectShownEntries();" />
    Then whenever I change the collapsed/expanded groups, and click the button, only the displayed records are properly selected.

    *) A "proper" fix to selectAll would basically be replacing the override I suggested earlier with the above function's body -- except for, it will not check for !metaGroup.isCollapsed, it will always do the inner selection.
    Fabrício Murta
    Developer & Support Expert
  7. #7
    I have just checked it, the fix on the selection when grouped has already been fixed on the upcoming Ext.NET 3.3 as well!

    So, more than ever, proper selecting to skip collapsed groups is required.

    I have created an issue and assigned to this thread because it was not reported before and is still actual until Ext.NET 3.3 release. The issue is available at github's #1254.

    I have also tagged the issue as [CLOSED] but feel free to continue the discussion if you are not satisfied with the fix and/or alternative provided to handle your issue!
    Fabrício Murta
    Developer & Support Expert

Similar Threads

  1. GridPanel grouping feature problem
    By gefran in forum 2.x Help
    Replies: 4
    Last Post: Jul 10, 2015, 10:16 PM
  2. [CLOSED] Facing problem with checkbox selection problem in gridpanel.
    By arjunrvasisht in forum 2.x Legacy Premium Help
    Replies: 1
    Last Post: May 06, 2015, 3:55 PM
  3. [CLOSED] Grid Row Selection Model - Row Count
    By speedstepmem4 in forum 2.x Legacy Premium Help
    Replies: 1
    Last Post: Jul 18, 2014, 5:46 PM
  4. grid with grouping and checkbox selection
    By [WP]joju in forum 1.x Help
    Replies: 1
    Last Post: Sep 30, 2009, 11:05 AM
  5. GridPanel Grouping Problem
    By yaser82 in forum 1.x Help
    Replies: 10
    Last Post: May 27, 2009, 4:53 AM

Tags for this Thread

Posting Permissions