Widget Dissected$.widget'thd.progressbar', { _create: function { var progress = this.options.value + '%'; this.element.addClass'progressbar'.textprogress; } }; $.widget Constructor W
Trang 1Writing jQuery Plugins
Jon Hartmann
Most content shamelessly stolen from http://learn.jquery.com/plugins/
and http://learn.jquery.com/jquery-ui/widget-factory/extending-widgets/
Trang 2What is a Widget?
Plugin
• Stateless
• Implemented by assigning to
$.fn
• No extensibility
– Need to modify it? Make a
new plugin
• Manual Setup
– Options
– Methods
– Callbacks
Widget
• Stateful
• Special implementation code
• Extensibility pattern
• Automatic Setup
– Options – Methods – Callbacks
Trang 3Simple Widget
$.widget('thd.progressbar', {
_create: function() {
var progress = this.options.value + '%';
this.element.addClass('progressbar').text(progress); }
});
$('<div />').appendTo('body').progressbar({ value: 20 });
Its called like this:
Trang 4Widget Dissected
$.widget('thd.progressbar', {
_create: function() {
var progress = this.options.value + '%';
this.element.addClass('progressbar').text(progress);
}
});
$.widget Constructor
Widget name with namespace
Widget configuration object
this also has an options object for all options passed in through when the widget is invoked
_create is standard
invoked on widget call this has access to the target element, but IS
NOT the target element
Trang 5Options Default Widget
$.widget('thd.progressbar', {
// Default Values
options: {
value: 0
},
_create: function() {
var progress = this.options.value + '%';
this.element.addClass('progressbar').text(progress); }
});
Trang 6Adding methods
$.widget('thd.progressbar', {
//
// Create a public method Calld as $('*').progressbar('value')
value: function( value ) {
//
},
// Create a private method Called as this._constrain()
_constrain: function( value ) {
//
}
});
• Adding public methods easy as adding them to configuration object
• Private methods easy as using an underscore
Trang 7Adding Callbacks
$.widget('thd.progressbar', {
//
_update: function() {
var progress = this.options.value + '%';
this.element.text( progress );
if ( this.options.value == 100 ) {
this._trigger('complete', null, { value: 100 } );
}
}
});
Callbacks passed and set like options, code can trigger them even if not specified
Easily add callbacks where necessary.
Always emits "custom" events!!
Trang 8Widgets Bind Directly to DOM
• Useful because you can
access the widget
methods by the DOM
– No need to call the $()
selector engine again
– Accessed via the data()
• Also means you have a
hook to override a
specific instance's
methods
var bar = $( "<div />") .appendTo( "body" ) .progressbar()
data( "progressbar" );
bar.option( "value", 50 ); alert( bar.options.value );
// Override
bar.open = function () { console.log('Overridden!'); };
bar.open();
Trang 9Widgets can be… DESTROY'ED!
• Automatically called when DOM element removed
• Helps clean up memory by removing references
• Cleans up HTML if you just want to remove the widget from the DOM element (no dangling classes)
$.widget('thd.progressbar', {
//
destroy: function() {
this.element
removeClass( "progressbar" )
text( "" );
// Call the base destroy function
$.Widget.prototype.destroy.call( this );
}
});
Trang 10Widgets Have a Prototype
• You can extend the widget dynamically
• You can extend the object like any other object.
– Is that the best way?
– No There is another Skywalker… err method.
$.thd.progressbar.prototype.reset = function() {
this._setOption( "value", 0 );
};
Trang 11Widget can Extend Widgets
• BOOM!
– Did you catch that?
• Built in inheritance
$.widget('thd.awesomebar', $.thd.progressbar, {
dazzle: function(onOff) {
this.options.dazzleOn = onOff;
this._update();
}
});
$('<div />').appendTo('body').awesomebar({ value: 20 });
Trang 12Widgets can Override or Extend Methods
• Widgets implement "_super" to access parent class.
$.widget('thd.awesomebar', $.thd.progressbar, {
open: function() {
console.log( "open" );
}
});
$.widget('thd.awesomebar', $.thd.progressbar, {
open: function () {
console.log( "open" );
// Invoke the parent widget's open()
return this._super();
}
});
Trang 13Access to _super
• _super() accepts argument list like call()
• _supperApply() accepts an array, like apply()
$.widget('thd.awesomebar', $.thd.progressbar, {
_someFunction : function () {
this._super( key, value ); // like call()
this._superApply( arguments ); // like apply()
}
});
Trang 14Cool Trick: Redefining Widget
• jQuery 1.9 lets you redefine a widget, which means this is valid:
$.widget('thd.progressbar', $.thd.progressbar, {
someMethod : function () {
// Do something
}
});
• Note that the name matches the original
object definition.