[FIXED] [#429] [2.x] Group Summary Grid Example Not Refresh When delete rows

  1. #1

    [FIXED] [#429] [2.x] Group Summary Grid Example Not Refresh When delete rows

    Hello i have a problem with group summary grid that does not refresh the group summary total (not the bottom bar totals) when i delete rows.
    I change this https://examples2.ext.net/#/GridPane...group_headers/ example with a delete button to reproduce the problem.

    I cannot find a method to manually refresh the totals myself.

    Any help please ?

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Collections.Generic" %>
    
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    
    <!DOCTYPE html>
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
         {
             this.Store1.DataSource = new List<Project> 
             { 
                new Project(100, "Ext Forms: Field Anchoring", 112, "Integrate 2.0 Forms with 2.0 Layouts", 6, 150, 0, new DateTime(2007, 06, 24)),
                new Project(100, "Ext Forms: Field Anchoring", 113, "Implement AnchorLayout", 4, 150, 0, new DateTime(2007, 06, 25)),
                new Project(100, "Ext Forms: Field Anchoring", 114, "Add support for multiple<br> types of anchors", 4, 150, 0, new DateTime(2007, 06, 27)),
                new Project(100, "Ext Forms: Field Anchoring", 115, "Testing and debugging", 8, 0, 0, new DateTime(2007, 06, 29)),
                new Project(101, "Ext Grid: Single-level Grouping", 101, "Add required rendering \"hooks\" to GridView", 6, 100, 0, new DateTime(2007, 07, 01)),
                new Project(101, "Ext Grid: Single-level Grouping", 102, "Extend GridView and override rendering functions", 6, 100, 0, new DateTime(2007, 07, 03)),
                new Project(101, "Ext Grid: Single-level Grouping", 103, "Extend Store with grouping functionality", 4, 100, 0, new DateTime(2007, 07, 04)),
                new Project(101, "Ext Grid: Single-level Grouping", 121, "Default CSS Styling", 2, 100, 0, new DateTime(2007, 07, 05)),
                new Project(101, "Ext Grid: Single-level Grouping", 104, "Testing and debugging", 6, 100, 0, new DateTime(2007, 07, 06)),
                new Project(102, "Ext Grid: Summary Rows", 105, "Ext Grid plugin integration", 4, 125, 0, new DateTime(2007, 07, 01)),
                new Project(102, "Ext Grid: Summary Rows", 106, "Summary creation during rendering phase", 4, 125, 0, new DateTime(2007, 07, 02)),
                new Project(102, "Ext Grid: Summary Rows", 107, "Dynamic summary updates in editor grids", 6, 125, 0, new DateTime(2007, 07, 05)),
                new Project(102, "Ext Grid: Summary Rows", 108, "Remote summary integration", 4, 125, 0, new DateTime(2007, 07, 05)),
                new Project(102, "Ext Grid: Summary Rows", 109, "Summary renderers and calculators", 4, 125, 0, new DateTime(2007, 07, 06)),
                new Project(102, "Ext Grid: Summary Rows", 110, "Integrate summaries with GroupingView", 10, 125, 0, new DateTime(2007, 07, 11)),
                new Project(102, "Ext Grid: Summary Rows", 111, "Testing and debugging", 8, 125, 0, new DateTime(2007, 07, 15))
             };
    
            this.Store1.DataBind();
        }
    
        public class Project
        {
            public Project(int projectId, string name, int taskId, string description, int estimate, double rate, double cost, DateTime due)
            {
                this.ProjectID = projectId;
                this.Name = name;
                this.TaskID = taskId;
                this.Description = description;
                this.Estimate = estimate;
                this.Rate = rate;
                this.Due = due;
            }
    
            public int ProjectID { get; set; }
            public string Name { get;set; }
            public int TaskID { get; set; }
            public string Description { get;set; }
            public int Estimate { get;set; }
            public double Rate { get; set; }
            public double Cost { get; set; }
            public DateTime Due { get; set; }
        }
    </script>
    
    <html>
    <head runat="server">
        <title>Locking, Cell Editing Summary Grid - Ext.NET Examples</title>
        
        <link href="/resources/css/examples.css" rel="stylesheet" />
       
        <style>
            .x-grid-body .x-grid-cell-Cost {
                background-color : #f1f2f4;
            }
             
            .x-grid-row-summary .x-grid-cell-Cost .x-grid-cell-inner{
                background-color : #e1e2e4;
            }    
    
            .task .x-grid-cell-inner {
                padding-left: 15px;
            }
    
            .x-grid-row-summary .x-grid-cell-inner {
                font-weight: bold;
                font-size: 11px;
                background-color : #f1f2f4;
            } 
        </style>
    
        <script>
    
          function delete_rows(button)
          {
    
            var rows = App.GridPanel1.selModel.getSelection();
            for (var i = 0; i < rows.length; i++) {
              App.GridPanel1.getStore().remove(rows[i]);
            }
          }
    
            var showSummary = true;
    
            var totalCost = function(records) {
                var i = 0,
                    length = records.length,
                    total = 0,
                    record;
    
                for (; i < length; ++i) {
                    record = records[i];
                    total += record.get('Estimate') * record.get('Rate');
                }
                return total;
            };
    
            var toggleSummary = function(b) {
                showSummary = !showSummary;
                var grid = b.up('gridpanel'),
                    view = grid.lockedGrid.getView();
                view.getFeature('group').toggleSummaryRow(showSummary);
                view.refresh();
                view = grid.normalGrid.getView();
                view.getFeature('group').toggleSummaryRow(showSummary);
                view.refresh();            
            };
    
            var beforeShowTip = function(grid, tip, data) {
                var cellNode = tip.triggerEvent.getTarget(tip.view.getCellSelector());
                if (cellNode) {
                    data.colName = tip.view.headerCt.getHeaderAtIndex(cellNode.cellIndex).text;
                }
            };
        </script>
    
    </head>
    <body>
        <form runat="server">
            <h1>Locking, Group Summary Grid Example with grouped headers and docked summary</h1>
            <p>It is not possible to lock or unlock <i>all</i> columns using the user interface. Each side, locked or unlocked must always contain at least one column.</p>
    
            <ext:ResourceManager runat="server"/>        
            
            <ext:GridPanel 
                ID="GridPanel1" 
                runat="server" 
                Frame="true"            
                Title="Sponsored Projects"                         
                Icon="ApplicationViewColumns"
                Width="800"
                Height="450">
                <Store>
                    <ext:Store ID="Store1" runat="server" GroupField="Name">
                        <Sorters>
                            <ext:DataSorter Property="Due" Direction="ASC" />
                        </Sorters>
                        <Model>
                            <ext:Model runat="server" IDProperty="TaskID">
                                <Fields>
                                    <ext:ModelField Name="ProjectID" Type="Int" />
                                    <ext:ModelField Name="Name" />
                                    <ext:ModelField Name="TaskID" Type="Int" />
                                    <ext:ModelField Name="Description" />
                                    <ext:ModelField Name="Estimate" Type="Int" />
                                    <ext:ModelField Name="Rate" Type="Float" />
                                    <ext:ModelField Name="Cost" Type="Float" />
                                    <ext:ModelField Name="Due" Type="Date" />
                                </Fields>
                            </ext:Model>
                        </Model>
                    </ext:Store>
                </Store>
                <Plugins>
                    <ext:CellEditing runat="server" ClicksToEdit="1" />
                    <ext:DataTip runat="server">
                        <Tpl>
                            <Html>
                                Click to edit {colName}
                            </Html>
                        </Tpl>          
                        <BeforeShowTip Fn="beforeShowTip" />
                    </ext:DataTip>
                </Plugins>
                <ColumnModel runat="server">
                    <Columns>
                        <ext:SummaryColumn                        
                            runat="server"
                            Locked="true"
                            TdCls="task"
                            Text="Task"                       
                            Sortable="true"
                            DataIndex="Description"
                            Hideable="false"
                            SummaryType="Count"
                            Width="300">
                            <SummaryRenderer Handler="return ((value === 0 || value > 1) ? '(' + value +' Tasks)' : '(1 Task)');" />     
                            <Editor>
                                <ext:TextField runat="server" />
                            </Editor>                       
                        </ext:SummaryColumn>
                         
                        <ext:Column runat="server" Text="Project" DataIndex="Name" Width="180" />
    
                        <ext:Column runat="server" Text="Schedule">
                            <Columns>
                                <ext:SummaryColumn
                                    runat="server"
                                    Width="125"
                                    Text="Due Date"
                                    Sortable="true"
                                    DataIndex="Due"
                                    SummaryType="Max">
                                    <Renderer Format="Date" FormatArgs="'m/d/Y'" />                        
                                    <SummaryRenderer Fn="Ext.util.Format.dateRenderer('m/d/Y')" />                        
                                    <Editor>
                                        <ext:DateField runat="server" Format="MM/dd/yyyy" />
                                    </Editor>
                                </ext:SummaryColumn>
     
                                <ext:SummaryColumn
                                    runat="server"  
                                    Width="125"
                                    Text="Estimate"
                                    Sortable="true"
                                    DataIndex="Estimate"
                                    SummaryType="Sum">
                                    <Renderer Handler="return value +' hours';" />
                                    <SummaryRenderer Handler="return value +' hours';" />
                                    <Editor>
                                        <ext:NumberField runat="server" AllowBlank="false" MinValue="0" StyleSpec="text-align:left" />
                                    </Editor>
                                </ext:SummaryColumn>
                         
                                <ext:SummaryColumn
                                    runat="server"
                                    Width="125"
                                    Text="Rate"
                                    Sortable="true"
                                    DataIndex="Rate"
                                    SummaryType="Average">
                                    <Renderer Format="UsMoney" />
                                    <SummaryRenderer Fn="Ext.util.Format.usMoney" />
                                     <Editor>
                                        <ext:NumberField runat="server" AllowBlank="false" MinValue="0" StyleSpec="text-align:left" />
                                    </Editor>
                                </ext:SummaryColumn>
                         
                                <ext:SummaryColumn
                                    runat="server"
                                    Width="114"
                                    ID="Cost"
                                    Text="Cost"
                                    Sortable="false"
                                    Groupable="false"
                                    DataIndex="Cost"
                                    CustomSummaryType="totalCost">
                                    <Renderer Handler="return Ext.util.Format.usMoney(record.data.Estimate * record.data.Rate);" />
                                    <SummaryRenderer Fn="Ext.util.Format.usMoney" />
                                </ext:SummaryColumn>
                            </Columns>
                        </ext:Column>                    
                    </Columns>                
                </ColumnModel>           
                <Features>               
                    <ext:GroupingSummary ID="group" runat="server" GroupHeaderTplString="{name}" HideGroupedHeader="true" EnableGroupingMenu="false" />
                    <ext:Summary runat="server" Dock="Bottom" />
                </Features>
                <TopBar>
                    <ext:Toolbar runat="server">
                        <Items>
                            <ext:Button ID="Button1" runat="server" Icon="Delete"  >
                                <Listeners>
                                    <Click Fn="delete_rows" />
                                </Listeners>
                            </ext:Button>
    
                            <ext:Button runat="server" Text="Toggle" ToolTip="Toggle the visibility of summary row" EnableToggle="true" Pressed="true">
                                <Listeners>
                                    <Click Fn="toggleSummary" />
                                </Listeners>
                            </ext:Button>
                        </Items>
                    </ext:Toolbar>
                </TopBar>
                <SelectionModel>
                    <ext:CheckBoxSelectionModel runat="server" />
                </SelectionModel>
            </ext:GridPanel>
        </form>
      </body>
    </html>
    Last edited by Daniil; Feb 06, 2014 at 7:47 AM. Reason: [OPEN] [#429]
  2. #2
    Hi @mtsig,

    Thank you for the report.

    It has been already reported to Sencha and confirmed as a bug.
    http://www.sencha.com/forum/showthread.php?278916

    We created an Issue to track the defect.
    https://github.com/extnet/Ext.NET/issues/429

    Please use this fix.

    Fix
    Ext.data.Store.override({
            updateGroupsOnRemove: function(records) {
            var me = this,
                groups = me.groups,
                len = records.length,
                i, groupName, group, rec;
    
    
            if(!len) {
                rec = records;
                groupName = me.getGroupString(rec);
                group = groups.getByKey(groupName);
                console.log(group);
                if (group) {
                    group.remove(rec);
                    if (group.records.length === 0) {
                        groups.remove(group);
                    }    
                }
            } else {
                for (i = 0; i < len; ++i) {
                    rec = records[i];
                    groupName = me.getGroupString(rec);
                    group = groups.getByKey(groupName);
                    console.log(group);
                    if (group) {
                        group.remove(rec);
                        if (group.records.length === 0) {
                            groups.remove(group);
                        }    
                    }
                }
            }
        },
    
        remove: function(records, /* private */ isMove, silent) {
            /*
                * Pass the isMove parameter if we know we're going to be re-inserting this record
                */
            isMove = isMove === true;
            
            var me = this,
                sync = false,
                snapshot = me.snapshot,
                data = me.data,
                i = 0,
                length,
                info = [],
                allRecords = [],
                indexes = [],
                item,
                isNotPhantom,
                index,
                record,
                removeRange,
                removeCount,
                fireRemoveEvent = !silent && me.hasListeners.remove;
            // Remove a single record
            if (records.isModel) {
                records = [records];
                length = 1;
            }
            
            // Or remove(myRecord)
            else if (Ext.isIterable(records)) {
                length = records.length;
            }
            
            // Allow remove({start:100: end: 110})
            // Private API used by removeAt to remove multiple, contiguous records
                else if (typeof records === 'object') {
                    removeRange = true;
                    i = records.start;
                    length = records.end + 1;
                    removeCount = length - i;
                }
            
            // Build an array of {record: rec, index: idx} objects to sort into index order.
            // Not necessary if we are removing a contiguous range
            if (!removeRange) {
                for (i = 0; i < length; ++i) {
                    
                    record = records[i];
                    
                    // Encountered a record index
                    if (typeof record == 'number') {
                        index = record;
                        record = data.getAt(index);
                    }
                    // Removing a record instance
                    else {
                        index = me.indexOf(record);
                    }
                    
                    // Check record. If number passed, it may not exist.
                    if (record && index > -1) {
                        info.push({
                            record: record,
                            index: index
                        });
                    }
                    
                    // record guaranteed to be a record now
                    if (snapshot) {
                        snapshot.remove(record);
                    }
                }
                
                // Sort records into ascending order so that removalscan be processed in a deterministic order
                info = Ext.Array.sort(info, function(o1, o2) {
                    var index1 = o1.index,
                        index2 = o2.index;
                    
                    return index1 === o2.index2 ? 0 : (index1 < index2 ? -1 : 1);
                });
                
                // The loop below loops through the info array if not removing contiguous range
                i = 0;
                length = info.length;
            }
            
            // we need to maintain a set of indexes since we're not guaranteed to
            // be removing the records in order
            // Start value of i is calculated!
            for (; i < length; i++) {
                if (removeRange) {
                    record = data.getAt(i);
                    index = i;
                } else {
                    item = info[i];
                    record = item.record;
                    index = item.index;
                }
                
                allRecords.push(record);
                indexes.push(index);
                
                isNotPhantom = record.phantom !== true;
                // don't push phantom records onto removed
                if (!isMove && isNotPhantom) {
                    
                    // Store the index the record was removed from so that rejectChanges can re-insert at the correct place.
                    // The record's index property won't do, as that is the index in the overall dataset when Store is buffered.
                    record.removedFrom = index;
                    me.removed.push(record);
                    
                }
                
                record.unjoin(me);
                
                // Remove using the index, but subtract any intervening removed records which would cause the data
                // array to shuffle up.
                index -= i;
                sync = sync || isNotPhantom;
                
                // If we have not been asked to remove a range we must remove individual records
                // and fire the individual remove event..
                if (!removeRange) {
                    if(me.isGrouped()) {
                        me.updateGroupsOnRemove(record);
                    }                
                    data.removeAt(index);
                    // Only fire individual remove events if not silent, and there are listeners.
                    if (fireRemoveEvent) {
                        me.fireEvent('remove', me, record, index, !!isMove);
                    }
                }
            }
            
            // If there was no listener for the single remove event, remove all records
            // from collection in one call
            if (removeRange) {
                data.removeRange(records.start, removeCount);
            }
            
            if (!silent) {
                me.fireEvent('bulkremove', me, allRecords, indexes, !!isMove);
                me.fireEvent('datachanged', me);
            }
            if (!isMove && me.autoSync && sync && !me.autoSyncSuspended) {
                me.sync();
            }
        }
    });
    By the way, to remove the selected records you can just call:
    App.GridPanel1.getStore().remove(App.GridPanel1.selModel.getSelection());
  3. #3
    Daniil,

    it worked! Thank you very much.

    Michael
  4. #4
    Ok is open
    Last edited by mtsig; Feb 11, 2014 at 9:06 AM.
  5. #5
    Hello!

    Sencha claims this issue has been fixed for some time now! So recent versions of Ext.NET should not present this issue by now!

    If not, just let us know!
    Fabrício Murta
    Developer & Support Expert

Similar Threads

  1. Replies: 9
    Last Post: Aug 07, 2015, 3:24 PM
  2. [CLOSED] Edit and Delete Grid Rows with Permissions
    By pint in forum 1.x Legacy Premium Help
    Replies: 1
    Last Post: Jun 25, 2012, 10:24 AM
  3. Replies: 0
    Last Post: Apr 10, 2011, 7:57 PM
  4. Replies: 1
    Last Post: Feb 15, 2011, 5:45 PM
  5. Replies: 1
    Last Post: Sep 03, 2009, 2:06 PM

Posting Permissions