JqueryUI - Widget Factory

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 −
This option disables the widget if set to true. By default its value is false.
Option - disabledhide
This option disables the widget if set to true. By default its value is false.
Example
$( ".selector" ).widget({ disabled: true });
This option determines how to animate the hiding of the element. By default its value is null.
Option - hide
This option determines how to animate the hiding of the element. By default its value is null.
This can be of type −
Boolean − If set to false no animation will be used. Element will fade out with the default duration and the default easing if set to true.
Boolean − If set to false no animation will be used. Element will fade out with the default duration and the default easing if set to true.
Number − The element will fade out with the specified duration and the default easing.
Number − The element will fade out with the specified duration and the default easing.
String − The element will be hidden using the specified effect.
String − The element will be hidden using the specified effect.
Object − If the value is an object, then effect, delay, duration, and easing properties may be provided.
Object − If the value is an object, then effect, delay, duration, and easing properties may be provided.
Example
$( ".selector" ).widget({ hide: { effect: "explode", duration: 1000 } });
This option determines how to animate the showing of the element. By default its value is null.
Option - show
This option determines how to animate the showing of the element. By default its value is null.
This can be of type −
Boolean − If set to false no animation will be used to show the element. Element will fade in with the default duration and the default easing if set to true.
Boolean − If set to false no animation will be used to show the element. Element will fade in with the default duration and the default easing if set to true.
Number − The element will fade in with the specified duration and the default easing.
Number − The element will fade in with the specified duration and the default easing.
String − The element will be shown using the specified effect.
String − The element will be shown using the specified effect.
Object − If the value is an object, then effect, delay, duration, and easing properties may be provided.
Object − If the value is an object, then effect, delay, duration, and easing properties may be provided.
Example
$( ".selector" ).widget({ show: { effect: "explode", duration: 1000 } });
The following table lists the different methods that can be used with the base widget −
This method is the widget's constructor. There are no parameters, but this.element and this.options are already set.
Action - _create()
This action destroys the accordion functionality of an element completely. The elements return to their pre-init state. This method is the widget's constructor. There are no parameters, but this.element and this.options are already set.
Example
_create: function() {
   this.element.css( "background-color", this.options.color );
}
This method invokes the provided function after a specified delay. Returns the timeout ID for use with clearTimeout().
Action - _delay( fn [, delay ] )
This method invokes the provided function after a specified delay. Returns the timeout ID for use with clearTimeout().
Example
this._delay( this._foo, 100 );
The public destroy() method cleans up all common data, events, etc. and then delegates out to this _destroy() method for custom, widget-specific, cleanup.
Action - _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.
Example
_destroy: function() {
   this.element.removeClass( "my-widget" );
}
This method sets up element to apply the ui-state-focus class on focus. The event handlers are automatically cleaned up on destroy.
Action - _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.
Example
_create: function() {
   this._focusable( this.element.find( ".my-items" ) );
}
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.
Action - _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.
Example
_getCreateEventData: function() {
   return this.options;
}
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.
Action - _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.
Example
_getCreateOptions: function() {
   return { id: this.element.attr( "id" ) };
}
This method hides an element immediately, using built-in animation methods, or using custom effects. See the hide option for possible option values.
Action - _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.
Example
this._hide( this.element, this.options.hide, function() {
   $( this ).remove();
});
This method Sets up element to apply the ui-state-hover class on hover. The event handlers are automatically cleaned up on destroy.
Action - _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.
Example
this._hoverable( this.element.find( "div" ) );
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.
Action - _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.
Example
_init: function() {
   if ( this.options.autoOpen ) {
      this.open();
   }
}
This method unbinds event handlers from the specified element(s).
Action - _off( element, eventName )
This method unbinds event handlers from the specified element(s).
Example
this._off( this.element, "click" );
Binds event handlers to the specified element(s). Delegation is supported via selectors inside the event names, e.g., "click .foo".
Action - _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".
Example
this._on( this.element, {
   "click a": function( event ) {
      event.preventDefault();
   }
});
This method is called from the _setOptions() method for each individual option. Widget state should be updated based on changes.
Action - _setOption( key, value )
This method is called from the _setOptions() method for each individual option. Widget state should be updated based on changes.
Example
_setOption: function( key, value ) {
   if ( key === "width" ) {
      this.element.width( value );
   }
   if ( key === "height" ) {
      this.element.height( value );
   }
   this._super( key, value );
}
This method is called whenever the option() method is called, regardless of the form in which the option() method was called.
Action - _setOptions( options )
This method is called whenever the option() method is called, regardless of the form in which the option() method was called.
Example
_setOptions: function( options ) {
   var that = this,
   resize = false;
   $.each( options, function( key, value ) {
      that._setOption( key, value );
      if ( key === "height" || key === "width" ) {
         resize = true;
      }
   });
   if ( resize ) {
      this.resize();
   }
}
Shows an element immediately, using built-in animation methods, or using custom effects. See the show option for possible option values.
Action - _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.
Example
_this._show( this.element, this.options.show, function() {
   // Focus the element when it's fully visible.
   this.focus();
}
This method invokes the method of the same name from the parent widget, with any specified arguments. Essentially .call().
Action - _super( [arg ] [, ... ] )
This method invokes the method of the same name from the parent widget, with any specified arguments. Essentially .call().
Example
_setOption: function( key, value ) {
   if ( key === "title" ) {
      this.element.find( "h3" ).text( value );
   }
   this._super( key, value );
}
Invokes the method of the same name from the parent widget, with the array of arguments.
Action - _superApply( arguments )
Invokes the method of the same name from the parent widget, with the array of arguments.
Example
_setOption: function( key, value ) {
   if ( key === "title" ) {
      this.element.find( "h3" ).text( value );
   }
   this._superApply( arguments );
}
This method triggers an event and its associated callback. The option with the name equal to type is invoked as the callback.
Action - _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.
Example
this._on( this.element, {
   keydown: function( event ) {
      // Pass the original event so that the custom search event has
      // useful information, such as keyCode
      this._trigger( "search", event, {
         // Pass additional information unique to this event
         value: this.element.val()
      });
   }
});
This method removes the widget functionality completely. This will return the element back to its pre-init state.
Action - destroy()
This method removes the widget functionality completely. This will return the element back to its pre-init state.
Example
this._on( this.element, {
   "click a": function( event ) {
      event.preventDefault();
      this.destroy();
   }
});
This method disables the widget.
Action - disable()
This method disables the widget.
Example
this._on( this.element, {
   "click a": function( event ) {
      event.preventDefault();
      this.disable();
   }
});
This method enables the widget.
Action - enable()
This method enables the widget.
Example
this._on( this.element, {
   "click a": function( event ) {
      event.preventDefault();
      this.enable();
   }
});
This method gets the value currently associated with the specified optionName.
Action - option( optionName )
This method gets the value currently associated with the specified optionName.
Example
this.option( "width" );
This method gets an object containing key/value pairs representing the current widget options hash.
Action - option()
This method gets an object containing key/value pairs representing the current widget options hash.
Example
var options = this.option();
for ( var key in options ) {
   console.log( key, options[ key ] );
}
This method sets the value of the widget option associated with the specified optionName.
Action - option( optionName, value )
This method sets the value of the widget option associated with the specified optionName.
Example
this.option( "width", 500 );
This method sets one or more options for the widget.
Action - option( options )
This method sets one or more options for the widget.
Example
this.option({
   width: 500,
   height: 500
});
This method returns a jQuery object containing the original element or other relevant generated element.
Action - widget()
This method returns a jQuery object containing the original element or other relevant generated element.
Example
_create: function() {
   this.widget().css( "border", "2px solid red" );
}
This event is triggered when a widget is created.
Event - create( event, ui )
This event is triggered when a widget is created. Where event is of type Event, and ui is of type Object.
Syntax
$( ".selector" ).widget({
   create: function( event, ui ) {}
});

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.
 Print
 Add Notes
 Bookmark this page