Dojo TabContainer: beating the wrap
Posted by Shane O'Sullivan on 4 April, 2009
One of the features of the Dojo Ajax Toolkit’s TabContainer that always bugged me was that, once there were too many tabs to fit horizontally in the widget, they’d wrap around, like you can see in the picture below.

Wrapping Tabs
It would have been far nicer for them to not wrap, and instead smoothly scroll, using either a menu to select them (like Firefox), or providing buttons to make the list of tabs slide right and left.
So, after much work, I’m just about finished upgrading the TabContainer with two new TabControllers:
- dijit.layout.TabController – the default widget, which places a single button to the right of the tabs, and shows a menu when you click it. This is very similar to how many browsers deal with tabs.
- dijit.layout.SlidingTabController – an optional widget, which places a button to left and right of the tabs, and slides the list left and right.
The video below shows the two widgets in action.
The upgrade is almost complete, and should hopefully make it into the upcoming 1.3.1 release of Dojo.
Update: the changes could not be put into 1.3.1, as that was only for bug fixes. It will be in 1.4 instead</b
Uxebu.com - JavaScript addicts » Dojo TabContainer: beating the wrap said
[...] Dojo TabContainer: beating the wrap [...]
Wolfram Kriesing said
Great stuff, this is such a relief! Thanks a lot! And it looks so slick, as we are used to from you!
Awesome.
Chris Barber said
Awesome! I’ve wanted this for so long!
For the SlidingTabController, it would be cool if the left slider button when all the way to the left and the right slider button when all the way to the right had an additional class that allows you to make the button look disabled since it can’t slide any further in the direction.
Crazy idea, what are your thoughts about tying the mousewheel to the tabs so they could slide with the mousewheel like Firefox does?
Great work!
Shane O'Sullivan said
@Wolfram thanks a lot
@Chris, that extra class is one of the small things that remain to be done, e.g. adding a class called ‘tabScrollDisabled’. It should be in the final patch.
Nathan Toone said
Ooh – what ticket do yo have a patch against? I’d love to patch my code with that and test it out…
Nathan Toone said
9004 – I found it.
Alex Russell said
This is great stuff! The tabs wrapping has been one of my biggest continual UI frustrations with Dijit. Thank you so much for fixing it.
Shane O'Sullivan said
@Alex, you’re very welcome – we’re upgrading to Dojo 1.3 from 0.4.2 at work, and I wouldn’t even try to convince the higher up guys to let me use a wrapping TabContainer, so it had to be done. I can imagine quite a few other people are in the same position.
Shane
Nikolai Onken said
Hi Shane,
this is awesome stuff!! One little suggestion, I’d pass in a flag e.g. overflow=”scroll” (or something similar) so we keep the amount of widgets low.
Does the patch permit that?
Nikolai
Dom Derrien said
Thanks for fixing it!
Once, I did use the
TabContainerin an environment that required the wrapping because the console user wanted to see all possibilities at the first glance. Because the console was displayed on a large screens (1900px wide), loosing real-estate with 2 or 3 rows of tabs was not an issue.I all other situations, keeping the tab number low what a constraint.
Not anymore;)
A+, Dom
Shane O'Sullivan said
Nikolai,
The patch already contains that exact attribute for that purpose.
I still separate it into two widgets, but they’re auto required for you
Chris Barber said
Does the SlidingTabContainer break accessibility?
It would be nice if there was a better way to put icons in the tabs. I think the only way to have different icons in each tab is to do title=”Hello” or extend the TabController and TabButton and set a new template… which sucks.
Shane O'Sullivan said
@Chris, as far as I can see, it doesn’t break accessibility. It still uses the same tabs, which are still accessible using keys.
I agree about the icons, but that would be another enhancement. Feel free to file a bug, or even a patch
Les said
This looks really nice… is there a way to rearrange tabs by dragging as e.g. in Chrome?
Shane O'Sullivan said
@Les, no, reordering of tabs is not included in this work. It’s not a bad idea however, so feel free to create an enhancement request at bugs.dojotoolkit.org
Peter Higgins said
awesome work shane!
Sarris said
At this moment I trying to develop the same as you already did, I’m just a starter with DoJo sow it takes me a lot of time just to get a (basic) understanding of it all. Where can I find a sample of the work you already did so I can try it out here?
Shane O'Sullivan said
Hi Sarris,
A Subversion patch is attached to the ticket http://bugs.dojotoolkit.org/ticket/9004 , which you can apply to the Dojo source, if you have it checked out
Shane
Sarris said
checked out the toolkit using svn and applied the latest patch … or should I apply all patches?? it is now complaining about missing the SlidingTabController.js
Sarris said
thats when I open the Dijt Theme tester
Shane O'Sullivan said
Apologies, I accidentally left SlidingTabController out the patch?
I’ve attached a new patch containing it.
Sarris said
Hi Shane,
Is it also possible to combine the slider and the dropdown, cause we want it like that?
Shane O'Sullivan said
@Sarris,
No, that’s not possible.
Sarris said
I’ve made a new controller, menuslidetabcontroller and now i’ve got the slider and the menu together … but for one thing I cannot get the menu button to work .. can click on it but it doesn’t show up … is there something I need to be aware of concerning that menu button?
Shane O'Sullivan said
Well, you have to tell the menu to open when it is clicked
Shane
Sarris said
and how do i do that, I tried connect to the onClick but don’t know what to supply as function
Sarris said
ow got it
Sarris said
I’ve just placed this slidertab into a portal page which is accessed using IE 6, when clicking on a unselected tab I can see it getting selected but it doesn’t change the content of the tabpane to content which should be visible .. any clue to where that problem could reside.
Sarris said
Hmm when looking closer at it, it looks like it doesn’t create the tabs .. I see the content of both tabs always … will this be due to IE 6
Shane O'Sullivan said
You have to call the onClick() method of the TabButton. This is normally triggered by an actual click, but you have to fake it. I found the same problem with my implementation.
Sarris said
You mean when the page is loaded in the onLoad method I should place a call to simulate a onClick on the tab?
Sarris said
I tried doing it in the onlOad of the page, but now I’m wondering after reading your post again .. if it should be a permanent part of code which is always callend when clicking the tab button .. if so then I’m not completely aware on how to accomplish this.
Shane O'Sullivan said
Sarris, as you guessed, it should be called whenever a tab is selected artificially, that is, not by an actual mouse click. If you look in my patch, the code is there – you have to retrieve a referance to the tab, and call tab.onClick()
Sarris said
Did you upload a new patch then? The last patch I see is the one in which you added the slidingTabController
Shane O'Sullivan said
No, the existing patches include a call to the tabs onClick method. Just do a search for “onClick” in the patch
Sarris said
In the onSelectChild I see two times a call to tab.onClick … when I place an alert just before both of them I can see the last tab.onClick is called .. so it looks like this is what you suggested .. but if it is then is doesn’t work .. or do I mis interpret the code?
Sarris said
I’ve got some weird behaviour because of the nowrapTabStrip style, this style only defines a width of 50000px. When using the sliding tabs in a portal enviroment the portlets are initally (after parse by dojo) of the size of the nowrapTabStrip and after a while the size of the portlet becomes like it should. But this is not what we want, do you have any clue in solving this problem, I’ve tried some things but can’t get rid of it.
Shane O'Sullivan said
Sarris,
This issue is fixed in the code I currently have I think. The problem is due to “when” classes are applied to the DOM nodes. The DIV surrounding the nowrapTabStrip should always have overflow:hidden set, but in the original patch, this was only set after the widgets construction.
When I submit a new patch in a week or so, this fix will be included.
Shane
itamar said
hi Shane
I’m new in dojo and could not get this thing to work, unfortunately, as it looks very good on your presentation video.
I’ve downloaded the full dojo kit 1.3.1 locally.
The code looks something like this in the head tag:
@import "../javascripts/dijit/themes/nihilo/nihilo.css";
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.layout.TabContainer");
dojo.require("dijit.form.Button");
And in the body tag:
First Tab
Second Tab
adding more ContentPane DIVs here
What am I missing here?
many thanks to any help.
itamar said
yep, I’m new to writing comments also…
Let’s try again:
head:
[style type="text/css"]
@import "../javascripts/dijit/themes/nihilo/nihilo.css";
[/style]
[script type="text/javascript"]
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.layout.TabContainer");
dojo.require("dijit.form.Button");
[/script]
body:
[div id="mainTabContainer" class="nihilo" dojoType="dijit.layout.TabContainer" style="height:100%;position:relative;top:-29px;"]
[div id="tab1" dojoType="dijit.layout.ContentPane" title="First Tab" selected="true" closable="false"]First Tab[/div]
[div id="tab2" dojoType="dijit.layout.ContentPane" title="Second Tab" closable="false"]Second Tab[/div]
[/div]
itamar said
(last comment, I swear. sorry for the mess)
By “not working” I mean that the tabs are not wrapped, they are places some above others, and there is no sign of a TabController or a SlidingTabController.
Shane O'Sullivan said
Hi Itamar,
Unfortunately the change could not be put into 1.3.1, as only bug fixes were allowed in. It will be in 1.4 instead.
Shane
Jean said
Hi Shane,
I did not find SlidingTabController.js anywhere !
the patch files do not contain it.
I need this patch urgently. Could you please verify the patch file because the miss this file
Thank you
Jean.
Shane O'Sullivan said
Hi Jean,
That file is no longer required. The widget that it used to contain has been rolled into the main tab controller widget.
Simply download the patch as it is and it will work
Shane