A collapsible fieldset as dojo widget

Posted by filed under Dojo Love, Goodies to go.

Though many people would disagree, I for one like to use fieldsets to structure complex forms. Even better do I like fieldsets that are collapsible.

As there is no such fieldset with dojo, I decided to write my own widget. While doing so, I learnt an interesting lesson…

First, I wrote it pretty simple, inheriting the widget from dijit._Widget and dijit._Templated. It had a toggle button next to its legend, which could be clicked. The toggle was a simple display none/block change.

But I wanted it to be accessible via the keyboard – so I added a tabIndex and a key handler. Next, I wanted it to be able to hold and parse widgets, so I inherited it from dijit.layout.ContentPane so I could make use of the content setter. Then I wanted it to animate smoothly, so I added animations, and so on… You get the point, I guess. Well, this went on for a while, until I made an unpleasant discovery: My fieldset was almost a clone of dijit.TitlePane. Ugh.

I had put all the time into creating a copy of something, that already existed.

So I inherited the fieldset widget from dijit.TitlePane and ended up with less than 50 lines of code. And it was a matter of minutes to do so. Ok, lesson learned: If you need something that doesn’t exist and you are going to code it – first check if there’s something that behaves similar to what you want. Or similar to what you might want in the future. If I had invested a little more time in thinking about the fieldset widget before starting to code, it would have been obvious that I wanted the above mentioned features one day. And I would have saved a lot of time.

Well, however, here it is: a collapsible fieldset, coming with all the ContentPane goodness (child widgets, remote loading,…).

You can create it via markup (I put it into a namespace called “app”; choose a namespace you like):

<fieldset dojotype="app.Fieldset">
    <legend>Legend</legend>
    Content
</fieldset>

or programmatically:

var fieldset = new app.Fieldset({legend:'dojo fieldset', id: 'someId'},dojo.create('div',{},dojo.body()));

The fieldset takes pretty much the same arguments as dijit.TitlePane. To change the legend, use dojo.attr('legend','Teh new legend'), to change the content dojo.attr('content',content) as usual. To stay close to TitlePane, I left _setTitleAttr() in it, but it is an alias for _setLegendAttr().

The code is simple (after I inherited from TitlePane), I only added a method to setup the legend tag and changed the methods that handle hover states, as the TitlePane’s methods paid no respect to the dijit’s base class. The fieldset is closed by default, but you can add open="true" to the markup (or add open: true to the constructor args) to make it start open. You can style it as you would style any other widget.

The testpage is over here: test_Fieldset.html
Code: Fieldset.js
Template: Fieldset.html

Update: If you have downloaded the code and intend to use it, please re-download it, as I updated a method and fixed a namespace confusion (and added doc).

7 Responses to A collapsible fieldset as dojo widget


  1. Hi,
    It’s a cool……..Thank you…I have searched for the similar solution.

    Here,I create a fieldset.I just want to hide the particular “fieldset” according to a button click that is present in the “fieldset”.How can I do that?I tried the “hide” and “close” method.But it did not give me a solution….I am sending the following code of what I have done.

    dojo.connect(cancelDomain, ‘onClick’, this, function()
    {
    dojo.connect(fieldset,null,this,function(){

    this.hide();
    })
    });


  2. @Sankar:

    Glad you like it! To open/close the Fieldset, you need to call the “toggle” method. Also make sure you are calling the method in the right scope – I don’t know where the ‘this’ keyword in your example points to. I’d recommend a code like this:

    dojo.connect(yourButton,’onclick’,dijit.byId(‘yourFieldsetID’),’toggle’);


  3. Hi Jens,
    Thank you for your reply.Yesterday,I done some thing like this and its work perfectly.Hope you will again come with these type of cool ideas…Thank You..

    dojo.connect(cancelDomain, ‘onClick’, this, function()
    {
    fieldset.attr(“style”, “visibility:none;display:none”);
    parentMailBox.deleteMailBox();
    });


  4. Jens — excellent widget. I can particularly empathise with your “d’oh!” moment :)

    One question tho — I’d love to use your code, but I need to know the terms under which you’re releasing it first :) Are you freely putting it out there for any use without restriction, or are you putting it under a license like the LGPL?

    Sorry for the nitpicky question, but it either ask now or I get spanked later by an auditor… :)


  5. @Chris Weyl

    Thanks! Yeah, that “d’oh” moment really hit me…

    No problem with the question, no one wants avoidable spanking here… ;) The code is licensed under a dual style license: either the new BSD license or the Academic Free License >= 2.1 (I’ve added an according block to the code). So it should pretty much suit your needs, I guess.

    Thanks for using it and enjoy!


  1. […] Dieser Eintrag wurde auf Twitter von wolframkriesing, Karl Tiedt und Jens Arps, Jens Arps erwähnt. Jens Arps sagte: New blog post: A collapsible fieldset as dojo widget – and a lesson learned: http://bit.ly/31I8Ic […]


  2. […] seinem Blog-Beitrag “A collapsible fieldset as dojo widget” berichtet er von seinen Erfahrungen mit dem Erstellen eines neuen Widgets und wie er dabei […]

[Comments are automatically closed after 30 days.]

Comment via Google+