14

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.

user12882
  • 4,702
  • 9
  • 39
  • 54
  • 1
    Define "extend". Depending on what you'd like to do, you usually just add the new methods then override some existing methods to make use of your added functionality. As in the [autocomplete accentFolding extension](https://github.com/scottgonzalez/jquery-ui-extensions/blob/master/autocomplete/jquery.ui.autocomplete.accentFolding.js). There isn't much of a clean and future-proof way. – Fabrício Matté Dec 04 '12 at 20:18
  • I think the only answer anyone can provide is you have to do it carefully. You will have to become familiar with the codebase, and then be sure you maintain whatever contracts functions have with each other. – thatidiotguy Dec 04 '12 at 20:18
  • @Fabrício Matté - What do you mean with "there isn't much of a clean and future-proof way"? – user12882 Dec 04 '12 at 20:21
  • @thatidiotguy - Simply, I would like just to add new methods and options but I didn't plan to override existing methods. – user12882 Dec 04 '12 at 20:24
  • Well, you're editing a plugin functionality after all. You can't foresee what will change in it in future versions. You can create a reference the original method before overriding it, override it with your own code and invoke the original method before/after your added code which is the closest to a clean/future-proof way, but not 100%. – Fabrício Matté Dec 04 '12 at 20:25
  • @Fabrício Matté - As in the question, *how can I make that the "proper" (maybe, the "standard") way?* – user12882 Dec 04 '12 at 20:27
  • That's what I just said, `There isn't a clean and future-proof way` as far as I'm aware of. See how Scott edits the `autocomplete.prototype._initSource` in the previously linked extension, that's probably the closer you'll get to a "proper" way. But then again, it depends on what you're trying to achieve. – Fabrício Matté Dec 04 '12 at 20:29

1 Answers1

40

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 );
    },
});
Scott González
  • 1,917
  • 16
  • 10
  • 7
    What are differences between *extending* and *inheriting*? – user12882 Dec 07 '12 at 13:12
  • 4
    Inheriting creates a new widget, without changes to the existing widget. Extending a widget changes the behaviour of the existing widget, not creating a new one. – Jörn Zaefferer Dec 07 '12 at 13:49
  • 2
    In case it saves anyone the same time/headache I just went through, note that you can't extend jQuery UI's datepicker (in version 1.10 and maybe later) since it isn't based on the widget factory in earlier versions. See this question http://stackoverflow.com/questions/25011698/extending-jquery-ui-datepicker. With other widgets, extending should work ok. – jinglesthula Sep 26 '16 at 16:18