[CLOSED] Buffered Grid Scrolling repeats rows

Page 1 of 2 12 LastLast
  1. #1

    [CLOSED] Buffered Grid Scrolling repeats rows

    Hello,
    I have a buffered grid with both remote sort and filter that I'm getting a strange behavior when scrolling down the grid that I'll try to explain clearly, I'm including an example that shows the behavior. In the example PageSize is set to 100 and when I start scrolling down the grid when I get to about row #125 it seems to lose it's place and the data in the row starts repeating rows from the beginning of the grid, but the row number keeps incrementing normally. If you keep scrolling the next approx. 125 rows it will happen again. Changing the PageSize changes when it happens, so if I set PageSize to 150, it will start repeating around row #175. I've tried playing with other properties like the Buffer Zones but I can't seem to pinpoint what I'm doing wrong. I'm using version 2.1.1 in VS2010 w/.NET 4.0, see it in both IE8 and Chrome. Thanks in advance.

    JW

    <%@ Page Language="C#"%>
    <%@ Register Assembly="Ext.NET" Namespace="Ext.Net" TagPrefix="ext" %>
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!X.IsAjaxRequest)
            {
                this.Store1.DataSource = this.dynData;
            }
        }
        private List<object> dynData
        {
            get
            {
                List<object> comps = new List<object> { };
                
                for (int i = 0; i < 500; i++)
                {
                    comps.Add(new {company = "Company " + i, price = 71.72, change = 0.02, pctChange = 0.03, lastCahnge = new DateTime(2013, 9, 1) });
                }
                
                return comps;
            }
        }
        protected void Store1_RefreshData(object sender, StoreReadDataEventArgs e)
        {
            List<object> data = this.dynData;
            string s = e.Parameters[this.GridFilters1.ParamPrefix];
            //-- start filtering ------------------------------------------------------------
            if (!string.IsNullOrEmpty(s))
            {
                FilterConditions fc = new FilterConditions(s);
    
                foreach (FilterCondition condition in fc.Conditions)
                {
                    Comparison comparison = condition.Comparison;
                    string field = condition.Field;
                    FilterType type = condition.Type;
    
                    object value;
                    switch (condition.Type)
                    {
                        case FilterType.Boolean:
                            value = condition.Value<bool>();
                            break;
                        case FilterType.Date:
                            value = condition.Value<DateTime>();
                            break;
                        case FilterType.List:
                            value = condition.List;
                            break;
                        case FilterType.Numeric:
                            if (data.Count > 0 && data[0].GetType().GetProperty(field).PropertyType == typeof(int))
                            {
                                value = condition.Value<int>();
                            }
                            else
                            {
                                value = condition.Value<double>();
                            }
    
                            break;
                        case FilterType.String:
                            value = condition.Value<string>();
                            break;
                        default:
                            throw new ArgumentOutOfRangeException();
                    }
    
                    data.RemoveAll(
                        item =>
                        {
                            object oValue = item.GetType().GetProperty(field).GetValue(item, null);
                            IComparable cItem = oValue as IComparable;
    
                            switch (comparison)
                            {
                                case Comparison.Eq:
    
                                    switch (type)
                                    {
                                        case FilterType.List:
                                            return !(value as List<string>).Contains(oValue.ToString());
                                        case FilterType.String:
                                            return !oValue.ToString().StartsWith(value.ToString());
                                        default:
                                            return !cItem.Equals(value);
                                    }
    
                                case Comparison.Gt:
                                    return cItem.CompareTo(value) < 1;
                                case Comparison.Lt:
                                    return cItem.CompareTo(value) > -1;
                                default:
                                    throw new ArgumentOutOfRangeException();
                            }
                        }
                    );
                }
            }
            //-- end filtering ------------------------------------------------------------
            //-- start sorting ------------------------------------------------------------
            if (e.Sort.Length > 0)
            {
                data.Sort(delegate(object x, object y)
                {
                    object a;
                    object b;
    
                    int direction = e.Sort[0].Direction == Ext.Net.SortDirection.DESC ? -1 : 1;
    
                    a = x.GetType().GetProperty(e.Sort[0].Property).GetValue(x, null);
                    b = y.GetType().GetProperty(e.Sort[0].Property).GetValue(y, null);
                    return CaseInsensitiveComparer.Default.Compare(a, b) * direction;
                });
            }
            //-- end sorting ------------------------------------------------------------
            this.GridPanel1.GetStore().DataSource = data;
        }
        protected void Button1_Click(object sender, DirectEventArgs e)
        {
            RowSelectionModel selRows = GridPanel1.GetSelectionModel() as RowSelectionModel;
            this.Store1.DataSource = this.dynData;
            selRows.ClearSelection();
        }
    </script>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
        <title></title>
        <script type="text/javascript">
            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="ExtResourceManager" runat="server" DisableViewState="false" RenderStyles="Embedded"></ext:ResourceManager>
        <ext:GridPanel ID="GridPanel1" runat="server" Title="Sample Grid" Width="650" Height="350" EnableColumnMove="false">
            <Store>
                <ext:Store ID="Store1" runat="server" Buffered="true" PageSize="100" RemoteSort="true"
                            RemoteFilter="true" OnReadData="Store1_RefreshData" LeadingBufferZone="50" TrailingBufferZone="50">
                    <Proxy>
                        <ext:PageProxy/>
                    </Proxy>
                    <Model>
                        <ext:Model ID="Model1" 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 OverflowY="Auto">
                <Columns>
                    <ext:RowNumbererColumn Width="50"></ext:RowNumbererColumn>
                    <ext:Column ID="Column1" runat="server" Text="Company" DataIndex="company" Flex="1" />
                    <ext:Column ID="Column2" runat="server" Text="Price" DataIndex="price">                  
                        <Renderer Format="UsMoney" />
                    </ext:Column>
                    <ext:Column ID="Column3" runat="server" Text="Change" DataIndex="change">
                        <Renderer Fn="change" />
                    </ext:Column>
                    <ext:Column ID="Column4" runat="server" Text="Change" DataIndex="pctChange">
                        <Renderer Fn="pctChange" />
                    </ext:Column>
                    <ext:DateColumn ID="DateColumn1" runat="server" Text="Last Updated" DataIndex="lastChange" />
                </Columns>            
            </ColumnModel>       
            <SelectionModel>
                <ext:CheckboxSelectionModel ID="CheckboxSelectionModel1" runat="server" Mode="Single" AllowDeselect="true" ShowHeaderCheckbox="false"></ext:CheckboxSelectionModel>
            </SelectionModel>
            <Features>
                <ext:GridFilters ID="GridFilters1" runat="server" Local="false" Enabled="true">
                    <Filters>
                        <ext:StringFilter DataIndex="company"></ext:StringFilter>
                    </Filters>
                </ext:GridFilters>
            </Features>
        </ext:GridPanel>
        </form>
    </body>
    </html>
    Last edited by Daniil; Feb 09, 2013 at 5:49 AM. Reason: [CLOSED]
  2. #2
    Hello!

    Try to set the following:

    <ext:Store ID="Store1" runat="server" Buffered="true" PageSize="500" RemoteSort="true"
                            RemoteFilter="true" OnReadData="Store1_RefreshData">
    ...
    </ext:Store>
  3. #3
    Quote Originally Posted by Baidaly View Post
    Hello!

    Try to set the following:

    <ext:Store ID="Store1" runat="server" Buffered="true" PageSize="500" RemoteSort="true"
                            RemoteFilter="true" OnReadData="Store1_RefreshData">
    ...
    </ext:Store>
    Hi Baidaly,
    Setting that PageSize works only for this test example I created where I'm specifically setting the #rows to 500, you're basically turning off buffering. In my actual application the number of rows is dynamic and could have serveral thousand rows and I want to buffer the grid for perfomance purposes. If I set Buffered=false it works fine as well, so there's something going on when it's buffered and the grid goes to load the next page it's not keeping it's place on the datasource?

    JW
  4. #4
    I tested your sample with latest code (from SVN trunk) and I cannot reproduce such behaviour. Can you update from SVN trunk and retest?
    Vladimir Shcheglov
    Sr. Developer
  5. #5
    Hi Vladimir,
    I downloaded the current source and now my example page works. I did however notice that if I remove the Leading and Trailing BufferZone settings from the Store it still happens. I'm attaching a screen shot of what I see.

    JW
    Attached Thumbnails Click image for larger version. 

Name:	RowRepeat.PNG 
Views:	63 
Size:	60.9 KB 
ID:	5574  
  6. #6
    Trunk works with ExtJS 4.2 beta 2 version
    In this version I suggest to use BufferedRenderer plugin for GridPanel (remove Buffered (and related) options from the store and add that plugin to the grid)

    <%@ Page Language="C#"%>
    <%@ Register Assembly="Ext.NET" Namespace="Ext.Net" TagPrefix="ext" %>
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!X.IsAjaxRequest)
            {
                this.Store1.DataSource = this.dynData;
            }
        }
        private List<object> dynData
        {
            get
            {
                List<object> comps = new List<object> { };
                 
                for (int i = 0; i < 500; i++)
                {
                    comps.Add(new {company = "Company " + i, price = 71.72, change = 0.02, pctChange = 0.03, lastCahnge = new DateTime(2013, 9, 1) });
                }
                 
                return comps;
            }
        }
        protected void Store1_RefreshData(object sender, StoreReadDataEventArgs e)
        {
            List<object> data = this.dynData;
            string s = e.Parameters[this.GridFilters1.ParamPrefix];
            //-- start filtering ------------------------------------------------------------
            if (!string.IsNullOrEmpty(s))
            {
                FilterConditions fc = new FilterConditions(s);
     
                foreach (FilterCondition condition in fc.Conditions)
                {
                    Comparison comparison = condition.Comparison;
                    string field = condition.Field;
                    FilterType type = condition.Type;
     
                    object value;
                    switch (condition.Type)
                    {
                        case FilterType.Boolean:
                            value = condition.Value<bool>();
                            break;
                        case FilterType.Date:
                            value = condition.Value<DateTime>();
                            break;
                        case FilterType.List:
                            value = condition.List;
                            break;
                        case FilterType.Numeric:
                            if (data.Count > 0 && data[0].GetType().GetProperty(field).PropertyType == typeof(int))
                            {
                                value = condition.Value<int>();
                            }
                            else
                            {
                                value = condition.Value<double>();
                            }
     
                            break;
                        case FilterType.String:
                            value = condition.Value<string>();
                            break;
                        default:
                            throw new ArgumentOutOfRangeException();
                    }
     
                    data.RemoveAll(
                        item =>
                        {
                            object oValue = item.GetType().GetProperty(field).GetValue(item, null);
                            IComparable cItem = oValue as IComparable;
     
                            switch (comparison)
                            {
                                case Comparison.Eq:
     
                                    switch (type)
                                    {
                                        case FilterType.List:
                                            return !(value as List<string>).Contains(oValue.ToString());
                                        case FilterType.String:
                                            return !oValue.ToString().StartsWith(value.ToString());
                                        default:
                                            return !cItem.Equals(value);
                                    }
     
                                case Comparison.Gt:
                                    return cItem.CompareTo(value) < 1;
                                case Comparison.Lt:
                                    return cItem.CompareTo(value) > -1;
                                default:
                                    throw new ArgumentOutOfRangeException();
                            }
                        }
                    );
                }
            }
            //-- end filtering ------------------------------------------------------------
            //-- start sorting ------------------------------------------------------------
            if (e.Sort.Length > 0)
            {
                data.Sort(delegate(object x, object y)
                {
                    object a;
                    object b;
     
                    int direction = e.Sort[0].Direction == Ext.Net.SortDirection.DESC ? -1 : 1;
     
                    a = x.GetType().GetProperty(e.Sort[0].Property).GetValue(x, null);
                    b = y.GetType().GetProperty(e.Sort[0].Property).GetValue(y, null);
                    return CaseInsensitiveComparer.Default.Compare(a, b) * direction;
                });
            }
            //-- end sorting ------------------------------------------------------------
            this.GridPanel1.GetStore().DataSource = data;
        }
        protected void Button1_Click(object sender, DirectEventArgs e)
        {
            RowSelectionModel selRows = GridPanel1.GetSelectionModel() as RowSelectionModel;
            this.Store1.DataSource = this.dynData;
            selRows.ClearSelection();
        }
    </script>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
        <title></title>
        <script type="text/javascript">
            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="ExtResourceManager" runat="server" DisableViewState="false" RenderStyles="Embedded"></ext:ResourceManager>
        <ext:GridPanel ID="GridPanel1" runat="server" Title="Sample Grid" Width="650" Height="350" EnableColumnMove="false">
            <Store>
                <ext:Store ID="Store1" runat="server" RemoteSort="true"
                            RemoteFilter="true" OnReadData="Store1_RefreshData">
                    <Proxy>
                        <ext:PageProxy/>
                    </Proxy>
                    <Model>
                        <ext:Model ID="Model1" 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>
            <Plugins>
                <ext:BufferedRenderer runat="server" />
            </Plugins>
            <ColumnModel OverflowY="Auto">
                <Columns>
                    <ext:RowNumbererColumn Width="50"></ext:RowNumbererColumn>
                    <ext:Column ID="Column1" runat="server" Text="Company" DataIndex="company" Flex="1" />
                    <ext:Column ID="Column2" runat="server" Text="Price" DataIndex="price">                  
                        <Renderer Format="UsMoney" />
                    </ext:Column>
                    <ext:Column ID="Column3" runat="server" Text="Change" DataIndex="change">
                        <Renderer Fn="change" />
                    </ext:Column>
                    <ext:Column ID="Column4" runat="server" Text="Change" DataIndex="pctChange">
                        <Renderer Fn="pctChange" />
                    </ext:Column>
                    <ext:DateColumn ID="DateColumn1" runat="server" Text="Last Updated" DataIndex="lastChange" />
                </Columns>            
            </ColumnModel>       
            <SelectionModel>
                <ext:CheckboxSelectionModel ID="CheckboxSelectionModel1" runat="server" Mode="Single" AllowDeselect="true" ShowHeaderCheckbox="false"></ext:CheckboxSelectionModel>
            </SelectionModel>
            <Features>
                <ext:GridFilters ID="GridFilters1" runat="server" Local="false" Enabled="true">
                    <Filters>
                        <ext:StringFilter DataIndex="company"></ext:StringFilter>
                    </Filters>
                </ext:GridFilters>
            </Features>
        </ext:GridPanel>
        </form>
    </body>
    </html>
    Vladimir Shcheglov
    Sr. Developer
  7. #7
    Thanks Validmir, seems to work in my example good. I'll update my application and if I have any other problems will post back.

    So it sounds like the Buffered Store is a bug with Sencha version?

    JW
  8. #8
    Hi,

    I don't think it is a bug. You set up PageSize="100", but doesn't take it into account in the OnReadData handler. You returns 500 records each request, but the Store expects 100.

    Setting up PageSize="500" as @Baidaly suggested appears to fix the problem with your initial example. If PageSize doesn't equal the amount of records you should return the records from the OnReadData handler just only for the requested page. There are the Start, Limit and Page parameters for that in the StoreReadDataEventArgs instance.
  9. #9
    I seem to be good with buffering, but now that I updated my actual application with the SVN source code(4793), Tooltip and EmptyText are no longer working. I verified that they still work with my earlier version of the source. I did just notice that Rev 4798 is now been uploaded since yesterday, I will have to try that out next week before posting a new thread.

    JW
  10. #10
    Unfortunately, version of Ext JS in trunk still is beta and if you will provide sample to reproduce we can send them to Sencha and give temp fix
Page 1 of 2 12 LastLast

Similar Threads

  1. [CLOSED] Infinite srolling buffered grid scrolling problem
    By ASAPCH in forum 2.x Legacy Premium Help
    Replies: 6
    Last Post: Feb 04, 2013, 3:55 AM
  2. [CLOSED] Buffered Grid with filtering and editing
    By jchau in forum 2.x Legacy Premium Help
    Replies: 1
    Last Post: Jan 13, 2013, 6:39 AM
  3. Replies: 5
    Last Post: Dec 14, 2012, 5:07 PM
  4. Replies: 3
    Last Post: Oct 16, 2012, 5:03 PM
  5. [CLOSED] Buffered Grid View Scrolling
    By bethc in forum 1.x Legacy Premium Help
    Replies: 3
    Last Post: Dec 02, 2009, 7:29 AM

Posting Permissions