How to extend an existing jQuery UI widget?

user12882 picture user12882 · Dec 4, 2012 · Viewed 16.7k times · Source

I am using jQuery v1.8.3 and jQuery UI v1.9.2. I would like to extend an existing jQuery UI widget (in my case the Autocomplete widget) by adding and overriding just some options and methods but keeping the others functionalities as those present in the official release. How can I make that the "proper" (maybe, the "standard") way?


P.S.: I searched on the Web (1, 2, ...) and I found documentation mostly related to creating a new jQuery UI widget but not to extending an existing one.

Answer

Scott González picture Scott González · Dec 7, 2012

In jQuery UI 1.9+, extending a widget is done in the same manner as creating a new widget. The widget factory ($.widget()) supports a few scenarios:

Creating a new widget using the base widget ($.Widget) as the starting point:

$.widget( "ns.widget", { ... } )

Creating a new widget that inherits from an existing widget:

$.widget( "ns.widget", $.ns.existingWidget, { ... } )

Extending a widget:

$.widget( "ns.widget", $.ns.widget, { ... } )

You'll notice that the extending syntax and the inheritance syntax are the same. The widget factory is smart enough to notice that the widget you're creating and the widget you're inheriting from are the same and handle it appropriately.

When inheriting or extending a widget, you only need to define what you want to change or add. There are also a few new methods that exist on the base widget to make it easier to work with inheritance and methods that change context. Read the jQuery.Widget documentation for a full list of methods and their descriptions. You'll definitely want to read about _super() if you're extending a widget.

Here's an example that would change the default delay option to 500 and add a new option prefix which is added to all suggestions:

$.widget( "ui.autocomplete", $.ui.autocomplete, {
    options: {
        delay: 500,
        prefix: ""
    },

    _renderItem: function( ul, item ) {
        var label = item.label;
        if ( this.options.prefix ) {
            label = this.options.prefix + " " + label;
        }
        return $( "<li>" )
            .append( $( "<a>" ).text( label ) )
            .appendTo( ul );
    },
});