Looks like we can't reproduce the issue or there's a problem in the test case provided.
  1. #1
    Ext JS Premium Member
    Join Date
    Aug 2011
    Posts
    11
    Vote Rating
    0
    philidem is on a distinguished road

      0  

    Default Custom container with inner structure causes layout failure

    Custom container with inner structure causes layout failure


    REQUIRED INFORMATION Ext version tested:
    • Ext 4.1 RC2
    Browser versions tested against:
    • Chrome
    • Firefox 4
    DOCTYPE tested against:
    • <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    Description:
    • When creating a custom container (a class that extends 'Ext.container.Container') with a renderTpl and an overridden getTargetEl() function the layout engine doesn't complete successfully. This will cause the afterFirstLayout function in Ext.container.Viewport to not be called which will prevent the Viewport from listening to window resize events.
    Steps to reproduce the problem:
    • Define class that extends Ext.container.Container
    • Initialize renderTpl, renderData, childEls
    • Override getTargetEl() to return a child element instead of the default element
    The result that was expected:
    • afterFirstLayout() function will be called related events will be fired
    The result that occurs instead:
    • afterFirstLayout() is never called
    • If you're using a Viewport then Viewport will not listen to window resize events.
    Test Case:
    Code:
    Ext.Loader.setConfig({enabled: true, disableCaching: false});
    
    Ext.require(['Ext.container.Viewport']);
    
    Ext.onReady(function() {
        
        Ext.define('CustomContainer', {
            
            extend : 'Ext.container.Container',
            
            childEls : [
                'bodyElem'
            ],
            
            renderTpl : [
                '<div id="{id}-bodyElem" style="background-color: white;">',
                    'TEST CONTENT',
                '</div>'
            ],
            
            initComponent : function() {
                
                Ext.apply(this, {
                    style : 'background-color: gray; padding: 10px;',
                    renderData : {
                        id : this.id
                    }
                });
                
                this.callParent(arguments);
            },
            
            getTargetEl : function() {
                return this.bodyElem;
            }
        });
        
        Ext.create('Ext.container.Viewport', {
            layout: 'fit',
            items: Ext.create('CustomContainer')
        });
    });
    HELPFUL INFORMATION Screenshot or Video:
    • (not available)
    See this URL for live test case: http:// Debugging already done:
    • (not available)
    Possible fix:
    • The problem seems to be that the custom container layout is not requeued inside Context.js and the next time runCycle() is called it looks like no progress is made so the handleFailure() function gets called. Either the custom container layout which is not "done" should be requeued or runCycle() should return true if (layouts.length == 0).
    Additional CSS used:
    • only default ext-all.css
    Operating System:
    • Windows y
    • WinXP Pro
    Last edited by philidem; 18 Apr 2012 at 10:04 AM. Reason: Fixing typos

  2. #2
    Ext JS Premium Member
    Join Date
    Aug 2011
    Posts
    11
    Vote Rating
    0
    philidem is on a distinguished road

      0  

    Default


    Is there good documentation for writing custom containers that have internal HTML structure? I would like to also point out that I encountered this issue after upgrading from Ext JS 4.0.7 to Ext JS 4.1 RC2. That is, my custom containers with internal HTML structure were working in 4.0.7 but no longer work in Ext JS 4.1.

    The layout code is fairly complicated so I'm not sure if this is a bug if I am just writing code that doesn't conform to the API. The error is actually kind of hidden because you never see a JavaScript error or console log that indicates a problem. So, if I am writing bad code it would still be nice if Context.js handleFailure() emitted a log statement if there is ever a layout problem.

    In my example, I didn't actually nest any items in the container to keep things simple. If you nest items then you'll see same problem with layout engine.

  3. #3
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    16,997
    Vote Rating
    649
    evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute

      0  

    Default


    Perhaps it would be better if you explained what you're trying to achieve, as you said the layout system is quite complex, there could well be an easier way around it.
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!

  4. #4
    Ext JS Premium Member
    Join Date
    Aug 2011
    Posts
    11
    Vote Rating
    0
    philidem is on a distinguished road

      0  

    Default


    I am basically trying to create a custom container that uses this render template:
    Code:
    ['<table class="rsa-HeaderPanel"><tr>',
        '<td style="width: 33%">',
            '<h2 class="rsa-HeaderPanel-title">{title}</h2>',
            '<div class="rsa-HeaderPanel-subtitle">{subtitle}</div>',
        '</td>',
        '<td id="{id}-bodyElem" class="{bodyCls}" style="width: 34%">',
        '</td>',
        '<td style="width: 33%"></td>',
    '</tr></table>']
    As you can probably tell it's a header with three cells on a single row. The first cell contains a static title and subtitle. The middle cell contains the children items. The last cell is there just so the middle cell is centered. I want the children items to be rendered inside TD with ID {id}-bodyElem. I want the container to use the "auto" layout so that the children can be positioned using the browser's default flow.

    Please let me know if you need more clarification.

  5. #5
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    16,997
    Vote Rating
    649
    evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute

      0  

    Default


    In this case you need to use a body layout:

    Code:
    Ext.define('CustomContainer', {
        extend: 'Ext.container.Container',
        alias: 'widget.foo',
    
        childEls: ['body'],
        
        componentLayout: 'body',
    
        renderTpl: [
            '<table class="rsa-HeaderPanel"><tr>',
                '<td style="width: 33%">',
                    '<h2 class="rsa-HeaderPanel-title">{title}</h2>',
                    '<div class="rsa-HeaderPanel-subtitle">{subtitle}</div>',
                '</td>',
                '<td id="{id}-body" class="{bodyCls}" style="width: 34%">',
                '</td>',
                '<td style="width: 33%"></td>',
            '</tr></table>'],
    
        initComponent: function() {
            Ext.apply(this, {
                style: 'background-color: gray; padding: 10px;'
            });
            this.callParent();
        },
        
        getTargetEl: function() {
            return this.body;
        }
    });
    
    Ext.onReady(function() {
    
        Ext.create('Ext.container.Viewport', {
            layout: 'fit',
            items: Ext.create('CustomContainer', {
                items: {
                    html: 'Foo'
                }
            })
        });
    });
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!

  6. #6
    Ext JS Premium Member
    Join Date
    Aug 2011
    Posts
    11
    Vote Rating
    0
    philidem is on a distinguished road

      0  

    Default


    I just wanted to let you know that your solution worked well. I didn't get a chance to verify it until recently because I had to temporarily revert back to 4.0.7. We are up and running on 4.1 and everything seems to be working well (I did encounter some minor changes in the API but I was able to make changes to handle these).

    I recommend adding better documentation to the "body" component layout.

    Thanks for your help!

Thread Participants: 1