[CLOSED] Help needed with GridPanel CustomSummaryType records.length value

  1. #1

    [CLOSED] Help needed with GridPanel CustomSummaryType records.length value

    Hello, I am finding that GridPanel CustomSummaryType javascript function uses records.length, but this value is the PageSize of the store when the grid has a paging toolbar. How do I get the total record count of the store instead of the records filtered by the paging tool bar? To duplicate the issue I have modified https://examples4.ext.net/#/GridPane...group_headers/

    Note that the value returned by var totalCost is no longer $9500 as it is in the website example and instead it is $4900 or $4600 based on the displayed page. Is it not possible to use CustomSummaryType and PagingToolbar together? If it is possible can you please advise. Thank you -MCR

    <%@ Page Language="C#" %>
    
    <%@ Import Namespace="System.Collections.Generic" %>
    
    <!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 id="Head1" 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>
            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 id="Form1" 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 ID="ResourceManager1" 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"  PageSize="10">
                        <Sorters>
                            <ext:DataSorter Property="Due" Direction="ASC" />
                        </Sorters>
                        <Model>
                            <ext:Model ID="Model1" 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 ID="CellEditing1" runat="server" ClicksToEdit="1" />
                    <ext:DataTip ID="DataTip1" runat="server">
                        <Tpl>
                            <Html>
                                Click to edit {colName}
                            </Html>
                        </Tpl>
                        <BeforeShowTip Fn="beforeShowTip" />
                    </ext:DataTip>
                </Plugins>
                <ColumnModel ID="ColumnModel1" runat="server">
                    <Columns>
                        <ext:Column ID="Column1"
                            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 ID="TextField1" runat="server" />
                            </Editor>
                        </ext:Column>
    
                        <ext:Column ID="Column2" runat="server" Text="Project" DataIndex="Name" Width="180" />
    
                        <ext:Column ID="Column3" runat="server" Text="Schedule">
                            <Columns>
                                <ext:DateColumn ID="DateColumn1"
                                    runat="server"
                                    Width="125"
                                    Text="Due Date"
                                    Sortable="true"
                                    DataIndex="Due"
                                    SummaryType="Max"
                                    Format="MM/dd/yyyy">
                                    <Editor>
                                        <ext:DateField ID="DateField1" runat="server" Format="MM/dd/yyyy" />
                                    </Editor>
                                    <%-- Remove after fixing #563 --%>
                                    <SummaryRenderer Format="Date" FormatArgs="'m/d/Y'" />
                                </ext:DateColumn>
    
                                <ext:Column ID="Column4"
                                    runat="server"
                                    Width="125"
                                    Text="Estimate"
                                    Sortable="true"
                                    DataIndex="Estimate"
                                    SummaryType="Sum">
                                    <Renderer Handler="return value +' hours';" />
                                    <%-- Remove after fixing #563 --%>
                                    <SummaryRenderer Handler="return value + ' hours';" />
                                    <Editor>
                                        <ext:NumberField ID="NumberField1" runat="server" AllowBlank="false" MinValue="0" StyleSpec="text-align:left" />
                                    </Editor>
                                </ext:Column>
    
                                <ext:Column ID="Column5"
                                    runat="server"
                                    Width="125"
                                    Text="Rate"
                                    Sortable="true"
                                    DataIndex="Rate"
                                    SummaryType="Average">
                                    <Renderer Format="UsMoney" />
                                    <%-- Remove after fixing #563 --%>
                                    <SummaryRenderer Format="UsMoney" />
                                    <Editor>
                                        <ext:NumberField ID="NumberField2" runat="server" AllowBlank="false" MinValue="0" StyleSpec="text-align:left" />
                                    </Editor>
                                </ext:Column>
    
                                <ext:Column
                                    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);" />
                                    <%-- Remove after fixing #563 --%>
                                    <SummaryRenderer Format="UsMoney" />
                                </ext:Column>
                            </Columns>
                        </ext:Column>
                    </Columns>
                </ColumnModel>
                <Features>
                    <ext:GroupingSummary
                        ID="group"
                        runat="server"
                        GroupHeaderTplString="{name}"
                        HideGroupedHeader="true"
                        EnableGroupingMenu="false" />
    
                    <ext:Summary ID="Summary1" runat="server" Dock="Bottom" />
                </Features>
                <TopBar>
                    <ext:Toolbar ID="Toolbar1" runat="server">
                        <Items>
                            <ext:Button ID="Button1"
                                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>
                <BottomBar>
                             <ext:PagingToolbar ID="PagingToolbar2" runat="server" HideRefresh="true"></ext:PagingToolbar>
                         </BottomBar>
            </ext:GridPanel>
        </form>
      </body>
    </html>
  2. #2
    Hello MCR, and welcome to Ext.NET forums!

    Sorry for the delay in the response, I hope we can make up for it with the reply below!

    If you're not into reading, you can just skip below to the code block, it implements one way to solve your issue. Otherwise, sit tight and happy reading!

    You ask if that's impossible to attain. Well, in computing most things are not impossible, particularly if they can be done in other ways. There are some very difficult things and others that are not so difficult though.

    Fortunately, this time the issue is not very difficult, but it would be easier to have some more knowledge of what's going on.

    Usually a grid, when it displays only a subset of the data, it keeps its original store with all data, and a "filtered store" (or something the likes) to fool the grid into showing only what the plugin or feature (like paging grid) wants to.

    Aside from that, all records come from a store. So, why not, a record should have a pointer to the store. And so it does.

    But now you get nowhere. The records from a filtered store will link to a filtered store, with the limited amount of data. But wait, the filtered store could have a reference to the full store, right? Yes!

    Now the maybe last bit left is: so, how to make the summary do the sum? That would be a bigger problem if you were using stock/predefined summary types, but in the case you raised, you're worried exactly with the custom summary type, which you define in your sample's code lines 86 to 97 (and referenced on line 241). So then well, all we have to do is customize the already custom code.

    Of course the paragraphs above point to the "forward engineer" after "reverse engineering" what was available to us from that custom code -- which are the records. So then joining the information, from the records we get the paged store, from the paged store, the raw store. From that, the full data set where we can do the math we want for the summary row.

    Then, I can just keep the calculation and replace the records variable with a reference to the full list of records doing this:

    var totalCost = function (records) {
        var i = 0,
            length = records.length,
            total = 0,
            record;
    
        // You may also fancy here checking whether the list of records is
        // already the full list, so you don't need to always bind data.
        if (length > 0) {
            // Now make records become the first record's reference to
            // store and all the data.
            records = records[0].store.allData.items;
            length = records.length;
        }
    
        for (; i < length; ++i) {
            record = records[i];
            total += record.get('Estimate') * record.get('Rate');
        }
        return total;
    };
    There's always several ways to do a same thing in Ext.NET (as in many programming scenarios and languages), this is just one way to solve the problem you have, and there may be more elegant ways to do so. The focus here is just to show one solution using the code you have.

    Well, if you had a server-side paged store (and a hybrid example), then the history would have been different. As data would come from the server that way, we wouldn't have the full data set handy then, so the only way to resolve would be a server-side summary (or just providing the summary field with the total value for all rows (including the ones not provided by the server), from the server itself.

    You can find out those references record has by just trying with browser's debugging tools while you step by breakpoints in the code. Setting ResourceManager with ScriptMode="Debug" SourceFormatting="true" also helps developing and walking thru methods, but you can also rely on the client-side documentation at Sencha Documentation page. Notice you want to stick to the classic toolkit, as that's the one Ext.NET uses.

    Unfortunately though, as we need custom behavior and extend functionalities, like in the case of this thread, we need to tread a dangerous territory: undocumented methods and properties. In fact, the record's store, store's allData for example are not documented in Sencha. This give them the right to change those methods as they will and next release, even a minor release, they can be gone so, as you extend features, whenever possible try to stick to their documentation as far as it is feasible. Unfortunately, I couldn't find a good alternative but you can reduce risks, for example, if you access the store directly instead of relying on the first record:

    records = App.Store1.getAllRange();
    length = records.length;
    But although here we will be able to access App.Store1 across versions, we won't be able to guarantee getAllRange() would be likewise available.

    Well, I hope this helps clarify the issue you have and also help you understand how we got into the solution and also how to proceed from this point. And of course, that the reading was not too boring. :)

    Last but not least, thanks for the fully runnable test sample, this really helps us a great deal on understanding the issue you have without having to guess (with often goes wrong and only results on several pages long threads and no solutions). You did very well with the test case, and I hope the answer above (the code part at least) can help you solve your problem!
    Fabrício Murta
    Developer & Support Expert
  3. #3
    fabricio thank you very much for your response, I surely would not have figured this one out without you! I have confirmed this fixes my issue. -MCR

Similar Threads

  1. [CLOSED] Background Color in CustomSummaryType
    By Z in forum 3.x Legacy Premium Help
    Replies: 10
    Last Post: Apr 26, 2016, 2:08 AM
  2. [CLOSED] CustomSummaryType and ColumnName
    By bbros in forum 3.x Legacy Premium Help
    Replies: 9
    Last Post: Aug 18, 2015, 3:18 PM
  3. Replies: 3
    Last Post: Nov 19, 2014, 5:30 AM
  4. Replies: 0
    Last Post: Apr 06, 2011, 1:06 PM
  5. Replies: 3
    Last Post: Jun 29, 2010, 2:54 PM

Tags for this Thread

Posting Permissions