1. #1
    Ext JS Premium Member
    Join Date
    Jun 2007
    Posts
    13
    Vote Rating
    0
    bdurette is on a distinguished road

      0  

    Default Extending Panel: How can I manipulate the layout regions?

    Extending Panel: How can I manipulate the layout regions?


    I'm trying to extend Ext.Panel, so I can specify the layout and (dynamically) the contents of the various layout regions. I have not figured out how or when the regions actually appear in the DOM so I can manipulate them. I'm using a border layout and in my simplified example I'm only using the 'south' and 'center' region and want to manipulate the 'center' region to add an image. Here's the code I have (full demo code in attachment):

    Code:
    Test.ImagePanel = Ext.extend( Ext.Panel, {
        layout: 'border',
        img: null,
    
        initComponent : function() {
            // Configure the layout for this panel
            Ext.apply(this, {
                layout: 'border',
                items: [{
                    region: 'center',
                    border: false,
                    titlebar: false,
                    deferredRender: false
                },
                new Ext.Slider({
                    animate: false,
                    width: 200,
                    value: 50,
                    minValue: 0,
                    region: 'south',
                    maxValue: 100
                })
            ]});
    
            // Invoke super-class initialization
            Test.ImagePanel.superclass.initComponent.call(this);
            
            this.imagePanel = this.items.itemAt(0);
        },
    
        afterRender: function(ct) {
            /* XXX This doesn't work because the imagePanel is not present in the DOM! */
            Ext.DomHelper.append(this.imagePanel.body.dom, {
                tag:'div',children:[{
                    tag:'img',src:this.img
                    }]
            });
            return;
        },
    
        ...
    I guess I could make yet another panel extension for just holding the image and do the manipulation in the onRender or afterRender of that panel, but that seems like such a waste. Is there a better way?

    Thanks,
    Brandon
    Attached Files
    Last edited by bdurette; 25 Jul 2008 at 10:59 AM. Reason: Update attachment to include image and suggested use of the html attribute on region

  2. #2
    jay@moduscreate.com's Avatar
    Join Date
    Mar 2007
    Location
    Frederick MD, NYC, DC
    Posts
    16,353
    Vote Rating
    79
    jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all

      0  

    Default


    why not just include the image as html : "<img src='" + this.img '">" in the center panel?

  3. #3
    Ext JS Premium Member
    Join Date
    Jun 2007
    Posts
    13
    Vote Rating
    0
    bdurette is on a distinguished road

      0  

    Default Extending Panel: How can I manipulate the layout regions?

    Extending Panel: How can I manipulate the layout regions?


    why not just include the image as html : "<img src='" + this.img '">" in the center panel?
    Thanks for the suggestion. I tried that and while it does seem to put that HTML in the body of the panel, it's still not clear to me when and how I can manipulate the contents of the layout regions. Ultimately, this example is highly simplified test code. I want to be able to further modify the contents of this panel at runtime, but this was just the first step.

    Having done what you suggest, I also now discover that there must be another bug in my code that is causing the panel not to be laid out in the proper location. Firebug shows it being in the top-left as opposed to below the stub box component that makes up the north region of its parent. I'm reattaching the example code as at the very least, the image was missing. I'm off to try to figure out what that might be.
    Attached Files

  4. #4
    jay@moduscreate.com's Avatar
    Join Date
    Mar 2007
    Location
    Frederick MD, NYC, DC
    Posts
    16,353
    Vote Rating
    79
    jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all

      0  

    Default


    you can do Ext.getCmp('yourPanelId').update('some html fragement')

  5. #5
    Ext JS Premium Member
    Join Date
    Jun 2007
    Posts
    13
    Vote Rating
    0
    bdurette is on a distinguished road

      0  

    Default Thanks

    Thanks


    Thanks Jay,

    Seems to basically work now with a few tweaks. Now we'll see if I can expand it to be the entire widget I'm looking to build. Not to hijack my own thread, but on the layout issue I mentioned earlier, I changed the Viewport declaration in my test HTML file and I'm a bit nervous about the change I had to make:

    HTML Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Test of Image Panel</title>
    <link rel="stylesheet" type="text/css" href="../../../ext/resources/css/ext-all.css"></link>
    <script type="text/javascript" src="../../../ext/adapter/ext/ext-base.js"></script>
    <script type="text/javascript" src="../../../ext/ext-all-debug.js"></script>
    <script type="text/javascript" src="cp.js"></script>
    <script type="text/javascript">
    Ext.onReady( function() {
        var vp = new Ext.Viewport({
            layout:'border',
            items:[
                new Ext.BoxComponent({
                    region: 'north',
                    el: 'north',
                    height: 32,
                    border: false,
                    split: false
                }), 
                new Test.ImagePanel({
                    el: 'center',
                    region: 'center',
                    img: 'a.jpg',
                    autoScroll: true,
                    split: true
                })
            ]
        });
    });    
    </script>
    </head>
    <body>
    
    <div id="north">Some stub area to test layout.</div>
    <div id="center"></div>
    </body>
    </html>
    You can see I use an "el" configuration parameter to configure my stubbed out BoxComponent and also my ImagePanel. This seems to make it render in the correct place, but since that's not a documented configuration parameter, I'm not sure I should be doing it. I got the idea from one of the examples I found on here or on Saki's site, I'm not sure which. Should I be concerned? Is there a different way to get it to render correctly?

    Thanks again,
    Brandon

  6. #6
    jay@moduscreate.com's Avatar
    Join Date
    Mar 2007
    Location
    Frederick MD, NYC, DC
    Posts
    16,353
    Vote Rating
    79
    jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all

      0  

    Default


    I personally dislike the use of the private parameter el.

  7. #7
    Ext JS Premium Member
    Join Date
    Jun 2007
    Posts
    13
    Vote Rating
    0
    bdurette is on a distinguished road

      0  

    Default


    I agree, using private parameters is not advisable. I managed to solve this issue by using applyTo for both the BoxComponent and the ImagePanel. I guess I was mislead by the example code I started with and was using el on the BoxComponent. I think this caused it not to render correctly with respect to the ImagePanel that was properly using applyTo.

    Thanks again for all the help.

  8. #8
    Ext JS Premium Member
    Join Date
    Jun 2007
    Posts
    13
    Vote Rating
    0
    bdurette is on a distinguished road

      0  

    Default When are DOM elements available

    When are DOM elements available


    Well, I've gotten further, but I remain perplexed on the original question, which has bitten me in other ways (as I originally expected). The question is, when do the DOM elements for a panel appear in the DOM? Is there a callback method (i.e., from a template method) that is guaranteed to occur after this? Is there an event I can listen for? I need to explicitly change the size of some div elements after they are rendered, but I don't know when they are actually in the DOM.

    In my panel subclass I have:

    Code:
        initComponent : function() {
            var rid = this.rightImgId = Ext.id();
            var lid = this.leftImgId = Ext.id();
    
            // --- snip out construction of this.slider and this.toggleButton
                
            // Configure the layout for this panel
            Ext.apply(this, {
                layout: 'border',
                items: [{
                    region: 'center',
                    border: false,
                    titlebar: false,
                    deferredRender: false,
                    html: '<div id=\"' + lid + '" >' + 
                            '<img  src="' + this.leftImg + '" />' +
                          '</div><div id=\"' + rid + '" >' +
                            '<img  src="' + this.rightImg + '"/>' +
                          '</div>',
                    autoScroll: true
                    },{
                        region: 'south',
                        items: [ this.slider, this.toggleButton ]
                    }
            ]});
    
            // --- snip out additional inconsequential initialization
    
            Test.ImagePanel.superclass.initComponent.call(this);
        },
    Given the above initialization code, when is it safe to invoke
    Code:
    Ext.get(this.leftImgId)
    and expect to get an element back? I've tried (again) to do this in afterRender, but none of the DOM elements are available.

Thread Participants: 1