Earlier, the only way to write custom controls in jQuery was to extend the $.fn namespace. This works well for simple widgets. Suppose you build more stateful widgets, it quickly becomes cumbersome. To aid in the process of building widgets, Widget Factory was introduced in the jQuery UI, which removes most of the boilerplate that is typically associated with managing a widget.
The jQueryUI Widget Factory is simply a function ($.widget) that takes a string name and an object as arguments and creates a jQuery plugin and a "Class" to encapsulate its functionality.
The following is the syntax of jQueryUI Widget Factory method −
jQuery.widget( name [, base ], prototype )
name − It is a string containing a namespace and the widget name (separated by a dot) of the widget to create.
base − The base widget to inherit from. This must be a constructor that can be instantiated with the `new` keyword. Defaults to jQuery.Widget.
prototype − The object to use as a prototype for the widget to inherit from. For instance, jQuery UI has a "mouse" plugin on which the rest of the interaction plugins are based. In order to achieve this, draggable, droppable, etc. all inherit from the mouse plugin like so: jQuery.widget( "ui.draggable", $.ui.mouse, {...} ); If you do not supply this argument, the widget will inherit directly from the "base widget," jQuery.Widget (note the difference between lowercase "w" jQuery.widget and uppercase "W" jQuery.Widget).
Base widget is the widget used by the widget factory.
The following table lists the different options that can be used with the base widget −
Sr.No. | Option & Description |
---|---|
1 | disabledhide
This option disables the widget if set to true. By default its value is false. |
2 | hide
This option determines how to animate the hiding of the element. By default its value is null. |
3 | show
This option determines how to animate the showing of the element. By default its value is null. |
The following table lists the different methods that can be used with the base widget −
Sr.No. | Action & Description |
---|---|
1 | _create()
This method is the widget's constructor. There are no parameters, but this.element and this.options are already set. |
2 | _delay( fn [, delay ] )
This method invokes the provided function after a specified delay. Returns the timeout ID for use with clearTimeout(). |
3 | _destroy()
The public destroy() method cleans up all common data, events, etc. and then delegates out to this _destroy() method for custom, widget-specific, cleanup. |
4 | _focusable( element )
This method sets up element to apply the ui-state-focus class on focus. The event handlers are automatically cleaned up on destroy. |
5 | _getCreateEventData()
All widgets trigger the create event. By default, no data is provided in the event, but this method can return an object which will be passed as the create event's data. |
6 | _getCreateOptions()
This method allows the widget to define a custom method for defining options during instantiation. The user-provided options override the options returned by this method, which override the default options. |
7 | _hide( element, option [, callback ] )
This method hides an element immediately, using built-in animation methods, or using custom effects. See the hide option for possible option values. |
8 | _hoverable( element )
This method Sets up element to apply the ui-state-hover class on hover. The event handlers are automatically cleaned up on destroy. |
9 | _init()
Any time the plugin is called with no arguments or with only an option hash, the widget is initialized; this includes when the widget is created. |
10 | _off( element, eventName )
This method unbinds event handlers from the specified element(s). |
11 | _on( [suppressDisabledCheck ] [, element ], handlers )
Binds event handlers to the specified element(s). Delegation is supported via selectors inside the event names, e.g., "click .foo". |
12 | _setOption( key, value )
This method is called from the _setOptions() method for each individual option. Widget state should be updated based on changes. |
13 | _setOptions( options )
This method is called whenever the option() method is called, regardless of the form in which the option() method was called. |
14 | _show( element, option [, callback ] )
Shows an element immediately, using built-in animation methods, or using custom effects. See the show option for possible option values. |
15 | _super( [arg ] [, ... ] )
This method invokes the method of the same name from the parent widget, with any specified arguments. Essentially .call(). |
16 | _superApply( arguments )
Invokes the method of the same name from the parent widget, with the array of arguments. |
17 | _trigger( type [, event ] [, data ] )
This method triggers an event and its associated callback. The option with the name equal to type is invoked as the callback. |
18 | destroy()
This method removes the widget functionality completely. This will return the element back to its pre-init state. |
19 | disable()
This method disables the widget. |
20 | enable()
This method enables the widget. |
21 | option( optionName )
This method gets the value currently associated with the specified optionName. |
22 | option()
This method gets an object containing key/value pairs representing the current widget options hash. |
23 | option( optionName, value )
This method sets the value of the widget option associated with the specified optionName. |
24 | option( options )
This method sets one or more options for the widget. |
25 | widget()
This method returns a jQuery object containing the original element or other relevant generated element. |
Sr.No. | Event Method & Description |
---|---|
1 | create( event, ui )
This event is triggered when a widget is created. |
The jQueryUI widget factory, provides an object-oriented way to manage the lifecycle of a widget. These lifecycle activities include −
Creating and destroying a widget: For example,
$( "#elem" ).progressbar();
Changing widget options: For example
$( "#elem" ).progressbar({ value: 20 });
Making "super" calls in subclassed widgets: For example
$( "#elem" ).progressbar( "value" ); or $( "#elem" ).progressbar( "value", 40 );
Event notifications: For example
$( "#elem" ).bind( "progressbarchange", function() { alert( "The value has changed!" ); });
Now let us create a custom widget in the following example. We will create a button widget. We will see how to create options, methods and events in a widget in the following examples −
Let us first create a simple custom widget.
<!DOCTYPE html> <html> <head> <meta charset = "utf-8"> <title>jQuery UI Widget - Default functionality</title> <link rel = "stylesheet" href = "//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src = "https://code.jquery.com/jquery-1.10.2.js"></script> <script src = "https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <script> $(function() { $.widget("iP.myButton", { _create: function() { this._button = $("<button>"); this._button.text("My first Widget Button"); this._button.width(this.options.width) this._button.css("background-color", this.options.color); this._button.css("position", "absolute"); this._button.css("left", "100px"); $(this.element).append(this._button); }, }); $("#button1").myButton(); }); </script> </head> <body> <div id = "button1"></div> </body> </html>
Let us save the above code in an HTML file widgetfactoryexample.htm and open it in a standard browser which supports javascript, you must also see the following output −
In the previous example, we used the _create function to create a custom control. But users generally want to customize the control by setting and modifying options. We can define an options object which stores the default values for all of the options you define. _setOption function is used for this purpose. It is called for each individual option that the user sets. Here we are setting width and background-color of the button.
<!DOCTYPE html> <html> <head> <meta charset = "utf-8"> <title>jQuery UI Widget - Default functionality</title> <link rel = "stylesheet" href = "//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src = "https://code.jquery.com/jquery-1.10.2.js"></script> <script src = "https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <script> $(function() { $.widget("iP.myButton", { _create: function() { this._button = $("<button>"); this._button.text("My first Widget Button"); this._button.width(this.options.width) this._button.css("background-color", this.options.color); this._button.css("position", "absolute"); this._button.css("left", "100px"); $(this.element).append(this._button); }, _setOption: function(key, value) { switch (key) { case "width": this._button.width(value); break; case "color": this._button.css("background-color",value); break; } }, }); $("#button2").myButton(); $("#button2").myButton("option", {width:100,color:"#cedc98"}); }); </script> </head> <body> <div id = "button2"></div> </body> </html>
Let us save the above code in an HTML file widgetfactoryexample.htm and open it in a standard browser which supports javascript, you must also see the following output −
In the following example we will add methods that the user can make use of and these are very easy to build into the framework. We will write a Move method, that shifts the button a specified horizontal distance. To make this work, we also need to set the position and left properties in the _create function −
this._button.css("position", "absolute"); this._button.css("left", "100px");
Following this, the user can now call your method in the usual jQuery UI way −
this._button.css("position", "absolute"); this._button.css("left", "100px");
$("button3").myButton("move", 200);
<!DOCTYPE html> <html> <head> <meta charset = "utf-8"> <title>jQuery UI Widget - Default functionality</title> <link rel = "stylesheet" href = "//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src = "https://code.jquery.com/jquery-1.10.2.js"></script> <script src = "https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <script> $(function() { $.widget("iP.myButton", { _create: function() { this._button = $("<button>"); this._button.text("My first Widget Button"); this._button.width(this.options.width) this._button.css("background-color", this.options.color); this._button.css("position", "absolute"); this._button.css("left", "100px"); $(this.element).append(this._button); }, move: function(dx) { var x = dx + parseInt(this._button.css("left")); this._button.css("left", x); if(x>400) { this._trigger("outbounds",{}, {position:x}); } } }); $("#button3").myButton(); $("#button3").myButton("move", 200); }); </script> </head> <body> <div id = "button3"></div> </body> </html>
Let us save the above code in an HTML file widgetfactoryexample.htm and open it in a standard browser which supports javascript, you must also see the following output −
In this example we will demonstrate how to create an event. To create an event all you have to do is use the _trigger method. The first parameter is the name of the event, the second any standard event object you want to pass and the third any custom event object you want to pass.
Here we are firing an event when if the button moves beyond x=400. All you have to do is to add to the move function −
if(x<400) { this._trigger("outbounds",{}, {position:x}); }
In this case the event is called outbounds and an empty event object is passed with a custom event object that simply supplies the position as its only property.
The entire move function is −
move: function(dx) { var x = dx + parseInt(this._button.css("left")); this._button.css("left", x); if(x<400) { this._trigger("outbounds",{}, {position:x}); } }
The user can set the event handling function by simply defining an option of the same name.
$("button4").myButton("option", { width: 100, color: "red", outbounds:function(e,ui) { alert(ui.position);} });
<!DOCTYPE html> <html> <head> <meta charset = "utf-8"> <title>jQuery UI Widget - Default functionality</title> <link rel = "stylesheet" href = "//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src = "https://code.jquery.com/jquery-1.10.2.js"></script> <script src = "https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <script> $(function() { $.widget("iP.myButton", { _create: function() { this._button = $("<button>"); this._button.text("My first Widget Button"); this._button.width(this.options.width) this._button.css("background-color", this.options.color); this._button.css("position", "absolute"); this._button.css("left", "100px"); $(this.element).append(this._button); }, move: function(dx) { var x = dx + parseInt(this._button.css("left")); this._button.css("left", x); if(x>400) { this._trigger("outbounds",{}, {position:x}); } } }); $("#button4").myButton(); $("#button4").on("mybuttonoutbounds", function(e, ui) { alert("out"); }); $("#button4").myButton("move", 500); }); </script> </head> <body> <div id = "button4"></div> </body> </html>
Let us save the above code in an HTML file widgetfactoryexample.htm and open it in a standard browser which supports javascript, an alert box opens up.