, convert it into a superDialog, and call the red() method.
$( "
I am red
" )
.superDialog()
.superDialog( "red" );
Now `superDialog` has a `red()` method that changes its text color to red. Notice how the Widget Factory automatically sets `this` to the widget instance. For a list of all available methods and properties on an instance, please refer to the (#).
### Extending Existing Methods
Sometimes, you need to adjust or add to the behavior of an existing widget method. You can specify the method name as the method to override on the prototype object. The following example overrides the dialog's [`open()` method](#). Since the dialog is open by default, `"open"` will be logged when this code runs.
```javascript
$.widget( "custom.superDialog", $.ui.dialog, {
open: function() {
console.log( "open" );
}
});
// Create a new , and convert it into a superDialog.
$( "
" ).superDialog();
When this code runs, there is a problem. Because we overrode the default behavior of `open()`, the dialog no longer appears on the screen.
When we use a method on the prototype object, we are overriding the original method, replacing it with a new one in the prototype chain.
To make the parent widget method available, the Widget Factory provides two methods: `_super()` and `_superApply()`.
### Accessing the Parent Widget with `_super()` and `_superApply()`
[`_super()`](#) and [`_superApply()`](#) invoke the same method in the parent widget. Look at the following example. Like the previous example, this one also overrides the `open()` method to log `"open"`. However, this time running `_super()` invokes the dialog's `open()`, opening the dialog.
```javascript
$.widget( "custom.superDialog", $.ui.dialog, {
open: function() {
console.log( "open" );
// Invoke the parent widget's open().
return this._super();
}
});
$( "
" ).superDialog();
`_super()` and `_superApply()` are essentially equivalent to the original `Function.prototype.call()` and `Function.prototype.apply()` methods. Therefore, `_super()` accepts an argument list, while `_superApply()` accepts a single array as arguments. The following example demonstrates the difference between the two.
```javascript
$.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 a Widget
jQuery UI 1.9 added the ability to redefine a widget. This means that instead of creating a new widget, we can simply pass an existing widget name and constructor to `$.widget()`. The following example adds the same logging in `open()`, but does so without creating a new widget.
```javascript
$.widget( "ui.dialog", $.ui.dialog, {
open: function() {
console.log( "open" );
return this._super();
}
});
$( "
" ).dialog();
With this method, we can extend an existing widget method while still being able to use `_super()` to access the original methodβall without creating a new widget, by directly redefining the widget.
### Widgets and Polymorphism
When interacting between widget extensions and their plugins, it's important to note that the parent widget's plugin cannot be used to call methods on a child widget element. The following example demonstrates this.
```javascript
$.widget( "custom.superDialog", $.ui.dialog, {} );
var dialog = $( "
" ).superDialog();
// This works.
dialog.superDialog( "close" );
// This doesn't.
dialog.dialog( "close" );
In the example above, the parent widget's plugin, `dialog()`, cannot call the `close()` method on the superDialog element. To learn more about calling widget methods, please see (#).
### Customizing Individual Instances
So far, the examples we've seen have extended methods on the widget prototype. Methods overridden on the prototype affect all instances of the widget.
To demonstrate this, look at the following example. Both instances of the dialog use the same `open()` method.
```javascript
$.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.
$( "
" ).dialog();
$( "
" ).dialog();
Sometimes, you only want to change the behavior of a specific widget instance. To do this, you need to use normal JavaScript property assignment to get a reference to the instance and override the method. This is shown in the example below.
```javascript
var dialogInstance = $( "
" )
.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
$( "
" ).dialog();
// Select both dialogs and call close() on each of them.
// "close" will only be logged once.
$( ":data(ui-dialog)" ).dialog( "close" );
The technique of overriding methods for individual instances is perfect for one-off customizations.
YouTip