Home > Ajax > dcomments.blogs.d.dojo_toolkit_blogs  [ Add to favorite]  Print Message

Widget.attr()


Dojo 1.2 will sport a nice API standardization for widgets. Widget.attr() is now the standard interface for setting/getting all widget attributes. For example:

myTitlePane.attr('title', 'hello world'); // set title
var dis = myButton.attr('disabled'); // find out if button is disabled
myDateTextBox.attr('value', new Date()); // set to the current date

It also supports a hash API like dojo.attr(), for setting multiple attributes:

myInput.attr({ tabIndex: 3, disabled: true, value: 'hi'});

Notes for widget developers:

The first thing to think about as a widget developer is that all the documentation for an attribute needs to go next
to the attribute definition, even when you need special documentation about how attr() is performing for that
widget.

// value: Date
//     The date picked on the date picker, as a Date Object.
//     When setting the date on initialization (ex: new DateTextBox({value: "2008-1-1"})
//     or changing it (ex: attr('value', "2008-1-1")), you  can specify either a Date object or
//     a string in ISO format

The second thing is that when writing or extending a widget now you need to think of a "holy trinity" for each widget attribute:

  1. initialization
  2. setter
  3. getter

Some attributes can only be specified at initialization time, but for most of them, they can be changed after initialization, and users can always get the
value at any time, which means that some of the paradigms we've been using up 'till now need to be changed. For example, you might have had a template
like this:

<button>$</button>

That's compact and new myButtonWidget({label: 'hi'}) works fine, but myButtonWidget.attr('label', 'bye') doesn't.

So, instead, you should be supporting this through the enhanced attributeMap in the 1.2 release.
You should think of attributeMap as a binding from widget attribute to DOM nodes. Previously
in 1.1 it could only map widget attributes to DOM node attributes, but now in 1.2 it can map to
innerHTML (like above) too.

So your attributeMap should map from the widget attribute to the DOM node innerHTML. You can
see this in action for TitlePane:

attributeMap: dojo.mixin(dojo.clone(dijit.layout.ContentPane.prototype.attributeMap), {
        title: {node: "titleNode", type: "innerHTML" }
}),

(the fancy mixin stuff is so TitlePane's attributeMap has everything that ContentPane has,
plus this additional command).

It also supports class attributes like iconClass, see Menu for an example of both in action:

attributeMap: dojo.mixin(dojo.clone(dijit._Widget.prototype.attributeMap), {
        label: {node: "containerNode", type: "innerHTML"},
        iconClass: {node: "iconNode", type: "class" }
}),

Custom setters/getters

When you have an attribute where setting/getting it is more complicated than attributeMap can
handle, you need to write custom getters/setters for it. The naming convention is _setFooAttr() and
_getFooAttr(). attr() will automatically detect and call these custom setters.

Custom setters are quite common. Usually you don't need a custom getter (as the default action
for attr('foo') is to access Widget.foo), but for something like Editor where it's impractical to constantly
keep Editor.value up to date, writing a custom _getValueAttr() accessor makes sense.

postCreate()
The custom setters listed above, plus every entry in attributeMap, is applied during
widget creation (in addition to whenever someone calls attr('name', value)).
So, much of the code you previously had in postCreate() can go away.

Note that the application happens after buildRendering() but before postCreate(), so
you need to make sure that none of that code is dependent on something that happens
in postCreate(), or later. This in particular is an issue for any widgets that depend on timeouts
for setup, which need to have special code to handle when _setDisabledAttr() etc. is
called during startup.

Anyway, all this code is available in trunk now so I encourage you to take it for a test drive.
We are still working out some kinks so now's a great time to give feedback on it, to make sure
that the 1.2 release is solid. Thanks!

Bill

Wed,
20 Aug 2008
Original article here Author :bill