Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: [4.1.2] TableLayout + IE8: calling doLayout after hidding an item causes a JS error

    You found a bug! We've classified it as EXTJS-7500 . We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.
  1. #1
    Sencha User Daniil's Avatar
    Join Date
    Jun 2010
    Location
    Saint-Petersburg, Russia
    Posts
    1,017
    Vote Rating
    125
      0  

    Default [4.1.2] TableLayout + IE8: calling doLayout after hidding an item causes a JS error

    REQUIRED INFORMATION

    Ext version tested:

    • Ext 4.1.2

    Browser versions tested against:
    • IE8 - throws a JavaScript error
    • IE9 - OK
    • Chrome - OK
    • FireFox - OK

    Description:
    • Working on some issue, I discovered that calling doLayout() for a container with TableLayout after hiding some item causes a JavaScript error in IE8. Generally, it is not required to call doLayout() in the example below (it is just a test case to reproduce), but, I think, it should not cause an error.
    • The error "tagName is null or not an object" occurs here:
      Code:
      ensureInDocument: function (el) {
          var dom = el.dom.parentNode;
          while (dom) {
              if (dom.tagName.toUpperCase() == 'BODY') {
                  return;
              }
              dom = dom.parentNode;
          }
      
          Ext.getDetachedBody().appendChild(el);
      }

    Steps to reproduce the problem:
    • Run the sample in IE8 (it is reporducible in IE9 with IE8 mode as well)
    • Click the button

    The result that was expected:
    • No error

    The result that occurs instead:
    • A JavaScript error occurs

    Test Case:

    Code:
    <html>
    <head>
        <title>TableLayout hide item</title>
    
        <link type="text/css" rel="stylesheet" href="../resources/css/ext-all.css" />
        
        <script type="text/javascript" src="../ext-all-debug.js"></script>
    
        <script type="text/javascript">
            Ext.onReady(function () {
                Ext.create("Ext.container.Container", {
                    renderTo: Ext.getBody(),
                    layout: "table",
                    items: [{
                        xtype: "button",
                        text: "Hide label",
                        handler: function () {
                            var ct = this.up("container");
                            ct.child("label").hide();
                            
                            ct.doLayout(); // actually, it is not required, but reproduces the issue.
                        }
                    }, {
                        xtype: "label",
                        text: "Label"
                    }]
                });
            });
        </script>
    </head>
    <body>
    
    </body>
    </html>


  2. #2
    Sencha - Sr Software Engineer mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    39,894
    Vote Rating
    1327
      0  

    Default

    Thanks for the report! I have opened a bug in our bug tracker.

  3. #3
    Sencha User
    Join Date
    Apr 2012
    Posts
    5
    Vote Rating
    1
      0  

    Default

    There is any quick fix for it?

  4. #4
    Sencha User Daniil's Avatar
    Join Date
    Jun 2010
    Location
    Saint-Petersburg, Russia
    Posts
    1,017
    Vote Rating
    125
      0  

    Default

    Maybe this workaround. Actually, this is not a fix. I didn't investigate a root of the problem. But, at least, it allows to avoid an error.

    Workaround
    Code:
    Ext.layout.container.Table.override({
        ensureInDocument: function(el){
            var dom = el.dom.parentNode;
            while (dom) {
                if (dom.tagName && dom.tagName.toUpperCase() == 'BODY') {
                    return;
                }
                dom = dom.parentNode;
            } 
            
            Ext.getDetachedBody().appendChild(el);
        }
    });
    Object.NET
    Frameworks and Tools for .NET Developers
    --------------------------------------------------
    Ext.NET - Ext JS for ASP.NET - Examples | Twitter
    Bridge.NET - Write C#. Run JavaScript! - Live | Twitter
    --------------------------------------------------

  5. #5
    Sencha User
    Join Date
    Apr 2012
    Posts
    5
    Vote Rating
    1
      0  

    Default

    This is only workaround for silent the javascript error.
    But the label isn't shown when you do something like this:
    Code:
    var label = Ext.ComponentQuery.query("label")[0];
    label.show();
    label.updateLayout();

  6. #6
    Sencha User Daniil's Avatar
    Join Date
    Jun 2010
    Location
    Saint-Petersburg, Russia
    Posts
    1,017
    Vote Rating
    125
      0  

    Default

    Sadly. Maybe you could wrap the Label in an additional Container?
    Object.NET
    Frameworks and Tools for .NET Developers
    --------------------------------------------------
    Ext.NET - Ext JS for ASP.NET - Examples | Twitter
    Bridge.NET - Write C#. Run JavaScript! - Live | Twitter
    --------------------------------------------------

  7. #7
    Sencha User
    Join Date
    Feb 2013
    Posts
    1
    Vote Rating
    0
      0  

    Default

    Could you please provide the link to the bug bug tracker. So that we can keep track of this issue and make changes to our code accordingly.

  8. #8
    Sencha User Daniil's Avatar
    Join Date
    Jun 2010
    Location
    Saint-Petersburg, Russia
    Posts
    1,017
    Vote Rating
    125
      0  

    Default

    Sencha's tracker is private.

    The thread should be marked as closed just after it gets fixed.

    A bug id is EXTJSIV-7500 . You can also review it in Release Notes of a new release.

    By the way, sometimes it happens when there is no bug id in Release Notes, a thread is still opened, but a bug is actually fixed.
    Object.NET
    Frameworks and Tools for .NET Developers
    --------------------------------------------------
    Ext.NET - Ext JS for ASP.NET - Examples | Twitter
    Bridge.NET - Write C#. Run JavaScript! - Live | Twitter
    --------------------------------------------------

  9. #9
    Sencha Premium Member
    Join Date
    Jan 2014
    Posts
    8
    Vote Rating
    1
      0  

    Default

    We ran into this problem in 4.2.2. We were trying to call hide() on a component within a table layout. We didn't explicitly call doLayout(), but the hide triggered a layout run and then the error happened. Switching the table layout to a vbox worked around the error, but to retain our layout we were able to fix it by setting hidden to true on the intial configuration of the element (and then showing the element as needed for specific cases).

    The workaround of using "hidden: true" only works for us because we don't need to show or hide the element more than the first time. If we had to be showing and hiding the item multiple times, we'd perhaps be running into the problem again.

  10. #10
    Sencha User
    Join Date
    Mar 2010
    Location
    Nowhere
    Posts
    2
    Vote Rating
    1
      0  

    Default

    I found a solution which works for me. Kindly check if this works for you.

    Ext.layout.container.Table.override({
    renderChildren: function() {
    var me = this,
    items = me.getLayoutItems(),
    tbody = me.owner.getTargetEl().child('table', true).tBodies[0],
    rows = tbody.rows,
    i = 0,
    len = items.length,
    hiddenItems = me.getHiddenItems(),
    cells, curCell, rowIdx, cellIdx, item, trEl, tdEl, itemCt, el;
    var cnt = items.length;

    //need to push hidden items as well
    for(i=0;i<hiddenItems.length;i++)
    {
    items.push(hiddenItems[i]);
    }
    // Calculate the correct cell structure for the current items
    cells = me.calculateCells(items);


    // Loop over each cell and compare to the current cells in the table, inserting/
    // removing/moving cells as needed, and making sure each item is rendered into
    // the correct cell.
    for (var i=0; i < items.length; i++) {
    curCell = cells[i];
    rowIdx = curCell.rowIdx;
    cellIdx = curCell.cellIdx;
    item = items[i];


    // If no row present, create and insert one
    trEl = rows[rowIdx];
    if (!trEl) {
    trEl = tbody.insertRow(rowIdx);
    if (me.trAttrs) {
    trEl.set(me.trAttrs);
    }
    }


    // If no cell present, create and insert one
    itemCt = tdEl = Ext.get(trEl.cells[cellIdx] || trEl.insertCell(cellIdx));
    if (me.needsDivWrap()) { //create wrapper div if needed - see docs below
    itemCt = tdEl.first() || tdEl.createChild({tag: 'div'});
    itemCt.setWidth(null);
    }


    // Render or move the component into the cell
    if (!item.rendered) {
    me.renderItem(item, itemCt, 0);
    } else if (!me.isValidParent(item, itemCt, rowIdx, cellIdx, tbody)) {
    me.moveItem(item, itemCt, 0);
    }


    // Set the cell properties
    if (me.tdAttrs) {
    tdEl.set(me.tdAttrs);
    }
    if (item.tdAttrs) {
    tdEl.set(item.tdAttrs);
    }
    tdEl.set({
    colSpan: item.colspan || 1,
    rowSpan: item.rowspan || 1,
    id: item.cellId || '',
    cls: me.cellCls + ' ' + (item.cellCls || '')
    });


    // If at the end of a row, remove any extra cells
    if (!cells[i + 1] || cells[i + 1].rowIdx !== rowIdx) {
    cellIdx++;
    while (trEl.cells[cellIdx]) {
    trEl.deleteCell(cellIdx);
    }
    }
    }


    // Delete any extra rows
    rowIdx++;
    while (tbody.rows[rowIdx]) {
    tbody.deleteRow(rowIdx);
    }
    // Check if we've removed any cells that contain a component, we need to move
    // them so they don't get cleaned up by the gc
    for (i = len; i < items.length; i++) {
    me.ensureInDocument(items[i].getEl());
    }

    //Not needed
    /*for (i = 0, len = hiddenItems.length; i < len; ++i) {
    me.ensureInDocument(hiddenItems[i].getEl());
    }*/
    }
    });

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •