Hacking at 0300: Extending jQuery UI Widgets

No Comments

Been looking at ways to modify and extend the default jquery widgets and came across this interesting extension to jquery.ui that allows for subclassing widgets and also allows for aspect orientated programming within javascript.

http://bililite.com/blog/extending-jquery-ui-widgets/

One small note, if using the jquery.ui.subclass.js is that you must copy the .subclass() method onto any of the existing UI widgets that you wish to modify.

To give a actual example of this code in use, this is a little extension to the jquery ui.tabs widget, that enables you to specify for non-javascript clients, and for javascript clients. Also auto-updates the anchor (hash) tag in the location bar to better enable copy/paste links by end users.

// Requires jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.subclass.js, jquery.ui.tabs.js
// Import subclass function
$.ui.tabs.subclass = $.ui.widget.subclass;
 
/**
 *  @attr  <root><ul><li><a ajax="">       explicit url to load via ajax, overrides options.ajaxRewrite
 *  @param {Function} options.ajaxRewrite  a function to convert the href url into an ajax url, default function adds .tab before .html
 */
$.ui.tabs.subclass('ui.pagetabs', {
    options: {
        ajaxRewrite: function(url) { return url.replace(/(\.tab)*\.html/, '.tab.html'); }
    },  
    _tabify: function(init) {
        this._super(init);
 
        // Auto-append the anchor tag to the browser location bar
        this.anchors.bind( "click.tabs", function(){
            document.location.hash = this.getAttribute("href");
        });
    },
    load: function( index ) {
        var i = this._getIndex( index );
        var a = this.anchors.eq(i)[0];
 
        if( !$.data(a, "load.original") ) {
            $.data(a, "load.original", $.data(a, "load.tabs")); // save original, also acts as onetime flag
            $.data(a, "load.tabs", this.options.ajaxRewrite( $.data(a, "load.tabs") ));
        }
 
        // Read <a ajax=""> attribute, overrides this.options.ajaxRewrite
        if( a.getAttribute("ajax") ) {                       
            $.data(a, "load.tabs", a.getAttribute("ajax"));  
        }                                                    
 
        // Super will load contents of $.data(a, "load.tabs")
        this._super(index);                           
    }                                                 
});