[FIXED] [#1290] [3.3.0/4.0.0-beta] Maintain GridPanel Scroll position after refresh

  1. #1

    [FIXED] [#1290] [3.3.0/4.0.0-beta] Maintain GridPanel Scroll position after refresh

    Hello,

    I have a gridpanel with refresh button . the gridpanel has a vertical scroll.
    On refresh scroll position is set to top. I want to save the position where the scroll is and on refresh stay at this position.
    Note that I tried InvalidateScrollerOnRefresh="false" and ReserveScrollbar="false" and it doesn't work.
    Here is the sample code.

    aspx Page:
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></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 + "%");
          }
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
         <ext:ResourceManager ID="ResourceManager1" runat="server" ShowWarningOnAjaxFailure="false"/>
    
    
                <ext:GridPanel ID="GridPanel1" runat="server" Title="Vertical Scroll Test" InvalidateScrollerOnRefresh="false" Height="200" >
                   <Store>
                    <ext:Store ID="Store1" runat="server" PageSize="15">
                        <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="Size" />
                                    <ext:ModelField Name="lastChange" Type="Date" DateFormat="M/d hh:mmtt" />
                                    <ext:ModelField Name="industry" />
                                    <ext:ModelField Name="desc" />
                                </Fields>
                            </ext:Model>
                        </Model>
                    </ext:Store>
                </Store>
                    <ColumnModel runat="server">
                        <Columns>
                            <ext:Column ID="CompanyColumn" runat="server" Text="Company" DataIndex="company" Flex="1">
                                <Filter>
                                    <ext:StringFilter />
                                </Filter>
                            </ext:Column>
                            <ext:Column runat="server" Text="Price" DataIndex="Price">
                                <Renderer Format="UsMoney" />
                                <Filter>
                                    <ext:NumberFilter />
                                </Filter>
                            </ext:Column>
                            <ext:Column runat="server" Text="Change" DataIndex="change">
                            <Renderer Fn="change" />
                            </ext:Column>
                            <ext:Column runat="server" Text="Size" DataIndex="Size">
                                <Filter>
                                    <ext:ListFilter DataIndex="Size"/>
                                </Filter>
                            </ext:Column>
                            <ext:DateColumn runat="server" Text="Date" DataIndex="lastChange" Align="Center" Format="M/d hh:mmtt">
                                <Filter>
                                    <ext:DateFilter>
                                        <DatePickerOptions runat="server" TodayText="Now" />
                                    </ext:DateFilter>
                                </Filter>
                            </ext:DateColumn>
                               <ext:Column runat="server" Text="industry" DataIndex="industry">
                                <Filter>
                                    <ext:ListFilter DataIndex="industry"/>
                                </Filter>
                            </ext:Column>
                        </Columns>
                    </ColumnModel>
                    <Plugins>
                        <ext:GridFilters runat="server" />
                    </Plugins>
                    <BottomBar>
                        <ext:PagingToolbar runat="server"  RefreshHandler="App.direct.RefreshGrid();">
                
                        </ext:PagingToolbar>
                    </BottomBar>
                </ext:GridPanel>
    
    
        </form>
    </body>
    </html>
    Code behind (cs):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Ext.Net;
    
    namespace FFMS
    {
        public partial class FilterTest : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                if (!X.IsAjaxRequest)
                {
                    this.Store1.DataSource = new object[]
                {
                    new object[] { "3m Co", 71.72, 0.02, "Large", "9/1 12:00am", "Manufacturing" },
                    new object[] { "Alcoa Inc", 29.01, 0.42, "Extra-Large", "9/1 12:00am", "Manufacturing" },
                    new object[] { "Altria Group Inc", 83.81, 0.28, "small", "9/1 12:00am", "Manufacturing" },
                    new object[] { "American Express Company", 52.55, 0.01, "Large", "9/1 12:00am", "Finance" },
                    new object[] { "American International Group, Inc.", 64.13, 0.31, "Large", "9/1 12:00am", "Services" },
                    new object[] { "AT&T Inc.", 31.61, -0.48, "small", "9/1 12:00am", "Services" },
                    new object[] { "Boeing Co.", 75.43, 0.53, "Large", "9/1 12:00am", "Manufacturing" },
                    new object[] { "Caterpillar Inc.", 67.27, 0.92, "Large", "9/1 12:00am", "Services" },
                    new object[] { "Citigroup, Inc.", 49.37, 0.02, "Extra-Large", "9/1 12:00am", "Finance" },
                    new object[] { "E.I. du Pont de Nemours and Company", 40.48, 0.51, "Extra-Large", "9/1 12:00am", "Manufacturing" },
                    new object[] { "Exxon Mobil Corp", 68.1, -0.43, "small", "9/1 12:00am", "Manufacturing" },
                    new object[] { "General Electric Company", 34.14, -0.08, "small", "9/1 12:00am", "Manufacturing" },
                    new object[] { "General Motors Corporation", 30.27, 1.09, "Large", "9/1 12:00am", "Automotive" },
                    new object[] { "Hewlett-Packard Co.", 36.53, -0.03, "small", "9/1 12:00am", "Computer" },
                    new object[] { "Honeywell Intl Inc", 38.77, 0.05, "medium", "9/1 12:00am", "Manufacturing" },
                    new object[] { "Intel Corporation", 19.88, 0.31, "Large", "9/1 12:00am", "Computer" },
                    new object[] { "International Business Machines", 81.41, 0.44, "medium", "9/1 12:00am", "Computer" },
                    new object[] { "Johnson & Johnson", 64.72, 0.06, "small", "9/1 12:00am", "Medical" },
                    new object[] { "JP Morgan & Chase & Co", 45.73, 0.07, "small", "9/1 12:00am", "Finance" },
                    new object[] { "McDonald\"s Corporation", 36.76, 0.86, "Large", "9/1 12:00am", "Food" },
                    new object[] { "Merck & Co., Inc.", 40.96, 0.41, "Large", "9/1 12:00am", "Medical" },
                    new object[] { "Microsoft Corporation", 25.84, 0.14, "medium", "9/1 12:00am", "Computer" },
                    new object[] { "Pfizer Inc", 27.96, 0.4, "Large", "9/1 12:00am", "Medical" },
                    new object[] { "The Coca-Cola Company", 45.07, 0.26, "Large", "9/1 12:00am", "Food" },
                    new object[] { "The Home Depot, Inc.", 34.64, 0.35, "Large", "9/1 12:00am", "Retail" },
                    new object[] { "The Procter & Gamble Company", 61.91, 0.01, "small", "9/1 12:00am", "Manufacturing" },
                    new object[] { "United Technologies Corporation", 63.26, 0.55, "medium", "9/1 12:00am", "Computer" },
                    new object[] { "Verizon Communications", 35.57, 0.39, "Large", "9/1 12:00am", "Services" },
                    new object[] { "Wal-Mart Stores, Inc.", 45.45, 0.73, "Large", "9/1 12:00am", "Retail" }
                };
    
                    this.Store1.DataBind();
                }
            }
    
    
    
            [DirectMethod]
            public void RefreshGrid()
            {
                 this.Store1.DataSource = new object[]
                {
                    new object[] { "New Company 1", 11.52, 0.1, "Large", "9/1 12:00am", "Manufacturing" },
                    new object[] { "New Company 2", 71.72, 0.02, "small", "9/1 12:00am", "Computer" },
                    new object[] { "New Company 3", 54.72, 5.4, "Extra-Large", "9/1 12:00am", "Manufacturing" },
                    new object[] { "3m Co", 71.72, 0.02, "Large", "9/1 12:00am", "Manufacturing" },
                    new object[] { "Alcoa Inc", 29.01, 0.42, "Extra-Large", "9/1 12:00am", "Manufacturing" },
                    new object[] { "Altria Group Inc", 83.81, 0.28, "small", "9/1 12:00am", "Manufacturing" },
                    new object[] { "American Express Company", 52.55, 0.01, "Large", "9/1 12:00am", "Finance" },
                    new object[] { "American International Group, Inc.", 64.13, 0.31, "Large", "9/1 12:00am", "Services" },
                    new object[] { "AT&T Inc.", 31.61, -0.48, "small", "9/1 12:00am", "Services" },
                    new object[] { "Boeing Co.", 75.43, 0.53, "Large", "9/1 12:00am", "Manufacturing" },
                    new object[] { "Caterpillar Inc.", 67.27, 0.92, "Large", "9/1 12:00am", "Services" },
                    new object[] { "Citigroup, Inc.", 49.37, 0.02, "Extra-Large", "9/1 12:00am", "Finance" },
                    new object[] { "E.I. du Pont de Nemours and Company", 40.48, 0.51, "Extra-Large", "9/1 12:00am", "Manufacturing" },
                    new object[] { "Exxon Mobil Corp", 68.1, -0.43, "small", "9/1 12:00am", "Manufacturing" },
                    new object[] { "General Electric Company", 34.14, -0.08, "small", "9/1 12:00am", "Manufacturing" },
                    new object[] { "General Motors Corporation", 30.27, 1.09, "Large", "9/1 12:00am", "Automotive" },
                    new object[] { "Hewlett-Packard Co.", 36.53, -0.03, "small", "9/1 12:00am", "Computer" },
                    new object[] { "Honeywell Intl Inc", 38.77, 0.05, "medium", "9/1 12:00am", "Manufacturing" },
                    new object[] { "Intel Corporation", 19.88, 0.31, "Large", "9/1 12:00am", "Computer" },
                    new object[] { "International Business Machines", 81.41, 0.44, "medium", "9/1 12:00am", "Computer" },
                    new object[] { "Johnson & Johnson", 64.72, 0.06, "small", "9/1 12:00am", "Medical" },
                    new object[] { "JP Morgan & Chase & Co", 45.73, 0.07, "small", "9/1 12:00am", "Finance" },
                    new object[] { "McDonald\"s Corporation", 36.76, 0.86, "Large", "9/1 12:00am", "Food" },
                    new object[] { "Merck & Co., Inc.", 40.96, 0.41, "Large", "9/1 12:00am", "Medical" },
                    new object[] { "Microsoft Corporation", 25.84, 0.14, "medium", "9/1 12:00am", "Computer" },
                    new object[] { "Pfizer Inc", 27.96, 0.4, "Large", "9/1 12:00am", "Medical" },
                    new object[] { "The Coca-Cola Company", 45.07, 0.26, "Large", "9/1 12:00am", "Food" },
                    new object[] { "The Home Depot, Inc.", 34.64, 0.35, "Large", "9/1 12:00am", "Retail" },
                    new object[] { "The Procter & Gamble Company", 61.91, 0.01, "small", "9/1 12:00am", "Manufacturing" },
                    new object[] { "United Technologies Corporation", 63.26, 0.55, "medium", "9/1 12:00am", "Computer" },
                    new object[] { "Verizon Communications", 35.57, 0.39, "Large", "9/1 12:00am", "Services" },
                    new object[] { "Wal-Mart Stores, Inc.", 45.45, 0.73, "Large", "9/1 12:00am", "Retail" }
                };
    
                    this.Store1.DataBind();
                
            }
    
    
        }
    }
    Attached Thumbnails Click image for larger version. 

Name:	ScrollafterRefresh.png 
Views:	60 
Size:	30.3 KB 
ID:	24490   Click image for larger version. 

Name:	ScrollbeforeRefresh.png 
Views:	71 
Size:	26.7 KB 
ID:	24491  
    Last edited by fabricio.murta; Mar 22, 2016 at 8:41 PM.
  2. #2
    Hello @Geovision!

    Thanks for the runnable example, I could easily identify the issue. But as for the answer, it may not be perfect in your case.

    The problem is that there are new entries in the panel so, if I scrolled 50 pixels before refresh, the entries displayed 50 scroll pixels after refresh will not be the same, as the entries are on top. This is rather a limitation and not a problem, as scrolling is not record-oriented, but pixels-oriented.

    But this should do good in the average if the data is not changing too much and too often.

    Add this script to your page (between lines 7-17):
          var handleRefresh = function () {
              App.GridPanel1.view.saveScrollState();
              App.direct.RefreshGrid({ success: handleScrollPos } );
          }
    
          var handleScrollPos = function () {
              App.GridPanel1.view.restoreScrollState();
          }
    And then use handleRefresh as refresh handler on your paging config (line 81):
    <ext:PagingToolbar runat="server" RefreshHandler="handleRefresh();" />
    I hope this helps!
    Fabrício Murta
    Developer & Support Expert
  3. #3

    Slowness on IE

    Hello,

    i have implemented the below and using IE i can see a blur "slowness" to reset the Scroll to its position to its location while in Chrome its very smooth and very fast.

    in general the IE is a bit slower than Chrome (when applying a grid filters etc..) and i don't know if this is a generic issue.
  4. #4
    Hello @Geovision!

    I didn't notice an actual slowness in IE11 on the example you provided, but indeed we can see the scroll briefly shows on top before it is readjusted.

    I am afraid that's a IE11 quirk. It probably needs an interval between loading actual data (so scroller is updated to its actual length) and effectively scrolling.

    What you can do to mask this is literally using a load mask when the user clicks 'refresh'. For that, add the mask before the direct event is called and remove the mask when the success (or failure) callback is run.

    I hope this helps!
    Fabrício Murta
    Developer & Support Expert
  5. #5
    Hello,

    is there any suggestion that the scroll in the grid doesn't show briefly on top before it is readjusted in IE?
    This problem persist in IE if using signalR instead of re-configuring the gridpanel ??

    thank you
  6. #6
    Hello @Geovision!

    About the SignalR approach, it does not seem to scroll at all when entries are updated. Check it out here:
    SignalR Stock Ticker example using Ext.NET by Anup.

    I tried here just reducing the height of the panel so only two entries are visible, and scrolled a little down. Even when a row were added, no scrolling happened in IE.

    I will give a little more tries with the current example to see if I can bypass the flicker-on-refresh on IE.
    Fabrício Murta
    Developer & Support Expert
  7. #7
    Okay, seems I found a very nice solution for the problem!..

    From your original sample code, just add the following line inside your grid definition:
    <ViewConfig PreserveScrollOnReload="true" />

    You should have the scroll being preserved nicely from that point on. Please don't mind a possible green squiggle on the PreserveScrollOnReload word in your .aspx view when in Visual Studio. This option was recently introduced and didn't make it in Ext.NET intellisense. For that, we've logged issue #1290 to address this missing part.

    But the line should work on your page despite this with no changes to Ext.NET or code behind.
    Fabrício Murta
    Developer & Support Expert
  8. #8
    Hello! We just implemented this on Ext.Net 3! It is available on our latest SVN revision, 6763, if you want to use it.

    Also, this fix made it out to the just-released Ext.Net 4-rc!
    Fabrício Murta
    Developer & Support Expert

Similar Threads

  1. Replies: 11
    Last Post: Jan 13, 2017, 1:27 AM
  2. Maintain Scroll Position in a Panel
    By Uziel in forum 1.x Help
    Replies: 0
    Last Post: Mar 16, 2016, 3:33 PM
  3. Replies: 11
    Last Post: Aug 06, 2013, 5:29 AM
  4. Maintain scroll position in dataview
    By dotnet in forum 1.x Help
    Replies: 0
    Last Post: Jan 28, 2013, 10:10 AM
  5. [CLOSED] Maintain scroll position in Ext.NET
    By skyone in forum 1.x Legacy Premium Help
    Replies: 1
    Last Post: Jul 27, 2010, 12:15 PM

Posting Permissions