1. #1
    Sencha User
    Join Date
    Dec 2008
    Posts
    20
    Vote Rating
    0
    ogradyjd is on a distinguished road

      0  

    Default [Answered] ExtJS 4.1 layout problem

    [Answered] ExtJS 4.1 layout problem


    All I've done here is take the example from the docs for a column layout panel with two child panels, and stick that in a window component, and the result is the window not centering itself on the page anymore and what looks to be broken title bars for the panels.

    I am having a bear of a time trying to get this modal thing I'm working on to render right. I've tried using straight-up html content in the window, but the window does not respect the dimensions of the child container div. So now I'm trying to go the route of all ExtJS content in the modal, and as soon as I start adding panels like below, I get strange results.

    Code:
    var newModal = Ext.create('Ext.Window',{
        renderTo: Ext.getBody(),
        id: 'hello',
        title: 'Modal Window Title',
        modal: true,
        border: 0,
        items: [{
            xtype: 'panel',
            title: 'Nested Panel',
            layout: 'column',
            items: [{
                xtype: 'panel',
                title: 'Child Panel 1',
                height: 100,
                columnWidth: 0.5,
                html: 'child panel 1'
            },{
                xtype: 'panel',
                title: 'Child Panel 2',
                height: 100,
                columnWidth: 0.5,
                html: 'child panel 2'
            }]
        }]
    });
    newModal.show();
    Last edited by ogradyjd; 16 Jun 2012 at 10:12 AM. Reason: Question was answered

  2. #2
    Sencha - Support Team scottmartin's Avatar
    Join Date
    Jul 2010
    Location
    Houston, Tx
    Posts
    8,910
    Vote Rating
    443
    scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future

      0  

    Default


    I would suggestion something like:

    Code:
    Ext.create('Ext.window.Window', {
        height: 200,
        width: 300,
        layout: {
            align: 'stretch',
            type: 'hbox'
        },
        title: 'My Window',
        items: [
            {
                xtype: 'panel',
                title: 'My Panel',
                flex: 1
            },
            {
                xtype: 'panel',
                title: 'My Panel',
                flex: 1
            }
        ]
    }).show();‚Äč
    Regards,
    Scott.

  3. #3
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,568
    Vote Rating
    307
    skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future

      4  

    Default


    To elaborate a little...

    The width and height of each component has got to come from somewhere. Sometimes components have a natural size, for example a button should wrap around its text, but in most cases there isn't any such size. In your example you haven't given your window a size so it will attempt to wrap around its children. However, you haven't given the child panel a size either, so it will also try to wrap around its children. Those two children have a fixed height but their widths are relative to their parent (0.5 each). Now we have a circularity and there's no way for the layout system to determine the widths of all the components.

  4. #4
    Sencha User
    Join Date
    Dec 2008
    Posts
    20
    Vote Rating
    0
    ogradyjd is on a distinguished road

      0  

    Default +5

    +5


    skirtle:

    That was one of the most lucid and complete answers I've seen on these boards. It always annoys me when I get an answer which lacks any kind of explanation, since that doesn't help me learn how not to make the same mistakes again. Now that I understand about the containers needing dimensions, it makes perfect sense. Please keep up the good work.

    I guess I have one more question then:
    In the example I gave, I set the html property to some text. I would have thought that the content of those child panels would result in widths, and the window would then shrink-wrap around them. Based on what you said, though, I'm thinking now that the column layout bases itself on the parent width and ignores the fact that the children actually have width from their own content. Am I right? - and if so, what's the best layout for shrink wrapping around the ultimate children's content, which will be panels with html divs?

  5. #5
    Sencha - Support Team scottmartin's Avatar
    Join Date
    Jul 2010
    Location
    Houston, Tx
    Posts
    8,910
    Vote Rating
    443
    scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future

      0  

    Default


    @ogradyjd

    Skirtle is always very helpful in the explanations.

    It always annoys me when I get an answer which lacks any kind of explanation, since that doesn't help me learn how not to make the same mistakes again.
    Please understand that we would like to sit down and explain each answer in detail, but when you have hundreds of posts to manage, it can become very time consuming. The standing rule is that we provide the answers needed and if you need additional information, we will continue from there.

    Scott.

  6. #6
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,568
    Vote Rating
    307
    skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future

      0  

    Default


    Quote Originally Posted by ogradyjd View Post
    I guess I have one more question then:
    In the example I gave, I set the html property to some text. I would have thought that the content of those child panels would result in widths, and the window would then shrink-wrap around them...
    Good question. If I've understood correctly, you're asking why does the HTML set for the two columns not provided a natural width for the containers to wrap around.

    It took me a little while to figure out what was going wrong here.

    If you take a look at the source to column layout:

    http://docs.sencha.com/ext-js/4-1/so...ntainer-Column

    you'll see this:

    Code:
    getItemSizePolicy: function (item) {
        if (item.columnWidth) {
            return this.columnWidthSizePolicy;
        }
        return this.autoSizePolicy;
    },
    The method getItemSizePolicy is responsible for deciding where the size of a component will come from. Basically there are two choices: either the component tells the layout how big it will be or vice versa. In your example you're setting columnWidth so we'll end up with a columnWidthSizePolicy. That policy is a few lines up and looks like this:

    Code:
    columnWidthSizePolicy: {
        setsWidth: 1,
        setsHeight: 0
    },
    This means that the layout is responsible for setting the width whereas the component is responsible for setting the height. In other words, the width won't shrink-wrap its contents.

    When you think about it this makes sense. How can a column shrink-wrap the width of its content and also have a columnWidth of 0.5? That doesn't make sense.

    On the face of it you should be able to fix this problem just be removing the columnWidth setting. I tried this but it didn't actually work. The columns rendered correctly but the surrounding panels didn't. My first thought was that you're missing a layout on your window (should probably be set to 'fit') but that didn't help either. It might be a bug in column layout though this type of usage might just not be supported, I'm not sure.

    Column layout largely exists for historical reasons and it isn't used much in practice. I'd generally use hbox for something like this. With an hbox the same reasoning covered above applies: you can't specify both a flex and expect it to wrap the contents. So it might look something like this:

    Code:
    var newModal = Ext.create('Ext.window.Window', {
        //renderTo: Ext.getBody(), <- not needed, get rid of this
        //id: 'hello', <- fixed ids are evil, highly recommended not to use them
        title: 'Modal Window Title',
        modal: true,
        border: 0,
        resizable: false, // <- for shrink-wrapping like this you'll probably want to disable resize
        layout: 'fit', // <- the default layout is pretty useless, looks like you want fit
        items: [{
            xtype: 'panel',
            title: 'Nested Panel',
            layout: 'hbox', // <- changed to hbox
            items: [{
                xtype: 'panel',
                title: 'Child Panel 1',
                height: 100,
                html: 'child panel 1'
            }, {
                xtype: 'panel',
                title: 'Child Panel 2',
                height: 100,
                html: 'child panel 2'
            }]
        }]
    });
    
    newModal.show();
    This seems to work fine. The inner panels will wrap their contents and everything else will wrap accordingly.

  7. #7
    Sencha User
    Join Date
    Dec 2008
    Posts
    20
    Vote Rating
    0
    ogradyjd is on a distinguished road

      0  

    Default Thanks again.

    Thanks again.


    @scottmartin
    Still annoying... but perfectly understandable considering what you said. Sorry about the quip. Maybe a hard example of shrink wrapping in the Panel docs would be in order - considering that shrink wrapping is one of those holy grails of web layout?

    @skirtle
    Thanks again for the long explanation. Once I'm more well versed in ExtJS dev, I'll be sure to do the same for someone else. Your note about evil IDs is good, but I've found that I have to use a hard ID for the modal Window so that I can change the styling of the child Slider components without affecting any other sliders my site might use. For all else I am now switching to itemID.

  8. #8
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,568
    Vote Rating
    307
    skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future

      0  

    Default


    I raised the column layout shrink-wrapping problem with someone on the ExtJS dev team and his initial view was that it's probably a bug. I'll be filing a bug report shortly but in the meantime you're probably better off using hbox anyway.

    Regarding static ids, you shouldn't need them for styling either. Have you tried using the cls config (or maybe bodyCls) to add a CSS class to your window instead? If I've understood your requirement correctly then that should allow you to achieve the same effect.

  9. #9
    Sencha User
    Join Date
    Dec 2008
    Posts
    20
    Vote Rating
    0
    ogradyjd is on a distinguished road

      0  

    Default


    Fully agreed. Just adding some html to a component xtype and trying to let the layout shrink around it seems like hit or miss. And then you get things like this from my not-that-complex layout:


    Code:
    <div id="panel-1012" class="x-panel x-box-item x-panel-default" style="width: 127px; height: 219px; margin: 0px; left: 0px; top: 12px; "><div id="panel-1012-body" class="x-panel-body x-panel-body-default x-panel-body-default x-box-layout-ct x-docked-noborder-top x-docked-noborder-right x-docked-noborder-bottom x-docked-noborder-left" style="width: 127px; height: 219px; left: 0px; top: 0px; "><div id="panel-1012-innerCt" class="x-box-inner " role="presentation" style="width: 127px; height: 219px; "><div id="panel-1012-targetEl" style="position:absolute;width:20000px;left:0px;top:0px;height:1px"><div id="panel-1013" class="x-panel limitFilterSliderLabelComponentCls limitFilterSliderLabelCls x-box-item x-panel-default" style="width: 65px; height: 219px; margin: 0px; left: 0px; top: 0px; "><div id="panel-1013-body" class="x-panel-body x-panel-body-default x-panel-body-default x-box-layout-ct" style="width: 65px; height: 219px; left: 0px; top: 0px; "><div id="panel-1013-innerCt" class="x-box-inner " role="presentation" style="height: 217px; width: 63px; "><div id="panel-1013-targetEl" style="position:absolute;width:20000px;left:0px;top:0px;height:1px"><div id="component-1014" class="x-component x-box-item x-component-default" style="margin: 0px; left: 0px; top: 0px; ">Impressions</div><table id="multislider-1015" class="x-field limitFilterSliderLeft limitFilterSliderCls limitFilterSliderFormItemCls x-box-item x-field-default x-vbox-form-item x-form-dirty" style="height: 200px; table-layout: auto; margin: 0px; left: 0px; top: 12px; " cellpadding="0"><tbody><tr id="multislider-1015-inputRow"><td id="multislider-1015-labelCell" style="display:none;" valign="top" halign="left" width="105" class="x-field-label-cell"><label id="multislider-1015-labelEl" for="multislider-1015-inputEl" class="x-form-item-label x-form-item-label-left" style="width:100px;margin-right:5px;"></label></td><td class="x-form-item-body limitFilterSliderFieldBodyCls" id="multislider-1015-bodyEl" role="presentation" colspan="3" style=""><div id="multislider-1015-inputEl" class="x-slider limitFilterSliderLeftFieldCls x-slider-vert" aria-valuemin="0" aria-valuemax="75000" aria-valuenow="56250" aria-valuetext="56250" aria-invalid="false" data-errorqtip="" style="-webkit-user-select: text; " tabindex="-1"><div id="multislider-1015-endEl" class="x-slider-end" role="presentation"><div id="multislider-1015-innerEl" class="x-slider-inner" role="presentation" style="height: 186px; "><div style="bottom: 0%; " id="multislider-1015-thumb-0" class="x-slider-thumb"></div><div style="z-index: 10000; bottom: 75%; " id="multislider-1015-thumb-1" class="x-slider-thumb"></div></div></div></div></td></tr></tbody></table></div></div></div></div><div id="panel-1017" class="x-panel limitFilterSliderLabelComponentCls limitFilterSliderLabelCls x-box-item x-panel-default" style="width: 62px; height: 219px; margin: 0px; left: 65px; top: 0px; "><div id="panel-1017-body" class="x-panel-body x-panel-body-default x-panel-body-default x-box-layout-ct" style="width: 62px; height: 219px; left: 0px; top: 0px; "><div id="panel-1017-innerCt" class="x-box-inner " role="presentation" style="height: 217px; width: 60px; "><div id="panel-1017-targetEl" style="position:absolute;width:20000px;left:0px;top:0px;height:1px"><div id="component-1018" class="x-component x-box-item x-component-default" style="margin: 0px; left: 0px; top: 0px; ">Total Clicks</div><table id="multislider-1019" class="x-field limitFilterSliderLeft limitFilterSliderCls limitFilterSliderFormItemCls x-box-item x-field-default x-vbox-form-item" style="height: 200px; table-layout: auto; margin: 0px; left: 0px; top: 12px; " cellpadding="0"><tbody><tr id="multislider-1019-inputRow"><td id="multislider-1019-labelCell" style="display:none;" valign="top" halign="left" width="105" class="x-field-label-cell"><label id="multislider-1019-labelEl" for="multislider-1019-inputEl" class="x-form-item-label x-form-item-label-left" style="width:100px;margin-right:5px;"></label></td><td class="x-form-item-body limitFilterSliderFieldBodyCls" id="multislider-1019-bodyEl" role="presentation" colspan="3" style=""><div id="multislider-1019-inputEl" class="x-slider limitFilterSliderLeftFieldCls x-slider-vert" aria-valuemin="0" aria-valuemax="75" aria-valuenow="0" aria-valuetext="0" aria-invalid="false" data-errorqtip="" style="-webkit-user-select: text; "><div id="multislider-1019-endEl" class="x-slider-end" role="presentation"><div id="multislider-1019-innerEl" class="x-slider-inner" role="presentation" style="height: 186px; "><div style="bottom:0%;" id="multislider-1019-thumb-0" class="x-slider-thumb"></div><div style="bottom:100%;" id="multislider-1019-thumb-1" class="x-slider-thumb"></div></div></div></div></td></tr></tbody></table></div></div></div></div></div></div></div></div>
    Sorry for the formatting. Anyway - there's a few panel targetEl elements in there with a width of 20000px. That is definitely not coming from my code, so something strange is going on in there. Good thing they don't affect the page area horizontal scrolling.

    And yes, I just found all the different cls config entries and I'm playing around with them now while styling. That should negate any use of id for now.

    Anyway, got to start custom styling my sliders now. Thanks again!

  10. #10
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,568
    Vote Rating
    307
    skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future

      0  

    Default


    The 20000px thing is to be expected using an hbox layout. It solves a specific problem that occurs in some edge cases. Say, for example, you have a button in a container where all the widths are determined by the text on the button. If the container starts off too narrow then the text will line wrap and measuring the text's width will give the wrong answer. Slipping a very wide element in between isn't the most elegant solution but it does prevent this crushing effect. Unfortunately there isn't a fast way to add and remove this wide element on demand so it ends up being there all the time.