Login Register

TabContainer first tab rendering incorrectly in all browsers

 Please forgive me if this has been asked and answered before.

I am creating TabContainer children programmatically in my application.   Consistently, in IE7 and FireFox 2 and 3, the first tab child which is created, the tab image renders incorrectly, with the content directly behind the tab itself in the z-axis.

Example rendering of the first tab over the content:
http://alpha.jenkinsmd.com/images/alpha_jenkinsmd_com/12/r_dojo-image1.p...

As soon as a second tab control is added, the rendering is correct:
http://alpha.jenkinsmd.com/images/alpha_jenkinsmd_com/12/r_dojo-image2.p...

Even when the user deletes all but one tab, the rendering remains correct. However, once a single tab is added back, the problem re-appears.

I have tried experimenting with tabContainer.startup() and contentPane.startup() where those are of course the TabContainer and ContentPane children respectively, but this does not seem to have any effect no matter which order I put the code in. If I understand correctly, addChild() should be calling startup() in any case.

I am using the Tundra theme, since I understand it is the most complete, and downloading my code from the AOL content network.

Below my signature, I am putting the markup and code.

If you know what I am doing wrong, please let me know.

Thanks very much.

---Scott Jenkins

Dojo Inclusion with Stylesheets

<script type="text/javascript">djConfig = { isDebug: false, parseOnLoad: true };</script><script type="text/javascript" src="http://o.aolcdn.com/dojo/1.1.0/dojo/dojo.xd.js"></script><!-- <script type="text/javascript" src="/FCKeditor/fckeditor.js">
</script> --><style type="text/css">      @import "http://o.aolcdn.com/dojo/1.1.0/dijit/themes/dijit.css";      @import "http://o.aolcdn.com/dojo/1.1.0/dijit/themes/tundra/tundra.css";      @import "http://o.aolcdn.com/dojo/1.1.0/dojo/resources/dojo.css";      @import "./mojo.css";</style>
<script language="JavaScript" type="text/javascript">
dojo.require("dojo.parser");

dojo.require("dijit.Menu");
dojo.require("dijit.TitlePane");
dojo.require("dijit.Tree");

// layouts used in page
dojo.require("dijit.layout.AccordionContainer");
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.layout.TabContainer");
dojo.require("dijit.layout.BorderContainer");
dojo.require("dijit.Dialog");

dojo.require("dijit.form.Button");

// scan page for widgets and instantiate them
dojo.require("dojo.parser");   
</script>

Markup for Dijits

<div id="outerFramework" dojoType="dijit.layout.BorderContainer">
        <div id="topPane" dojoType="dijit.layout.ContentPane" region="top"
                style="height:4em; padding-left:1em;" >

                <h1>Dojo Test and Experiment</h1>
        </div>
        <div id="innerFramework" dojoType="dijit.layout.BorderContainer" region="center">

                <div dojoType="dijit.layout.AccordionContainer" duration="200"
                        minSize="20" style="width: 300px;" id="leftAccordion" region="leading" splitter="true"
                        style="background-color:#99FFCC">
       
                        <style>
                        .menuitem {
                                width:15em;
                                margin:0.5em 0.1em 0.5em 0.0em;
                                text-align:center;
                        }
                        .menu item:hover {
                                color:blue;
                                cursor:hand;
                        }
                        </style>
                        <div dojoType="dijit.layout.AccordionPane" title="Views">
                                <button class="menuitem" dojoType="dijit.form.Button" label="Dummy Page" onclick="addTab('Dummy', '/dojotest.nsf/DummyPage?OpenPage')"></button>
                                <button class="menuitem" dojoType="dijit.form.Button" label="Widgets" onclick="addTab('Widget', '/dojotest.nsf/Widget1Form?OpenForm')"></button>
                                <button class="menuitem" dojoType="dijit.form.Button" label="Text Areas" onclick="addTab('text Areas', '/dojotest.nsf/Widget2Form?OpenForm')"></button>
                                <button class="menuitem" dojoType="dijit.form.Button" label="Controls" onclick="addTab('Controls', '/dojotest.nsf/Control1Form?OpenForm')"></button>
<!--
                                <button class="menuitem" dojoType="dijit.form.Button" label="Rich Text Editor" onclick="addTab('Rich Text Editor', '/dojotest.nsf/RteForm?OpenForm')">

</button>
-->
                                <button class="menuitem" dojoType="dijit.form.Button" label="Prototype Comparison" onclick="addTab('Prototype Comparison', 'http://blogresource.jenkinsmd.com/PrototypeDojo.html')"></button>

                                                       
                        </div>
                        <!-- Note the hide/when which restricts this to [Administrators] role -->
                </div><!-- end leftAccordion -->
                <div dojoType="dijit.layout.TabContainer" region="center" id="tabPane"></div><!-- end tabPane -->
        </div><!-- end of innerFramework -->
        <div
</div>
<!-- end outerFramework -->

JavaScript which creates Tabs

function addTab(title, resource) {

        //alert('addTab:  title=' + title + '; resource=' + resource);
        if (typeof(title) !== "string") {
                throw "addTab requires title parameter as a string";
        }
       
        if (typeof(resource) !== "string") {
                throw "Only urls supported for the resource so far...";
        }
       
        var iframe = createIframe(resource);
               
        var contentPane = new dijit.layout.ContentPane({
                closable: true,
                title: title
        }, dojo.doc.createElement('div'));
       
        contentPane.setContent(iframe);
       
        if (contentPane === null) {
                alert('null contentPane');
                return;
        }       
       
        var tabContainer = dijit.byId('tabPane');
        tabContainer.addChild(contentPane);
        tabContainer.selectChild(contentPane);

// See  http://dojotoolkit.org/forum/dijit-dijit-0-9/dijit-support/create-entire-tabcontainer-tabs-programmatically
 
        //tabContainer.layout();
}

same problem here

i'm encountering the same problem... looks like when a child is added, the child does not calculate the top by checking its own tab height. i have another child with a tab of taller height. When this child (2nd) is added after a child of normal height (1st), it doesn't re-calculate (it only consider tab height of 1st) to move the content downward. When another child of normal height (3rd) is added again, the tab-container re-calculate (looks like it consider tab heights of 1st and 2nd) and move the content downward to fit the 2nd tab.

workaround (hack)

One trick I use is if the tab container doesn't have children then after I've added my tab I add then remove a new tab.

2nd tab workaround - timeout required

Thanks for the workaround... I have something working around the problem now.

I had actually tried adding a second tab previously, then removing it. But then both tabs were mis-rendered.

Inspired by your post, I realized the only difference between the tabs created programmatically and the ones done through user interaction was timing (since I call the same addTab() function in my application in either case).

So, I tried it with a timeout, and that has a good workaround. This is code from my application, but I trust the variable names make their purpose obvious...

// Work around for tab rendering bug when there is only one tab.
        // some timeout appears to be required for this to work
        setTimeout(function () {
                if (tabContainer.getChildren().length === 1) {     
                        var dummyPane = new dijit.layout.ContentPane({
                                id: 'mojoDummyPane' + tabId,
                                closable: false,
                                title: ''
                        }, document.createElement('div'));                 
                        tabContainer.addChild(dummyPane);
                        tabContainer.removeChild(dummyPane);
                };
        }, 20);

I think the fact that this work around works indicates it really is some sort of bug. Hopefully, I can figure out how to report it formally now.

Entered bug: Ticket #7015

I have put in a formal bug for this ; Ticket #7015

test case

OK Scott, I see your code above but please put that into a test file and attach it to the ticket (#7015), and then reopen the ticket.

Try to get a smaller test case w/out using BorderContainer or whatever that createIframe() function is.

Thanks.

=========
Bill Keese
Project Lead (aka BDFL) of Dijit

it might be worth pointing out

... though I'm not sure if effects this example. CSS and @import resources dont effect addOnLoad, so there is a possibility the TabContainer is attempting to calculate the height of the tab before the css/paddings/margins have been applied (which would cause it to be 0px high, and render funny). Could you try just moving the [style] tag above the [script] tag loading dojo.js, to send the css off loading before the synchronous script tags are run?

thanks scott.a.jenkins your

thanks scott.a.jenkins

your code is functional :)