Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

The jQuery UI extends widgets through the parts library


May 08, 2021 jQuery UI


Table of contents


The jQuery UI extends widgets through the Widget Factory

The Widget Factory of the jQuery UI makes it easier to create widgets that extend the functionality of existing widgets. This allows you to create powerful widgets on top of what you already have, or you can make minor adjustments to existing widget functionality.

Note: Before you go into this section, you need to understand what a widget factory is and how it works. If you're not familiar with this knowledge, check out the Widget Factory section first.

Create a widget extension

Creating widgets through the Widget Factory is done by passing the widget name and a prototype object to $.widget() The following example is to create a "superDialog" widget in the "custom" namespace.

$.widget( "custom.superDialog", {} );

To support extensions, $.widget() optionally accepts constructors for widgets used as parent parts. When you specify a parent part, pass it as a second parameter, after the widget name, and in front of the widget prototype object.

Like the example above, here's a "superDialog" widget in the "custom" namespace. This time, however, it is the constructor $.ui.dialog widget of the jQuery UI that means that the superDialog widget should use the dialog widget of the jQuery UI as the parent.

$.widget( "custom.superDialog", $.ui.dialog, {} );

Here, the superDialog and dialog widgets are essentially equivalent, but with different names and namespaces. To make our new widget more featured, we can add some methods to its prototype object.

The prototype object of the widget $.widget() S o far, our instance is using an empty object. Now let's add a method to this object:

$.widget( "custom.superDialog", $.ui.dialog, {
    red: function() {
        this.element.css( "color", "red" );
    }
});
 
// Create a new <div>, convert it into a superDialog, and call the red() method.
$( "<div>I am red</div>" )
    .superDialog()
    .superDialog( "red" );

superDialog has a red() which changes its text color to red. N ote how widget Factory automatically sets this as an this of a widget. For a list of all available methods and properties on the instance, visit the Widget Factory API documentation.

Extend existing methods

Sometimes you need to adjust or add the behavior of an existing part method. Y ou can specify the method name as the name of the method that needs to be overloaded on the prototype object. T he following example overloads dialog's open() method. Because the dialog box is open by default, "open" is "open" code is run.

$.widget( "custom.superDialog", $.ui.dialog, {
    open: function() {
        console.log( "open" );
    }
});
 
// Create a new <div>, and convert it into a superDialog.
$( "<div>" ).superDialog();

When you run this code, there is a problem. Because we overloaded open() the dialog box no longer appears on the screen.

When we use methods on prototype objects, we actually overload the original method and use a new method in the prototype chain.

To make the parent part method available, the Widget Factory provides _super() _superApply()

Use _super() _superApply() access the parent part

_super() _superApply() the same method in the parent part. T ake a look at the example below. L ike the last instance, this instance also overloads the open() to record "open" However, this _super() open() that calls the open() opens the dialog box.

$.widget( "custom.superDialog", $.ui.dialog, {
    open: function() {
        console.log( "open" );
 
        // Invoke the parent widget's open().
        return this._super();
    }
});
 
$( "<div>" ).superDialog();

_super() and _superApply() equivalent Function.prototype.call() and Function.prototype.apply() _super() a list of _superApply() accepts an array as an argument. The following example illustrates the difference between the two.

$.widget( "custom.superDialog", $.ui.dialog, {
    _setOption: function( key, value ) {
 
        // Both invoke dialog's setOption() method. _super() requires the arguments
        // be passed as an argument list, _superApply() as a single array.
        this._super( key, value );
        this._superApply( arguments );
    }
});

Redefining widgets

jQuery UI 1.9 adds the ability to redefine widgets. S o instead of creating a new widget, we just need to pass an existing widget name and constructor like $.widget() The following example adds the same record to open() but not by creating a new widget.

$.widget( "ui.dialog", $.ui.dialog, {
    open: function() {
        console.log( "open" );
        return this._super();
    }
});
 
$( "<div>" ).dialog();

With this approach, we can extend an existing widget method, _super() access the original method - not by creating a new widget, but by redefining the widget directly.

Widgets and Polymorphisms

When interacting between widget extensions and their plug-ins, it is important to note that the plug-ins of the parent part cannot be used to invoke methods on child part elements. The following example demonstrates this.

$.widget( "custom.superDialog", $.ui.dialog, {} );
 
var dialog = $( "<div>" ).superDialog();
 
// This works.
dialog.superDialog( "close" );
 
// This doesn't.
dialog.dialog( "close" );

In the example above, the parent part's plug-in, dialog() cannot call the close() element. To learn more about calling widget methods, check out Widget method calls.

Customize personalized instances

So far, the instances we've seen have ways to extend on widget prototypes. The method of overloading on a prototype affects all instances of the widget.

To demonstrate this, look at the following example. Both forces of dialog use the same open() method.

$.widget( "ui.dialog", $.ui.dialog, {
    open: function() {
        console.log( "open" );
        return this._super();
    }
});
 
// Create two dialogs, both use the same open(), therefore "open" is logged twice.
$( "<div>" ).dialog();
$( "<div>" ).dialog();

Sometimes you just need to change the behavior of an instance of a widget. T o do this, you need to use the normal JavaScript property assignment, get a reference to the instance, and overload the method. This is shown in the following example.

var dialogInstance = $( "<div>" )
    .dialog()
    // Retrieve the dialog's instance and store it.
    .data( "ui-dialog" );
 
// Override the close() method for this dialog
dialogInstance.close = function() {
    console.log( "close" );
};
 
// Create a second dialog
$( "<div>" ).dialog();
 
// Select both dialogs and call close() on each of them.
// "close" will only be logged once.
$( ":data(ui-dialog)" ).dialog( "close" );

The overload method technology of personalized instances is perfect for one-time customization.