dojodijit.layout

TabContainer displays Tabs only at windowresize


I want to create a Tabcontainer and fill its TabPage contents programmatically, but the TabPages won't be displayed. So far my Code:

        _buildUI: function () {
            var bordercontainer = new dj_BorderContainer({ style: "height: 100%; width: 100%;", gutters: false, region: "top" });
            var tabcontainer = new dj_TabContainer({ useMenu: false, region: "center", tabposition: "top", doLayout: "false", style: "height: 100%; width: 100%;" });

            for (var i = 0; i < ki_KisConfig.widgets.movingwindow.calccount; i++) {
                var contentpane = new dj_ContentPane({ title: "Calculation " + (i + 1), content: "content", style: "height: 100%; width: 100%;" });

                //contentpane.startup();
                tabcontainer.addChild(contentpane);
            }

            tabcontainer.startup();
            bordercontainer.addChild(tabcontainer);
            bordercontainer.startup();
            do_domConstruct.place(bordercontainer.domNode, this.interface, "first");
            bordercontainer.resize({ h: "265px", w: "432px" });
        },

I've googled around and tried different things. As you cann see I'm setting the doLayout-Property mentioned here. I also use a BorderContainer like mentioned here in the last posting and I'm trying to resize it after creating the TabContainer like mentioned here. It doens't matter if I'm calling the method in the postCreate- or the startup-function of the containing widget.

I'm trying to set the width and height via style or to startup every "sub"widget.

Nothing works and the TabContainer only gets displayed when I'm resizing the browserwindow or resizing it by opening/closing the developertools (F12). If it gets displayed it looks like I want it. The only problem is that the TabList has a size of 0x0 and the same with the TabPaneWrapper when I'm inspecting directly the DOM.

Has anyone any idea?

Edit

After calling startup only on the BorderContainer I get this result: failing layout

The tablist layout is strange and also the content of the programmatic selected tab isn't displayed. Everything is again fine after a window resize:

correct layout

Solution (summary)

I retrieved the best result with defining the BorderContainer and the TabContainer in the HTML-template. Unfortunately the layout of the tablist still failed. This answer delivered the solution for correct tablist layout: My widget didn't contain resize() so I added it and everything is now working fine.

        resize: function() {
            var tabcontainer = dj_registry.byId("tabContainerMW");
            if (tabcontainer) {
                tabcontainer.resize(arguments);
            }
        },

Solution

  • Some notes to your code:

    The region attribute is here not required. Its only used to indicate the position for BorderContainer children.

    var bordercontainer = new dj_BorderContainer({
      style: "height: 100%; width: 100%;",
      gutters: false,
      region: "top"
    });
    

    You don't need to set a width and height on your ContentPane, let this do the TabContainer.

    var contentpane = new dj_ContentPane({
      title: "Calculation " + (i + 1),
      content: "content",
      style: "height: 100%; width: 100%;"
    });
    

    I've created a sample for you, maybe this helps you out.

    require(["dijit/layout/BorderContainer", "dijit/layout/TabContainer",
      "dijit/layout/ContentPane", "dojo/domReady!"],
    function(BorderContainer, TabContainer, ContentPane) {
      
      // first create the BorderContainer without any arguments.
      let bc = new BorderContainer({}, "bc");
      
      // then create your TabContainer with region center.
      let tc = new TabContainer({
        region: 'center'
      }, document.createElement("div"));
      
      // add it to your BorderContainer
      bc.addChild(tc);
      
      
      // then create three tab panes (ContentPane) and add them to your TabContainer
      let cp = new ContentPane({
        content: "My tab pane!",
        title: "My tab title"
      }, document.createElement("div"));
      tc.addChild(cp);
      
      let cp2 = new ContentPane({
        content: "My second tab pane!",
        title: "My second tab title"
      }, document.createElement("div"));
      tc.addChild(cp2);
      
      
      let cp3 = new ContentPane({
        content: "My closable tab pane!",
        title: "My closable tab title",
        closable: true
      }, document.createElement("div"));
      tc.addChild(cp3);
      
      // call startup on your BorderContainer. startup of BorderContainer will call also the startup methods of all children (TabContainer, ContentPane's).
      bc.startup();
    
    });
    body, html {
      height: 100%;
      width: 100%;
      overflow: hidden;
      margin: 0 auto;
    }
    <link href="//ajax.googleapis.com/ajax/libs/dojo/1.4/dijit/themes/tundra/tundra.css" rel="stylesheet"/>
    <script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
    <span class="tundra" style="width: 100%; height: 100%;">
      <div id="bc" style="width: 100%; height: 100%;"></div>
    </span>

    Edit

    As an addition: I was able to create a fiddle, which reproduces the failure. The problem here is that the createDialogContent() method is getting called after the dialog show's up. As I mentioned below in the comments section, it is important to create a dialog's content before showing it.

    In this fiddle (bottom end of code) are two sections, which call both the same methods, just transposed. In the first snippet, the methods are called in the wrong order. Int the second snippet, they're called in the right order.

       // uncomment this
       createDialogContent(); 
       dialog.show();
    
      // comment this
      // dialog.show();
      // createDialogContent();