[OPEN] [#369] Bug with gridpanel on tabs

  1. #1

    [OPEN] [#369] Bug with gridpanel on tabs

    I have TabPabel with two tabs, each of which is GridPanel. By pressing a button I try to load the data in the grids.

    The complete project for VS2010 can be downloaded at http://www.fileswap.com/dl/B9aOLl3nYa/

    The key snippets:

    View
    @using System.Collections.ObjectModel
    @using Ext.Net
    @using Ext.Net.MVC
    @using ScriptMode = Ext.Net.ScriptMode
    
    @{
        var ext = Html.X();
    }
    
    @ext.ResourceManager().ScriptMode(ScriptMode.Debug).SourceFormatting(true)
    
    <script type="text/javascript">
    
        var reloadGrid = function (name, data, config, grid) {
            var control = grid;
            var controlId = control.getId();
            console.log("reload begin: " + controlId);
            var store = control.getStore();
            store.proxy.extraParams = { name: controlId };
            store.load({
                scope: this,
                callback: function (records, operation, success) {
                    console.log("reload complete: " + controlId + " (" + success + ")");
                    if (success) {
                        var sm = control.getSelectionModel();
                        sm.clearSelections();
                        sm.select(0);
                    }
                }
            });
        }
    
    </script>
    
    @functions {
    
        private AbstractComponent CreateGrid(string gridId)
        {
            var ext = Html.X();
            return ext.GridPanel()
                      .ID(gridId)
                      .Title(gridId)
                      .ColumnModel(
                          ext.Column().Text("Id").DataIndex("ID"),
                          ext.Column().Text("Name").DataIndex("NAME"),
                          ext.Column().Text("Value").DataIndex("VALUE"),
                          ext.Column().Text("Date").DataIndex("DATE")
    
                      )
                      .SelectionModel(
                          ext.CheckboxSelectionModel().Mode(SelectionMode.Multi).ShowHeaderCheckbox(true).PruneRemoved(false)
                      )
                      .MessageBusListeners(new MessageBusListener
                          {
                              Name = "Test.Button.*",
                              Handler = "reloadGrid(name, data, config, this);"
                          })
                      .Store(
                          ext.Store()
                             .ItemID("ID")
                             .RemoteFilter(true).RemoteSort(true).RemotePaging(true).RemoteGroup(true)
                             .Buffered(true)
                             // With default value (25) loading will hang up... http://forums.ext.net/showthread.php?26505-OPEN-348-Infinity-Scrolling
                             .PageSize(50)
                             .AutoLoad(false)
                             .Model(
                                 ext.Model()
                                    .Name(gridId+"_model")
                                    .Fields(
                                        new ModelField("ID", ModelFieldType.Int),
                                        new ModelField("NAME", ModelFieldType.String),
                                        new ModelField("VALUE", ModelFieldType.Int),
                                        new ModelField("DATE", ModelFieldType.Date)
                                     )
                              )
                             .Proxy(
                                 ext.AjaxProxy()
                                    .Url(Url.Action("GetGridData"))
                                    .Reader(ext.JsonReader().Root("data").TotalProperty("total").IDProperty("ID"))
                                    .ActionMethods(methods => methods.Read = HttpMethod.POST)
                              )
                );
        }
    
    }
    
    @{
        var grids = new Collection<AbstractComponent>
            {
                CreateGrid("Grid1"),
                CreateGrid("Grid2"),
            };
    }
    
    @(ext.Viewport()
         .ID("viewPort")
         .Layout(LayoutType.Border)
         .Items(ext.Panel()
                   .Region(Region.North)
                   .Items(
                       ext.Button()
                          .Text("Reload")
                          .Listeners(listeners => { listeners.Click.BroadcastOnBus = "Test.Button.Click"; })),
                ext.TabPanel()
                   .Region(Region.Center)
                   .Items(grids)
          ))
    Controller
    using System;
    using System.Data;
    using System.Web.Mvc;
    using Ext.Net.MVC;
    
    namespace TwoGrids.Controllers
    {
        public class HomeController : Controller
        {
            private const int CMaxRowCount = 1001; // With value 1000 it will crashed then scroll down at end
    
            public ActionResult Index()
            {
                return View();
            }
    
            [HttpPost]
            public StoreResult GetGridData(string name, int? page, int? start, int limit)
            {
                var dataTable = GetData(name, start.HasValue ? start.Value : 0, limit);
                var result = this.Store(dataTable);
                result.Total = CMaxRowCount;
                return result;
            }
    
            private static DataTable GetData(string name, int firstRow, int maxRows)
            {
                var dataTable = new DataTable();
                dataTable.Columns.AddRange(new[]
                    {
                        new DataColumn("ID", typeof (int)),
                        new DataColumn("NAME", typeof (string)),
                        new DataColumn("VALUE", typeof (int)),
                        new DataColumn("DATE", typeof (DateTime))
                    });
    
                var randow = new Random();
    
                for (var i = firstRow + 1; i <= firstRow + maxRows; i++)
                {
                    var row = dataTable.NewRow();
                    row["ID"] = i;
                    row["NAME"] = name + "_" + i;
                    row["VALUE"] = randow.Next(100, 200);
                    row["DATE"] = DateTime.Now;
    
                    dataTable.Rows.Add(row);
                }
    
                return dataTable;
            }
        }
    }
    There are two bugs, but as I prepared one example, I will describe both of them in one post.

    1. Grid on inactive tab is not updated. There is an error somewhere in the javascripts, as evidenced by FireBug.

    Steps for localization:
    1.1 Open Page
    1.2 Press the button
    1.3 Go to the second tab. Catch the bug - 'rows' is undefined (see attached screenshot).
    Click image for larger version. 

Name:	bug1.png 
Views:	25 
Size:	88.3 KB 
ID:	7151

    UPDATE:
    In additional try to do this:
    1.1 Open Page
    1.2 DON'T PUSH BUTTON!
    1.3 Go to Tab2, Grid is empty. It's ok.
    1.4 Come back at Tab1
    1.5 PUSH THE BUTTON!
    1.6 Go to tab2, some records are there... but try to scroll.... it only 66 records, and grid will not fetch any more.... well thrid bug...


    2. Please note, the grid is buffered.
    When Total (from json response) divided by the PageSize no residue, when scrolling to the end we get an error. (Changing CMaxRowCount from 1000 to 1001 at my example will make it works).
    Steps for localization:
    1.1 Check that CMaxRowCount is 1000 - total number in dataset
    1.2 Check that grids PageSize is 100
    1.3 Open page
    1.4 Press the button
    1.5 Scroll down by the scroller at the end. All rows wont be loaded, it will crash at line 992 (screenshot attached).
    Click image for larger version. 

Name:	bug2.jpg 
Views:	24 
Size:	91.9 KB 
ID:	7152
    Last edited by Daniil; Nov 05, 2013 at 7:39 AM. Reason: [OPEN] [#369]
  2. #2
    Hi @alex303,

    Yes, unfortunately, there are problems with grid buffered rendering.

    I think the first two problems can be related to these Issues:
    https://github.com/extnet/Ext.NET/issues/270
    https://github.com/extnet/Ext.NET/issues/308
    https://github.com/extnet/Ext.NET/issues/355

    The third problem might be related to this one:
    https://github.com/extnet/Ext.NET/issues/288

    Thank you for a test sample. We should ensure it is not a new case.

    By the way, what is the Ext.NET version you are working with?
  3. #3
    Daniil,

    Thx, I will read those post...

    > By the way, what is the Ext.NET version you are working with?

    Latest version from SVN... I just build it from sources


    upd
    ---
    I spent a few hours on debugging Sencha's source code and now the cause of most bugs is clear to me. Incorrect behavior is a consequence of the fact that a lot of logic of BufferedRender depends on the size of DOM-elements. So as an invisible dom-elements sizes are equal to 0, I have seen the division by zero, Infinities and other "cute" things. So stupid.

    Unfortunately, this is not just a little bug, it's a total defect when BufferedRender is invisible (point of start - method onViewResize will set viewSize to Infinity due divizion by rowHeight which is zero). And the saddest thing is that Sencha doesn't want to fix it... I have read their forum... such bugs have a long story. Very strange and incomprehensible behavior for a commercial project. Especially for such importand and usefull thing like pageless grid with partial fetching.

    In my case, I have got a solution of most problems by implementing some kind of "pending updates". Not very elegant, but seems to be working.
    Last edited by alex303; Nov 03, 2013 at 8:02 PM.
  4. #4
    I totally agree with you. It is absolutely incomprehensible why such big bugs with key features take so much time to fix (or even not fixed at all).

    I added this thread for references in this Issue:
    https://github.com/extnet/Ext.NET/issues/270

    Do you mind we close this thread? If some new info comes up, we will update it with a new post.
  5. #5
    Quote Originally Posted by alex303 View Post
    2. Please note, the grid is buffered.
    When Total (from json response) divided by the PageSize no residue, when scrolling to the end we get an error. (Changing CMaxRowCount from 1000 to 1001 at my example will make it works).
    Steps for localization:
    1.1 Check that CMaxRowCount is 1000 - total number in dataset
    1.2 Check that grids PageSize is 100
    1.3 Open page
    1.4 Press the button
    1.5 Scroll down by the scroller at the end. All rows wont be loaded, it will crash at line 992 (screenshot attached).
    Click image for larger version. 

Name:	bug2.jpg 
Views:	24 
Size:	91.9 KB 
ID:	7152
    Could you, please, try this fix?


    Fix
    Ext.view.Table.override({
        renderRow: function(record, rowIdx, out) {
            var me = this,
                isMetadataRecord = rowIdx === -1,
                selModel = me.selModel,
                rowValues = me.rowValues,
                itemClasses = rowValues.itemClasses,
                rowClasses = rowValues.rowClasses,
                cls,
                rowTpl = me.rowTpl;
    
            // Set up mandatory properties on rowValues
            rowValues.record = record;
            rowValues.recordId = record.internalId;
            rowValues.recordIndex = rowIdx;
            rowValues.rowId = me.getRowId(record);
            rowValues.itemCls = rowValues.rowCls = '';
            if (!rowValues.columns) {
                rowValues.columns = me.ownerCt.columnManager.getColumns();
            }
    
            itemClasses.length = rowClasses.length = 0;
    
            // If it's a metadata record such as a summary record.
            // So do not decorate it with the regular CSS.
            // The Feature which renders it must know how to decorate it.
            if (!isMetadataRecord) {
                itemClasses[0] = Ext.baseCSSPrefix + "grid-row";
                if (selModel && selModel.isRowSelected) {
                    //if (selModel.isRowSelected(rowIdx + 1)) { // wrong
                    if (selModel.isRowSelected(record)) { // or if (selModel.isRowSelected(rowIdx)) {
                        itemClasses.push(me.beforeSelectedItemCls);
                    }
                    if (selModel.isRowSelected(record)) {
                        itemClasses.push(me.selectedItemCls);
                    }
                }
    
                if (me.stripeRows && rowIdx % 2 !== 0) {
                    rowClasses.push(me.altRowCls);
                }
    
                if (me.getRowClass) {
                    cls = me.getRowClass(record, rowIdx, null, me.dataSource);
                    if (cls) {
                        rowClasses.push(cls);
                    }
                }
            }
            
            if (out) {
                rowTpl.applyOut(rowValues, out);
            } else {
                return rowTpl.apply(rowValues);
            }
        }
    });
    Last edited by Daniil; Nov 04, 2013 at 10:09 AM.
  6. #6
    Quote Originally Posted by Daniil View Post
    Could you, please, try this fix?
    I did not test it deeply, but at first glance, works great! Thank you.

    Do you mind we close this thread?
    I have no reason to object.
  7. #7
    Quote Originally Posted by alex303 View Post
    I did not test it deeply, but at first glance, works great! Thank you.
    Nice, thank you for confirming. I committed the fix to the SVN trunk in revision 5466.

    Also created an Issue to review after next ExtJS update.
    https://github.com/extnet/Ext.NET/issues/369
  8. #8
    Hi @alex303,

    It turned out that my fix causes another issue.
    http://forums.ext.net/showthread.php?28089

    Could you, please, try this fix instead?

    Fix
    Ext.view.Table.override({
        renderRow: function(record, rowIdx, out) {
            var me = this,
                isMetadataRecord = rowIdx === -1,
                selModel = me.selModel,
                rowValues = me.rowValues,
                itemClasses = rowValues.itemClasses,
                rowClasses = rowValues.rowClasses,
                cls,
                rowTpl = me.rowTpl;
            
            rowValues.record = record;
            rowValues.recordId = record.internalId;
            rowValues.recordIndex = rowIdx;
            rowValues.rowId = me.getRowId(record);
            rowValues.itemCls = rowValues.rowCls = '';
            if (!rowValues.columns) {
                rowValues.columns = me.ownerCt.columnManager.getColumns();
            }
    
            itemClasses.length = rowClasses.length = 0;
    
            if (!isMetadataRecord) {
                itemClasses[0] = Ext.baseCSSPrefix + "grid-row";
                if (selModel && selModel.isRowSelected) {
    
                    if ((rowIdx + 1) < selModel.store.getTotalCount()) {
                        if (selModel.isRowSelected(rowIdx + 1)) {
                            itemClasses.push(me.beforeSelectedItemCls);
                        }
                    }
    
                    if (selModel.isRowSelected(record)) {
                        itemClasses.push(me.selectedItemCls);
                    }
                }
    
                if (me.stripeRows && rowIdx % 2 !== 0) {
                    rowClasses.push(me.altRowCls);
                }
    
                if (me.getRowClass) {
                    cls = me.getRowClass(record, rowIdx, null, me.dataSource);
                    if (cls) {
                        rowClasses.push(cls);
                    }
                }
            }
            
            if (out) {
                rowTpl.applyOut(rowValues, out);
            } else {
                return rowTpl.apply(rowValues);
            }
        }
    });
  9. #9
    I decided to commit the fix. Revision #5673. It will go to the v2.5 release.

    Please report if you face any issues with the new fix.

Similar Threads

  1. Replies: 1
    Last Post: Jul 16, 2013, 9:27 AM
  2. [CLOSED] Move tabs Tabs Style Google Chrome
    By majunior in forum 1.x Legacy Premium Help
    Replies: 7
    Last Post: Apr 30, 2013, 12:58 PM
  3. [CLOSED] TabPanel tabs activating differently if remove tabs
    By rnachman in forum 1.x Legacy Premium Help
    Replies: 7
    Last Post: Mar 15, 2013, 3:41 PM
  4. Replies: 0
    Last Post: Dec 25, 2012, 2:03 AM
  5. Vertical tabs in ext.Net
    By Prasad in forum 1.x Help
    Replies: 5
    Last Post: Sep 08, 2010, 3:00 PM

Posting Permissions