Skip to content

Commit 878403c

Browse files
committed
Various improvements and tweaks per review and reread.
1 parent 153dec6 commit 878403c

File tree

1 file changed

+43
-20
lines changed

1 file changed

+43
-20
lines changed

page/jquery-ui/widget-factory/extending-widgets.md

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ jQuery UI's widget factory makes it easy to build widgets that extend the functi
77

88
### Creating Widget Extensions
99

10-
Creating widgets with the widget factory is done by passing the name of the widget and a prototype object to `$.widget`. The following creats a "myWidget" widget in the "myNamespace" namespace.
10+
Creating widgets with the widget factory is done by passing the name of the widget and a prototype object to `$.widget`. The following creates a "myWidget" widget in the "myNamespace" namespace.
1111

1212
```
13-
$.widget( "myNamespace.myWidget" {} );
13+
$.widget( "myNamespace.myWidget", {} );
1414
```
1515

1616
`$.widget` also accepts the constructor of a widget to extend as an optional parameter. For instance, the constructor of [jQuery UI's dialog widget](http://jqueryui.com/dialog/) is `$.ui.dialog`.
1717

18-
When specifying a base widget, pass it as a second argument - after the widget's name, and before the widget's prototype object. The following creates a "superDialog" widget based on the dialog widget in the `"my"` namespace.
18+
When specifying a base widget, pass it as a second argument - after the widget's name, and before the widget's prototype object. The following creates a "superDialog" widget based on the dialog widget in the "my" namespace.
1919

2020
```
2121
$.widget( "my.superDialog", $.ui.dialog, {} );
@@ -59,49 +59,72 @@ While this runs, there's a problem. Since we overrode the default behavior of `o
5959

6060
When we place methods on the prototype object we are not actually overriding the original method - rather, we are placing a new method at a higher level in the prototype chain.
6161

62-
The original `show()` method is still available at `$.ui.dialog.prototype.open()`, and can be invoked. The following creates a new widget with an `open()` method that logs `"Opened"` then calls dialog's `open()`.
62+
The original `show()` method is still available at `$.ui.dialog.prototype.open()`, and can be invoked. To make this easy, the widget factory provides two methods - `_super()` and `superApply()`.
63+
64+
### Using `_super` and `_superApply` to Access Parents
65+
66+
Referencing the parent widget's prototype methods is a bit verbose, therefore [jQuery UI 1.9](http://jqueryui.com/upgrade-guide/1.9/) introduced the [`_super()`](http://api.jqueryui.com/jquery.widget/#method-_super) and [`_superApply()`](http://api.jqueryui.com/jquery.widget/#method-_superApply) methods.
67+
68+
`_super()` and `_superApply()` both invoke the method of the same name from the parent widget. For example the following creates a new widget with an `open()` method that logs `"open"`, then invokes dialog's `open()` method.
6369

6470
```
6571
$.widget( "my.superDialog", $.ui.dialog, {
6672
open: function() {
67-
console.log( "Opened" );
68-
return $.ui.dialog.prototype.open.apply( this, arguments );
73+
console.log( "open" );
74+
// Invoke the parent widget's open()
75+
return this._super();
6976
}
7077
});
7178
72-
$( "#dialog" ).superDialog();
79+
$( "<div>" ).superDialog();
7380
```
7481

75-
### Using _super to Access Parents
76-
77-
Referencing the parent widget's prototype methods is a bit verbose, therefore in [jQuery UI 1.9](http://jqueryui.com/upgrade-guide/1.9/) the [`_super()` method](http://api.jqueryui.com/jquery.widget/#method-_super) was introduced.
78-
79-
`_super()` invokes the method of the same name from the parent widget with the same set of arguments. Therefore we can replace our call to `$.ui.dialog.prototype.open()` with one to `_super()`.
82+
`_super()` and `superApply()` were designed to behave like the native `Function.prototype.call()` and `Function.prototype.apply()` methods. Therefore, `_super()` accepts an argument list, and `superApply()` accepts a single array of arguments. This difference is shown in the example below.
8083

8184
```
8285
$.widget( "my.superDialog", $.ui.dialog, {
83-
open: function() {
84-
console.log( "Opened" );
85-
return this._super();
86+
_setOption: function( key, value ) {
87+
// Both invoke dialog's setOption method. _super requires the arguments be
88+
// passed as an argument list, _superApply as a single array.
89+
this._super( key, value );
90+
this._superApply( arguments );
8691
}
8792
});
88-
89-
$( "#dialog" ).superDialog();
9093
```
9194

9295
### Redefining Widgets
9396

94-
Another feature added in jQuery UI 1.9 was the ability for widgets to redefine themselves. Therefore, instead of creating a new widget we can pass `$.widget` an existing widget's name and constructor. The following example adds the same logging in `open()`, but doesn't create a new widget to do so.
97+
Another feature added in jQuery UI 1.9 was the ability for widgets to redefine themselves. Therefore, instead of creating a new widget, we can pass `$.widget` an existing widget's name and constructor. The following example adds the same logging in `open()`, but doesn't create a new widget to do so.
9598

9699
```
97100
$.widget( "ui.dialog", $.ui.dialog, {
98101
open: function() {
99-
console.log( "Opened" );
102+
console.log( "open" );
100103
return this._super();
101104
}
102105
});
103106
104-
$( "#dialog" ).dialog();
107+
$( "<div>" ).dialog();
105108
```
106109

107110
Now you can extend an existing widget's method, and still have access to the original methods using `_super()`.
111+
112+
### Widgets and Polymorphism
113+
114+
One word of warning when interacting with widget extensions and their plugins. The parent widget's plugin cannot be used to invoke methods on elements that are child widgets. This is shown in the example below.
115+
116+
```
117+
$.widget( "my.superDialog", $.ui.dialog, {} );
118+
119+
var dialog = $( "<div>" ).superDialog();
120+
121+
// This works
122+
dialog.superDialog( "close" );
123+
124+
// This doesn't
125+
dialog.dialog( "close" );
126+
```
127+
128+
Above, the parent widget's plugin, `dialog()`, cannot invoke the `close()` method on an element that is a superDialog. If you need to access the parent's methods, you need to specify a new method on the prototype and use `_super()` or `_superApply()` to access the parent's method.
129+
130+
For more on the invoking widget methods see [Widget Method Invocation](/jquery-ui/widget-factory/widget-method-invocation/). For more information on the widget plugin bridge see [its documentation](http://api.jqueryui.com/jQuery.widget.bridge/).

0 commit comments

Comments
 (0)