Hacking TabContainer: setTitle extension
by Peter Higgins

A piece of functionality lost in the 0.4 -> 1.x transition of Dojo was the ability to set the Title of a tab pane, based on on a reference to the ContentPane associated with it. It seems a really common an trivial task, but the ambiguity of StackContainer (the foundation of TabContainer) conflicts with what a “setTitle” method would really do on a child …

So I came up with a small solution that works in my case, and I’d like to share it. Expanding on the concept of mucking dijit, we’re going to hack a setTitle method into any pane that is a child of a TabContainer,
as it is added.

So the spoiler, the full code:

dojo.declare("my.TabContainer", dijit.layout.TabContainer, {
	addChild: function(child){
		// summary: same as normal addChild, but this one adds a setTitle
		// method to the ContentPane if it doesn't have one
		this.inherited(arguments);
		if(!child["setTitle"] && child.title){
			dojo.mixin(child,{ 
				setTitle: function(title){
					// summary: set the title 
					this.title = title;
					this.controlButton.containerNode.innerHTML = title || ""; 
				}
			});
		}
	}
});

And now in Cookie fashion, what it does:

We’re making a subclass of the standard dijit.layout.TabContainer, called my.TabContainer. When a pane is added to a TabContainer, or is found during onLoad, the addChild method is being called. Here, we’re overriding the call, calling the inherited addChild (from TabContainer), and then mixing in a new function called setTitle. The if(!child["setTitle"]) prevents the method from being added if a setTitle method already exists (Some widgets have a setTitle method, and all are supported in Dijit, so we’re being safe).

The magic that already makes this possible is this.controlButton, already being mixed into ContentPane (child) from the setup. Its a convenient (public) variable I’d not noticed before, and a quick route to our setTitle mixin.

Notice how “this” changes meaning between the addChild and setTitle function declarations. setTitle will only be called in the scope of the child (dijit.byId("pane").setTitle("foo");), so it refers to it’s own instance. “this” within the addChild function refers to the TabContainer instance, from which addChild is being called.

The same principals apply: we can mix setTitle into an instance, extend TabContainer, or make a subclass. Maybe Neil will follow up with a super-cool way to use dojo.delegate to do this much faster overall …

Tags: , ,

This entry was posted on Friday, June 6th, 2008 at 5:20 am and is filed under Dojo Cookies. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

3 Responses to “Hacking TabContainer: setTitle extension”

  1. psypath Says:

    cool, was looking around for that already. Thanks phiggins.

    I don’t want to make my own class, but stay with dijit.layout.TabContainer.

    >> The same principals apply: we can mix setTitle into an instance, extend TabContainer,

    Means, I could also do this with a dojo.extend(…), right?

  2. dante Says:

    yes. it would be based on the linked “mucking dijit” Cookie, though slightly more difficult. (You can’t over-ride and use this.inherited(arguments) in a dojo.extend, iirc) Maybe something like:

    dojo.connect(dijit.layout.TabContainer.prototype,"addChild",function(child){   
         if(!child["setTitle"]){
             // doit ...
         }
    });
  3. dante Says:

    note: in order to get tabs in markup to have this extension, you need to override ‘_setupChild’ instead of ‘addChild’

Leave a Reply

You must be logged in to post a comment.