Archive for April 23rd, 2009

Right now UI widgets need to explicitly declare "getter" functions (methods that return information about the widget rather than manipulate it) with $.ui.widget.getter = 'gettermethod1 gettermethod2'. The reason is that most jQuery plugins are chainable: $(selector).widget('method').css('color','blue') executes method on each element matched, then css('color','blue') on each element. Some plugins and some uses of plugins instead return information about the first element selected, so they cannot be chained, like $(selector).css('color'). For normal methods, the widget code creates a plugin that automatically executes the method named on each element matched, then returns the jQuery object to allow chaining. It uses the getter list to determine which methods should pass their return value from the plugin instead, and only operate on the first element matched.

This is inelegant, and makes my subclassing code less useful, since the getter list cannot be extended easily, only copied or replaced.

This is due to be improved in jQuery 1.7.2 (or at least it's in the latest nightlies): any method that returns this is a "regular" method that, when used as a plugin, should be chainable. Any method that returns anything else is a "getter" that returns that value when used as a plugin.

Thus, in the widget tutorial, we no longer need the line $.ui.green4.getter = "getLevel"; and getLevel remains unchanged, but setLevel needs to be changed to:

    setLevel: function (x) {
        var greenlevels = this._getData('greenlevels'); 
        var level = Math.floor(Math.min(greenlevels.length-1, Math.max(0,x))); 
        this._setData('level', level); 
        this.element.css({background: greenlevels[level]}); 
        return this; // note new return value
    }, 

I think this will be an improvement, even if it means rewriting all my widgets. I would rather have used a return value of "undefined" as the flag for a chainable method, since that would not require rewriting regular methods, and getters that intentionally return undefined should be few and far between. But no one asked me.