Dojo TabContainer: beating the wrap

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
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

47 thoughts on “Dojo TabContainer: beating the wrap

  1. 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!

  2. @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.

  3. Ooh – what ticket do yo have a patch against? I’d love to patch my code with that and test it out…

  4. @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

  5. 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

  6. Thanks for fixing it!

    Once, I did use the TabContainer in 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

  7. 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.

  8. @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 🙂

  9. 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?

  10. 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

  11. 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?

  12. 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.

  13. 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

  14. 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.

  15. You mean when the page is loaded in the onLoad method I should place a call to simulate a onClick on the tab?

  16. 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.

  17. 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()

  18. Did you upload a new patch then? The last patch I see is the one in which you added the slidingTabController

  19. 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?

  20. 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.

  21. 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

  22. 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.

  23. 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]

  24. (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.

  25. 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.

  26. 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

  27. Hi Shane,

    I’m looking for a way to get a vertical slide for my TabContainer or instead that a drop down menu with the tab list, like in the case of an horizontal TabContainer .

    I’m using dojo toolkit v1.4 and when I overflow the width of an “horizontal tabcontainer” (top or bottom) appears a scrollbar in the corners and a menu, but with the “vertical tabcontainer”(left orientation) not occur the same and I need that functionality.

    I don’t yet have enough experience with Dojo to build something from scratch, so please give me an idea for how to get working the vertical slide for my tabcontainer.

    Regards,
    Manuel.

  28. Hello Shane,

    I want to use a custom icon for the left and right scroll and for the tab listing. I needed custom look and feel for the tabs as well and I was able to do that, but I am not able to figure out which classes to override for the scroll icons.

    Thanks in advance.

Leave a reply to Nathan Toone Cancel reply