[OPEN] [#1464] [4.2.0] Grid header not lineup with data column when tabbing through the row

  1. #1

    [OPEN] [#1464] [4.2.0] Grid header not lineup with data column when tabbing through the row

    Hi, I have a grid with many columns, to reproduce the issue, just open a window with narrow width. Tabbing through a raw automatically shifts columns into visible position, this is good. The issue is the header does not move with the column. I don't see this problem in 4.1. Any idea?
    Thanks!
    -szhang

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using Ext.Net;
    using Ext.Net.MVC;
    
    
    namespace desktopTest4._2mvc.Controllers
    {
        public class FABHomeController : Controller
        {
            // GET: FABHome
            public ActionResult Index()
            {
                return View();
            }
    
            [DirectMethod(ShowMask = true)]
            public ActionResult CreateWindow()
            {
                var desktop = this.GetDesktop();
                desktop.RemoveModule("add1-module");
    
                return this.PartialExtView("_GridWin");
    
            }
            public ActionResult DataGridPanel()
            {
               
                return PartialView("_DataGridPanel");
                
            }
    
            public ActionResult LoadGridData()
            {
    
                var results = new object[]
                   {
                        new object[] { "3m Co", 71.72, 0.02, 0.03, "9/1 12:00am" },
                        new object[] { "Alcoa Inc", 29.01, 0.42, 1.47, "9/1 12:00am" },
                        new object[] { "Altria Group Inc", 83.81, 0.28, 0.34, "9/1 12:00am" },
                        new object[] { "American Express Company", 52.55, 0.01, 0.02, "9/1 12:00am" },
                        new object[] { "American International Group, Inc.", 64.13, 0.31, 0.49, "9/1 12:00am" },
                        new object[] { "AT&T Inc.", 31.61, -0.48, -1.54, "9/1 12:00am" },
                        new object[] { "Boeing Co.", 75.43, 0.53, 0.71, "9/1 12:00am" },
                        new object[] { "Caterpillar Inc.", 67.27, 0.92, 1.39, "9/1 12:00am" },
                        new object[] { "Citigroup, Inc.", 49.37, 0.02, 0.04, "9/1 12:00am" },
                        new object[] { "E.I. du Pont de Nemours and Company", 40.48, 0.51, 1.28, "9/1 12:00am" },
                        new object[] { "Exxon Mobil Corp", 68.1, -0.43, -0.64, "9/1 12:00am" },
                        new object[] { "General Electric Company", 34.14, -0.08, -0.23, "9/1 12:00am" },
                        new object[] { "General Motors Corporation", 30.27, 1.09, 3.74, "9/1 12:00am" },
                        new object[] { "Hewlett-Packard Co.", 36.53, -0.03, -0.08, "9/1 12:00am" },
                        new object[] { "Honeywell Intl Inc", 38.77, 0.05, 0.13, "9/1 12:00am" },
                        new object[] { "Wal-Mart Stores, Inc.", 45.45, 0.73, 1.63, "9/1 12:00am" }
                   };
                return this.Store(results);
    
              
            }
    
    
        }
    }
    
    //index.cshtml
    @using Ext.Net;
    @using Ext.Net.MVC;
    
    @{
        Layout = null;
    }
    
    <!DOCTYPE html>
    
    <html>
    <head>
        <title>Ext.NET MVC Sample</title>    
    
    </head>
    <body>
        @(Html.X().ResourceManager())
    
        <header>
            <a href="http://ext.net/"><img src="http://speed.ext.net/identity/extnet-logo-large.png" class="logo"/></a>
        </header>
    
        @(
            Html.X().Desktop()
                .Modules(
                     Html.X().DesktopModule()
                        .ModuleID("add1-module")
                        .Shortcut(
                            Html.X().DesktopShortcut()
                                .Name("Render another module")
                                .Handler("OpenGridWin();")
                                .TextCls("x-long-label")
                        )
                )
                .DesktopConfig(
                     Html.X().DesktopConfig()
                        .ShortcutDragSelector(true)
                        .ShortcutDefaults(defaults =>
                        {
                            defaults.IconCls = "x-default-shortcut";
                        })
    
                )
    
    
        )
     
        <script>
           window.AppRoot = '@Url.Content("~")';
           var OpenGridWin = function (winId)
            {
                    Ext.net.DirectMethod.request({
                        url: window.AppRoot + 'FABHome/CreateWindow',
                        failure: function (result) {
                            Ext.Msg.alert("OnGridWindoError", result);
                            return false;
                        }
                    });
         
            }
    
        </script>
    </body>
    </html>
    
    //_GridWin.cshtml
    @{ 
        var X = Html.X();
    }
    
    @(
        X.DesktopModuleProxy()
            .Module(
                Html.X().DesktopModule().ModuleID("add1-module")
                    .AutoRun(true)
                    .Launcher(
                        Html.X().MenuItem()
                            .Icon(Icon.ApplicationEdit)
                    )
                    .Window(
                        Html.X().Window()
                            .Width(500)
                             .Height(500)
                             .Layout(LayoutType.Fit)
                             .CloseAction(CloseAction.Destroy) //won't keep state when it is open again
                             .Items(
                                 X.Panel()
                                  .ItemsFromAction("DataGridPanel")
                            ) // end items
                   )//end window
              ) //end module
    
    )
    
    //_DataGridPanel.cshtml
    
    
    @{
        var X = Html.X();
    }
    
    @(
     Html.X().GridPanel()
         .Frame(true).MultiColumnSort(true)
         .Store(
             X.Store().RemotePaging(false)
              .Model(
                 X.Model()
                    .Fields(
                            new ModelField("company"),
                            new ModelField("price", ModelFieldType.Float),
                            new ModelField("change", ModelFieldType.Float),
                            new ModelField("pctChange", ModelFieldType.Float),
                            new ModelField("lastChange", ModelFieldType.Date, "M/d hh:mmtt")
                        )
                    )
              .PageSize(20)
              .Proxy(
                   X.AjaxProxy()
                    .Reader(X.JsonReader().RootProperty("data").MessageProperty("message"))
                    .Url(Url.Action("LoadGridData"))
                )
            )
            .ColumnModel(
                    Html.X().Column().Text("Company").DataIndex("company")//.Locked(true)
                        .Editor(X.TextField()),
                    Html.X().Column().Text("Price").DataIndex("price").Renderer(RendererFormat.UsMoney)
                        .Editor(X.NumberField()),
                    Html.X().Column().Text("Change").DataIndex("change").Editor(X.NumberField()),
                    Html.X().Column().Text("Change").DataIndex("pctChange").Editor(X.NumberField()),
                    Html.X().DateColumn().Text("Last Updated").DataIndex("lastChange").Editor(X.DateField())
                )
            .TopBar(
                X.Toolbar()
                 .Items (
                    X.Button()
                     .Text("Toggle Filter Row")
                     .Handler("$('.x-column-header > .x-box-inner').slideToggle();")//("var header = this.up('grid').getView().mainHd; header.setDisplayed(!header.isVisible())"),
                                                                                    // ,X.LiveSearchToolbar().HideRegExp(true).HideCaseSensitive(true).SearchFieldWidth(100)
                 )
            )
            .BottomBar(X.PagingToolbar())
            .SelectionModel(X.SpreadsheetSelectionModel().RowSelect(true)) //add row number breaks grping,export,cell copy..
            .View(
                X.GridView()
                    .Listeners(ls =>
                    {
                        ls.Activate.Handler = "$('.x-column-header > .x-box-inner').slideToggle()";
                    })
            )
           .Plugins(
               X.CellEditing().ClicksToEdit(1)
            // ,X.LiveSearchGridPanel()
            //, X.FilterHeader().UpdateBuffer(2000) //delay checking input
            )
    
    )
    
    
  2. #2
    Hello Susan Zhang!

    The test case you provided is even a lot overkill to reproduce just that bug, but I understand it is a small change given your last report. Nevertheless it could have been much faster to reproduce the issue with a clean sample.

    I narrowed down the test case for this webforms equivalent that reproduces the issue. No desktop/dynamic modules are necessary at all:

    <%@ Page Language="C#" %>
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!X.IsAjaxRequest)
            {
                this.Store1.DataSource = this.Data;
            }
        }
    
        private object[] Data
        {
            get
            {
                return new object[]
                {
                    new object[] { "3m Co", 71.72, 0.02, 0.03, "9/1 12:00am" },
                    new object[] { "Alcoa Inc", 29.01, 0.42, 1.47, "9/1 12:00am" },
                };
            }
        }
    </script>
    
    <!DOCTYPE html>
    
    <html>
    <head runat="server">
        <title>61846 - GridPanel w/ headers not following tab keynav horizontal scrolling</title>
    </head>
    <body>
        <ext:ResourceManager runat="server" />
    
        <h1><a href="https://forums.ext.net/showthread.php?61846">61846</a> - GridPanel w/ headers not following tab keynav horizontal scrolling</h1>
    
        <p>
            To reproduce the issue, start editing '3m co' and tab until it wraps to the next line. Affected browser: Chrome 57. (firefox also has some glitches)
            <br />
            This is also <a href="https://fiddle.sencha.com/#view/editor&fiddle/1ti3">reproducible in ExtJS 6.2.1</a>.
        </p>
        <ext:GridPanel
            ID="GridPanel1"
            runat="server"
            Title="Grid"
            Frame="true"
            Width="500"
            Height="350">
            <Store>
                <ext:Store ID="Store1" runat="server">
                    <Model>
                        <ext:Model runat="server">
                            <Fields>
                                <ext:ModelField Name="company" />
                                <ext:ModelField Name="price" Type="Float" />
                                <ext:ModelField Name="change" Type="Float" />
                                <ext:ModelField Name="pctChange" Type="Float" />
                                <ext:ModelField Name="lastChange" Type="Date" DateFormat="M/d hh:mmtt" />
                            </Fields>
                        </ext:Model>
                    </Model>
                </ext:Store>
            </Store>
            <ColumnModel>
                <Columns>
                    <ext:Column runat="server" Text="Company" DataIndex="company" Width="200">
                        <Editor>
                            <ext:TextField runat="server" />
                        </Editor>
                    </ext:Column>
                    <ext:Column runat="server" Text="Price" DataIndex="price" Width="100" >
                        <Editor>
                            <ext:TextField runat="server" />
                        </Editor>
                    </ext:Column>
                    <ext:Column runat="server" Text="Change" DataIndex="change" Width="100">
                        <Editor>
                            <ext:TextField runat="server" />
                        </Editor>
                    </ext:Column>
                    <ext:Column runat="server" Text="Change" DataIndex="pctChange" Width="100" >
                        <Editor>
                            <ext:TextField runat="server" />
                        </Editor>
                    </ext:Column>
                    <ext:DateColumn runat="server" Text="Last Updated" DataIndex="lastChange" Width="120">
                        <Editor>
                            <ext:DateField runat="server" />
                        </Editor>
                    </ext:DateColumn>
                </Columns>
            </ColumnModel>
            <SelectionModel>
                <ext:SpreadsheetSelectionModel runat="server" RowSelect="true" />
            </SelectionModel>
            <Plugins>
                <ext:CellEditing runat="server" ClicksToEdit="1" />
                
                <%-- Using RowEditing the issue cannot be reproduced. --%>
                <%--<ext:RowEditing runat="server" ClicksToEdit="1" />--%>
            </Plugins>
        </ext:GridPanel>
    </body>
    </html>
    We've reproduced this on ExtJS as well, the issue is reproducible as described using chrome 57 only. No issues when using IE, but there are smaller issues if using Firefox 52.0.1 (the field does not focus correctly and scrollbar does not reflect the actual scroll position of the grid).

    We have logged this issue under #1464.

    Of course, you want a way to get up and running the sooner, the better. I can suggest you switching for the row editing plug in (X.RowEditing().ClicksToEdit(1)).

    Unfortunately it might take some more effort to patch or give an workaround for the cellediting plugin. Basically a workaround would consist of binding the Edit or BeforeEdit event (listener) to double check and sync the vertical scroll between grid view's column headers with contents.

    I hope this helps!
    Last edited by fabricio.murta; Apr 06, 2017 at 5:02 AM.
  3. #3
    Hi Fabricio, Thanks for your info! We are using Chrome 56. I am not sure if we can change from cell to row editing(don't remember the initial requirements) but like to try. After switch to row editing, it works fine without locking column. Using my example, set first column locked. I got following error by clicking on any columns. Please help!

    (Sorry I do not have time to try it on your simplified sample code this time.)

    Uncaught TypeError: Cannot read property 'getView' of null
    at F.onCellSelect (ext.axd?v=4.2.0:19)
    at F.setRangeEnd (ext.axd?v=4.2.0:19)
    at F.selectCells (ext.axd?v=4.2.0:19)
    at F.callParent (ext.axd?v=4.2.0:19)
    at F.selectCells (ext.axd?v=4.2.0:1533)
    at F.selectByPosition (ext.axd?v=4.2.0:19)
    at F.startEdit (ext.axd?v=4.2.0:19)
    at F.startEdit (ext.axd?v=4.2.0:19)
    at F.activateCell (ext.axd?v=4.2.0:19)
    at F.activateCell (ext.axd?v=4.2.0:19)
  4. #4
    With IE (11) when column lock enabled, I saw same issue with cell editing. If no column locked, event the header can line up with data but the line number disappeared after tabbing to the next line. Can you reproduce these on your side?
  5. #5
    Hello Susan! I could reproduce the issues you said.

    Well, if column locking is not required, something fairly simple you can do to circumvent the issue is making your panel fit the columns width (so that it never shows an horizontal scrollbar). It can still handle vertical scrolling.

    Then you wrap your panel inside a container with .Scrollable(Scrollable.Horizontal).

    From the WebForms sample, the example above would be turned into:

    <%@ Page Language="C#" %>
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!X.IsAjaxRequest)
            {
                this.Store1.DataSource = this.Data;
            }
        }
    
        private object[] Data
        {
            get
            {
                return new object[]
                {
                    new object[] { "3m Co", 71.72, 0.02, 0.03, "9/1 12:00am" },
                    new object[] { "Alcoa Inc", 29.01, 0.42, 1.47, "9/1 12:00am" },
                };
            }
        }
    </script>
    
    <!DOCTYPE html>
    
    <html>
    <head runat="server">
        <title>61846 - GridPanel w/ headers not following tab keynav horizontal scrolling</title>
    </head>
    <body>
        <ext:ResourceManager runat="server" />
    
        <h1><a href="https://forums.ext.net/showthread.php?61846">61846</a> - GridPanel w/ headers not following tab keynav horizontal scrolling</h1>
    
        <p>
            To reproduce the issue, start editing '3m co' and tab until it wraps to the next line. Affected browser: Chrome 57. (firefox also has some glitches)
            <br />
            This is also <a href="https://fiddle.sencha.com/#view/editor&fiddle/1ti3">reproducible in ExtJS 6.2.1</a>.
            <br />
            The "workaround" suggested here is wrap the grid panel on a container, force the grid panel to fit all shown columns so that the outer container scrolls instead.
        </p>
        <ext:Container
            runat="server"
            Scrollable="Horizontal"
            Height="400"
            StyleSpec="border:1px solid red"
            Width="500"
            >
            <Items>
                <ext:GridPanel
                    ID="GridPanel1"
                    runat="server"
                    Title="Grid"
                    Frame="true"
                    Width="670"
                    Height="350">
                    <Store>
                        <ext:Store ID="Store1" runat="server">
                            <Model>
                                <ext:Model runat="server">
                                    <Fields>
                                        <ext:ModelField Name="company" />
                                        <ext:ModelField Name="price" Type="Float" />
                                        <ext:ModelField Name="change" Type="Float" />
                                        <ext:ModelField Name="pctChange" Type="Float" />
                                        <ext:ModelField Name="lastChange" Type="Date" DateFormat="M/d hh:mmtt" />
                                    </Fields>
                                </ext:Model>
                            </Model>
                        </ext:Store>
                    </Store>
                    <ColumnModel>
                        <Columns>
                            <ext:Column runat="server" Text="Company" DataIndex="company" Width="200">
                                <Editor>
                                    <ext:TextField runat="server" />
                                </Editor>
                            </ext:Column>
                            <ext:Column runat="server" Text="Price" DataIndex="price" Width="100" >
                                <Editor>
                                    <ext:TextField runat="server" />
                                </Editor>
                            </ext:Column>
                            <ext:Column runat="server" Text="Change" DataIndex="change" Width="100">
                                <Editor>
                                    <ext:TextField runat="server" />
                                </Editor>
                            </ext:Column>
                            <ext:Column runat="server" Text="Change" DataIndex="pctChange" Width="100" >
                                <Editor>
                                    <ext:TextField runat="server" />
                                </Editor>
                            </ext:Column>
                            <ext:DateColumn runat="server" Text="Last Updated" DataIndex="lastChange" Width="120">
                                <Editor>
                                    <ext:DateField runat="server" />
                                </Editor>
                            </ext:DateColumn>
                        </Columns>
                    </ColumnModel>
                    <SelectionModel>
                        <ext:SpreadsheetSelectionModel runat="server" RowSelect="true">
                        </ext:SpreadsheetSelectionModel>
                    </SelectionModel>
                    <Plugins>
                        <ext:CellEditing runat="server" ClicksToEdit="1" />
                
                        <%-- Using RowEditing the issue cannot be reproduced. --%>
                        <%--<ext:RowEditing runat="server" ClicksToEdit="1" />--%>
                    </Plugins>
                </ext:GridPanel>
            </Items>
        </ext:Container>
    </body>
    </html>
    But well, if column locking is required then this wouldn't help at all. It would require us some time to investigate and get down to a solution or workaround to keep the header columns synced as this is a pretty particular case (spreadsheet + cellediting + using 'tab' key to cycle thru cells).
    Fabrício Murta
    Developer & Support Expert
  6. #6
    And this would likely be what best fits both locking or non-locking approaches:

    <%@ Page Language="C#" %>
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!X.IsAjaxRequest)
            {
                this.Store1.DataSource = this.Data;
            }
        }
    
        private object[] Data
        {
            get
            {
                return new object[]
                {
                    new object[] { "3m Co", 71.72, 0.02, 0.03, "9/1 12:00am" },
                    new object[] { "Alcoa Inc", 29.01, 0.42, 1.47, "9/1 12:00am" },
                };
            }
        }
    </script>
    
    <!DOCTYPE html>
    
    <html>
    <head runat="server">
        <title>61846 - GridPanel w/ headers not following tab keynav horizontal scrolling</title>
        <script type="text/javascript">
            function fixScrolling(item, e) {
                if (item.grid) {
                    var grid = item.grid,
                        header = grid.headerCt;
    
                    // for grid with locking enabled
                    if (item.grid.normalGrid) {
                        grid = item.grid.normalGrid,
                        header = grid.headerCt;
                    }
    
                    if (grid.getScrollX() != header.getScrollX()) {
                        header.scrollTo(grid.getScrollX());
                    }
                }
            }
        </script>
    </head>
    <body>
        <ext:ResourceManager runat="server" />
    
        <h1><a href="https://forums.ext.net/showthread.php?61846">61846</a> - GridPanel w/ headers not following tab keynav horizontal scrolling</h1>
    
        <p>
            To reproduce the issue, start editing '3m co' and tab until it wraps to the next line. Affected browser: Chrome 57. (firefox also has some glitches)
            <br />
            This is also <a href="https://fiddle.sencha.com/#view/editor&fiddle/1ti3">reproducible in ExtJS 6.2.1</a>.
            <br />
            The "workaround" suggested here keeps checking scroll position every time a field edit is about to start, fixing the position if it is not in sync.
        </p>
        <ext:GridPanel
            ID="GridPanel1"
            runat="server"
            Title="Grid"
            Frame="true"
            Width="500"
            Height="350">
            <Store>
                <ext:Store ID="Store1" runat="server">
                    <Model>
                        <ext:Model runat="server">
                            <Fields>
                                <ext:ModelField Name="company" />
                                <ext:ModelField Name="price" Type="Float" />
                                <ext:ModelField Name="change" Type="Float" />
                                <ext:ModelField Name="pctChange" Type="Float" />
                                <ext:ModelField Name="lastChange" Type="Date" DateFormat="M/d hh:mmtt" />
                            </Fields>
                        </ext:Model>
                    </Model>
                </ext:Store>
            </Store>
            <ColumnModel>
                <Columns>
                    <ext:Column runat="server" Text="Company" DataIndex="company" Width="200">
                        <Editor>
                            <ext:TextField runat="server" />
                        </Editor>
                    </ext:Column>
                    <ext:Column runat="server" Text="Price" DataIndex="price" Width="100" >
                        <Editor>
                            <ext:TextField runat="server" />
                        </Editor>
                    </ext:Column>
                    <ext:Column runat="server" Text="Change" DataIndex="change" Width="100">
                        <Editor>
                            <ext:TextField runat="server" />
                        </Editor>
                    </ext:Column>
                    <ext:Column runat="server" Text="Change" DataIndex="pctChange" Width="100" >
                        <Editor>
                            <ext:TextField runat="server" />
                        </Editor>
                    </ext:Column>
                    <ext:DateColumn runat="server" Text="Last Updated" DataIndex="lastChange" Width="120">
                        <Editor>
                            <ext:DateField runat="server" />
                        </Editor>
                    </ext:DateColumn>
                </Columns>
            </ColumnModel>
            <SelectionModel>
                <ext:SpreadsheetSelectionModel runat="server" >
                </ext:SpreadsheetSelectionModel>
            </SelectionModel>
            <Plugins>
                <ext:CellEditing runat="server" ClicksToEdit="1">
                    <Listeners>
                        <BeforeEdit Fn="fixScrolling" />
                    </Listeners>
                </ext:CellEditing>
                
            </Plugins>
        </ext:GridPanel>
    </body>
    </html>
    Although on IE there's an annoying "invisible" scrollbar still while cellEditing is enabled, it works much better on both Chrome and IE with that workaround to keep syncing scrollbars.

    Hope this helps for the time being!
    Fabrício Murta
    Developer & Support Expert
  7. #7
    Hi Fabricio, Thank you so much! I will try your last solution and let you know. Locking is required for us and many grids have 10 - 20 columns.
    Thanks
    -szhang
  8. #8
    Hi Fabricio, It works! Really appreciate all your efforts!
    Thank you
    -szhang
  9. #9
    Hello Susan Zhang!

    Thanks for the feedback! Glad it works for you for the time being!
    Fabrício Murta
    Developer & Support Expert

Similar Threads

  1. Replies: 4
    Last Post: Dec 01, 2015, 4:13 PM
  2. Replies: 4
    Last Post: Jul 01, 2015, 4:03 PM
  3. Replies: 9
    Last Post: Nov 13, 2014, 6:54 AM
  4. Replies: 1
    Last Post: Nov 24, 2011, 6:48 AM
  5. Replies: 16
    Last Post: Feb 23, 2011, 10:03 AM

Posting Permissions