[FIXED] [#493] [3.2.0] GridPanel with grouping data contains double quote.

  1. #1

    [FIXED] [#493] [3.2.0] GridPanel with grouping data contains double quote.

    Hi,

    I have a gridpanel with Grouping feature, if grouping field data contains double quotes (") then collapse and expand functions are not working.
    ex: data is like "TestGroup".

    Thank you.

    <%@ Page Language="C#" %>
     
    <%@ Import Namespace="System.Globalization" %>
    <%@ Import Namespace="System.Collections.Generic" %>
     
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
     
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            CultureInfo ci = new CultureInfo("en-US");
    
            Store store = this.GridPanel1.GetStore();
            
            store.DataSource = new List<Project> 
            { 
                new Project(100, "\"Ext Forms: Field Anchoring\"",      100, "Integrate 2.0 Forms with 2.0 Layouts", 6, 150, 0, DateTime.Parse("06/24/2007",ci)),
                new Project(100, "\"Ext Forms: Field Anchoring\"",      101, "Implement AnchorLayout", 4, 150, 0, DateTime.Parse("06/25/2007",ci)),
                new Project(100, "\"Ext Forms: Field Anchoring\"",      102, "Add support for multiple types of anchors", 4, 150, 0, DateTime.Parse("06/27/2007",ci)),
                new Project(100, "\"Ext Forms: Field Anchoring\"",      103, "Testing and debugging", 8, 0, 0, DateTime.Parse("06/29/2007",ci)),
                new Project(100, "\"Ext Forms: Field Anchoring\"",      104, "Add required rendering \"hooks\" to GridView", 6, 100, 0, DateTime.Parse("07/01/2007",ci)),
                new Project(100, "\"Ext Forms: Field Anchoring\"",      105, "Extend GridView and override rendering functions", 6, 100, 0, DateTime.Parse("07/03/2007",ci)),
                new Project(100, "\"Ext Forms: Field Anchoring\"",      106, "Extend Store with grouping functionality", 4, 100, 0, DateTime.Parse("07/04/2007",ci)),
                new Project(100, "\"Ext Forms: Field Anchoring\"",      107, "Default CSS Styling", 2, 100, 0, DateTime.Parse("07/05/2007",ci)),
                new Project(100, "\"Ext Forms: Field Anchoring\"",      108, "Testing and debugging", 6, 100, 0, DateTime.Parse("07/06/2007",ci)),
                new Project(100, "\"Ext Forms: Field Anchoring\"",      109, "Integrate 2.0 Forms with 2.0 Layouts", 6, 150, 0, DateTime.Parse("06/24/2007",ci)),
                new Project(100, "\"Ext Forms: Field Anchoring\"",      110, "Implement AnchorLayout", 4, 150, 0, DateTime.Parse("06/25/2007",ci)),
                new Project(100, "\"Ext Forms: Field Anchoring\"",      111, "Add support for multiple types of anchors", 4, 150, 0, DateTime.Parse("06/27/2007",ci)),
                new Project(100, "\"Ext Forms: Field Anchoring\"",      112, "Testing and debugging", 8, 0, 0, DateTime.Parse("06/29/2007",ci)),
                new Project(100, "\"Ext Forms: Field Anchoring\"",      113, "Add required rendering \"hooks\" to GridView", 6, 100, 0, DateTime.Parse("07/01/2007",ci)),
                new Project(100, "\"Ext Forms: Field Anchoring\"",      114, "Extend GridView and override rendering functions", 6, 100, 0, DateTime.Parse("07/03/2007",ci)),
                new Project(100, "\"Ext Forms: Field Anchoring\"",      115, "Extend Store with grouping functionality", 4, 100, 0, DateTime.Parse("07/04/2007",ci)),
                new Project(100, "\"Ext Forms: Field Anchoring\"",      116, "Default CSS Styling", 2, 100, 0, DateTime.Parse("07/05/2007",ci)),
                new Project(100, "\"Ext Forms: Field Anchoring\"",      117, "Testing and debugging", 6, 100, 0, DateTime.Parse("07/06/2007",ci)),
                
                new Project(102, "Ext Grid: Summary Rows",          118, "Ext Grid plugin integration", 4, 125, 0, DateTime.Parse("07/01/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          119, "Summary creation during rendering phase", 4, 125, 0, DateTime.Parse("07/02/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          120, "Dynamic summary updates in editor grids", 6, 125, 0, DateTime.Parse("07/05/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          121, "Remote summary integration", 4, 125, 0, DateTime.Parse("07/05/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          122, "Summary renderers and calculators", 4, 125, 0, DateTime.Parse("07/06/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          123, "Integrate summaries with GroupingView", 10, 125, 0, DateTime.Parse("07/11/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          124, "Testing and debugging", 8, 125, 0, DateTime.Parse("07/15/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          125, "Ext Grid plugin integration", 4, 125, 0, DateTime.Parse("07/01/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          126, "Summary creation during rendering phase", 4, 125, 0, DateTime.Parse("07/02/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          127, "Dynamic summary updates in editor grids", 6, 125, 0, DateTime.Parse("07/05/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          128, "Remote summary integration", 4, 125, 0, DateTime.Parse("07/05/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          129, "Summary renderers and calculators", 4, 125, 0, DateTime.Parse("07/06/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          130, "Integrate summaries with GroupingView", 10, 125, 0, DateTime.Parse("07/11/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          131, "Testing and debugging", 8, 125, 0, DateTime.Parse("07/15/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          132, "Ext Grid plugin integration", 4, 125, 0, DateTime.Parse("07/01/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          133, "Summary creation during rendering phase", 4, 125, 0, DateTime.Parse("07/02/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          134, "Dynamic summary updates in editor grids", 6, 125, 0, DateTime.Parse("07/05/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          135, "Remote summary integration", 4, 125, 0, DateTime.Parse("07/05/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          136, "Summary renderers and calculators", 4, 125, 0, DateTime.Parse("07/06/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          137, "Integrate summaries with GroupingView", 10, 125, 0, DateTime.Parse("07/11/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          138, "Testing and debugging", 8, 125, 0, DateTime.Parse("07/15/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          139, "Ext Grid plugin integration", 4, 125, 0, DateTime.Parse("07/01/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          140, "Summary creation during rendering phase", 4, 125, 0, DateTime.Parse("07/02/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          141, "Dynamic summary updates in editor grids", 6, 125, 0, DateTime.Parse("07/05/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          142, "Remote summary integration", 4, 125, 0, DateTime.Parse("07/05/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          143, "Summary renderers and calculators", 4, 125, 0, DateTime.Parse("07/06/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          144, "Integrate summaries with GroupingView", 10, 125, 0, DateTime.Parse("07/11/2007",ci)),
                new Project(102, "Ext Grid: Summary Rows",          145, "Testing and debugging", 8, 125, 0, DateTime.Parse("07/15/2007",ci))
            };
     
            store.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>
    
    <!DOCTYPE html>
    
    <html>
    <head runat="server">
        <title>Grouping Paging - Ext.NET Examples</title>
        <link href="/resources/css/examples.css" rel="stylesheet" />
        <script>
            Ext.view.Table.override({
                indexInStore: function (node) {
                    node = (node && node.isCollapsedPlaceholder) ? this.getNode(node) : this.getNode(node, false);
    
                    if (!node && node !== 0) {
                        return -1;
                    }
    
                    var recordIndex = node.getAttribute('data-recordIndex');
    
                    if (recordIndex) {
                        return parseInt(recordIndex, 10);
                    }
    
                    return this.dataSource.indexOf(this.getRecord(node));
                }
            });
        </script>
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server"/>
               <ext:Viewport runat="server" ID="ViewPort1" Layout="HBoxLayout">
               <LayoutConfig>
               <ext:HBoxLayoutConfig Align="Stretch" Pack="Center"  />
               </LayoutConfig>
            <Content>  
            
            <ext:GridPanel
                ID="GridPanel1"
                runat="server"
                Width="800"
                AutoScroll="true"
                ButtonAlign="Center">
                <Store>
                    <ext:Store ID="Store1" runat="server" GroupField="Name">
                       
                        <Model>
                            <ext:Model runat="server" IDProperty="TaskID">
                                <Fields>
                                    <ext:ModelField Name="ProjectID" />
                                    <ext:ModelField Name="Name" />
                                    <ext:ModelField Name="TaskID" />
                                    <ext:ModelField Name="Description" />
                                    <ext:ModelField Name="Estimate" Type="Int" />
                                    <ext:ModelField Name="Rate" Type="Float" />                                
                                    <ext:ModelField Name="Due" Type="Date" />
                                </Fields>
                            </ext:Model>
                        </Model>
                    </ext:Store>
                </Store>
                <ColumnModel runat="server">
                    <Columns>
                        <ext:Column                        
                            runat="server"
                            TdCls="task"
                            Text="Task"                       
                            Sortable="true"
                            DataIndex="Description"
                            Hideable="false"
                            Flex="1"
                            />
                         
                     
                    </Columns>                
                </ColumnModel>            
                <Features>
                    <ext:Grouping 
                        ID="Group1" 
                        runat="server" 
                        GroupHeaderTplString="{name}" 
                        HideGroupedHeader="true" 
                        EnableGroupingMenu="false" 
                        />
                </Features>
               <Buttons>
               <ext:Button runat="server" Text="Button1" />
               <ext:Button ID="Button1" runat="server" Text="Button2" />
               </Buttons>
            </ext:GridPanel>
             </Content>
        </ext:Viewport>
        </form>
      </body>
    </html>
    Last edited by Daniil; Jun 26, 2015 at 11:47 AM. Reason: [FIXED] [#493] [3.2.0]
  2. #2
    Hi @iansriley,

    I reproduced. Needs some time to investigate.
  3. #3
    Created an Issue:
    https://github.com/extnet/Ext.NET/issues/493

    As a solution we can suggest the following override.
    Ext.grid.feature.Grouping.override({
        groupTpl: [
            '{%',
                'var me = this.groupingFeature;',
                // If grouping is disabled, do not call setupRowData, and do not wrap
                'if (me.disabled) {',
                    'values.needsWrap = false;',
                '} else {',
                    'me.setupRowData(values.record, values.recordIndex, values);',
                    'values.needsWrap = !me.disabled && (values.isFirstRow || values.summaryRecord);',
                '}',
            '%}',
            '<tpl if="needsWrap">',
                '<tr data-boundView="{view.id}" data-recordId="{record.internalId:htmlEncode}" data-recordIndex="{[values.isCollapsedGroup ? -1 : values.recordIndex]}"',
                    'class="{[values.itemClasses.join(" ")]} ' + Ext.baseCSSPrefix + 'grid-wrap-row<tpl if="!summaryRecord"> ' + Ext.baseCSSPrefix + 'grid-group-row</tpl>">',
                    '<td class="' + Ext.baseCSSPrefix + 'group-hd-container" colspan="{columns.length}">',
                        '<tpl if="isFirstRow">',
                            '{%',
                                // Group title is visible if not locking, or we are the locked side, or the locked side has no columns/
                                // Use visibility to keep row heights synced without intervention.
                                'var groupTitleStyle = (!values.view.lockingPartner || (values.view.ownerCt === values.view.ownerCt.ownerLockable.lockedGrid) || (values.view.lockingPartner.headerCt.getVisibleGridColumns().length === 0)) ? "" : "visibility:hidden";',
                            '%}',
                            '<div id="{groupId}" class="' + Ext.baseCSSPrefix + 'grid-group-hd {collapsibleCls}" tabIndex="0">',
                                '<div class="' + Ext.baseCSSPrefix + 'grid-group-title" style="{[groupTitleStyle]}">',
                                    '{[values.groupHeaderTpl.apply(values.groupInfo, parent) || "&#160;"]}',
                                '</div>',
                            '</div>',
                        '</tpl>',
    
                        // Only output the child rows if  this is *not* a collapsed group
                        '<tpl if="summaryRecord || !isCollapsedGroup">',
                            '<table class="', Ext.baseCSSPrefix, '{view.id}-table ', Ext.baseCSSPrefix, 'grid-table',
                                '<tpl if="summaryRecord"> ', Ext.baseCSSPrefix, 'grid-table-summary</tpl>"',
                                'border="0" cellspacing="0" cellpadding="0" style="width:100%">',
                                '{[values.view.renderColumnSizer(out)]}',
                                // Only output the first row if this is *not* a collapsed group
                                '<tpl if="!isCollapsedGroup">',
                                    '{%',
                                        'values.itemClasses.length = 0;',
                                        'this.nextTpl.applyOut(values, out, parent);',
                                    '%}',
                                '</tpl>',
                                '<tpl if="summaryRecord">',
                                    '{%me.outputSummaryRecord(values.summaryRecord, values, out);%}',
                                '</tpl>',
                            '</table>',
                        '</tpl>',
                    '</td>',
                '</tr>',
            '<tpl else>',
                '{%this.nextTpl.applyOut(values, out, parent);%}',
            '</tpl>', {
                priority: 200,
    
                syncRowHeights: function(firstRow, secondRow) {
                    firstRow = Ext.fly(firstRow, 'syncDest');
                    secondRow = Ext.fly(secondRow, 'sycSrc');
                    var owner = this.owner,
                        firstHd = firstRow.down(owner.eventSelector, true),
                        secondHd,
                        firstSummaryRow = firstRow.down(owner.summaryRowSelector, true),
                        secondSummaryRow,
                        firstHeight, secondHeight;
    
                    // Sync the heights of header elements in each row if they need it.
                    if (firstHd && (secondHd = secondRow.down(owner.eventSelector, true))) {
                        firstHd.style.height = secondHd.style.height = '';
                        if ((firstHeight = firstHd.offsetHeight) > (secondHeight = secondHd.offsetHeight)) {
                            Ext.fly(secondHd).setHeight(firstHeight);
                        }
                        else if (secondHeight > firstHeight) {
                            Ext.fly(firstHd).setHeight(secondHeight);
                        }
                    }
    
                    // Sync the heights of summary row in each row if they need it.
                    if (firstSummaryRow && (secondSummaryRow = secondRow.down(owner.summaryRowSelector, true))) {
                        firstSummaryRow.style.height = secondSummaryRow.style.height = '';
                        if ((firstHeight = firstSummaryRow.offsetHeight) > (secondHeight = secondSummaryRow.offsetHeight)) {
                            Ext.fly(secondSummaryRow).setHeight(firstHeight);
                        }
                        else if (secondHeight > firstHeight) {
                            Ext.fly(firstSummaryRow).setHeight(secondHeight);
                        }
                    }
                },
    
                syncContent: function(destRow, sourceRow) {
                    destRow = Ext.fly(destRow, 'syncDest');
                    sourceRow = Ext.fly(sourceRow, 'sycSrc');
                    var owner = this.owner,
                        destHd = destRow.down(owner.eventSelector, true),
                        sourceHd = sourceRow.down(owner.eventSelector, true),
                        destSummaryRow = destRow.down(owner.summaryRowSelector, true),
                        sourceSummaryRow = sourceRow.down(owner.summaryRowSelector, true);
    
                    // Sync the content of header element.
                    if (destHd && sourceHd) {
                        Ext.fly(destHd).syncContent(sourceHd);
                    }
    
                    // Sync the content of summary row element.
                    if (destSummaryRow && sourceSummaryRow) {
                        Ext.fly(destSummaryRow).syncContent(sourceSummaryRow);
                    }
                }
            }
        ]
    });
  4. #4
    That is no longer reproducible with the latest Ext.NET from SVN trunk. So, the upcoming 3.2.0 release will get rid of this issue. Though, earlier 3.x release might be okay as well.

Similar Threads

  1. [CLOSED] gridPanel enable nullable<double>
    By marco.morreale in forum 2.x Legacy Premium Help
    Replies: 2
    Last Post: May 22, 2014, 12:17 PM
  2. GridPanel double click
    By AlexMaslakov in forum 1.x Help
    Replies: 1
    Last Post: Sep 12, 2011, 9:52 AM
  3. Replies: 2
    Last Post: Aug 04, 2011, 2:14 PM
  4. [CLOSED] JSON.Deserialize backslash and double-quote fixing
    By webclouder in forum 1.x Legacy Premium Help
    Replies: 13
    Last Post: Jun 20, 2011, 9:10 PM
  5. Replies: 4
    Last Post: Nov 22, 2010, 12:54 PM

Tags for this Thread

Posting Permissions