Extending jQuery UI Widgets
This page is obsolete; current versions are on my github pages at github.bililite.com/extending-widgets.html. This page is being kept here for historical purposes.
Avoiding Bloat in Widgets
A while back, Justin Palmer wrote an excellent article on "Avoiding Bloat in Widgets." The basic premise (no suprise to anyone whose ever dealt with object-oriented programming) is that your widgets should not do everything possible; they should do one thing well but be flexible enough to allow others to modify them.
He describes two ways of extending objects: subclassing and aspect-oriented programming (AOP). Subclassing creates new classes, while AOP modfies the methods of a single object. Both can be useful.
So let's make Palmer's Superbox
widget (it just moves randomly about the screen with mouse clicks):
var Superbox = {
_init: function(){
var self = this;
this.element.click(function(){
self.move();
});
},
move: function(){
this.element.css (this._newPoint());
},
_newPoint: function(){
return {top: this._distance(), left: this._distance()};
},
_distance: function(){
return Math.round (Math.random()*this.options.distance);
},
options: {
distance: 200
}
};
$.widget ('ui.superbox', Superbox);
I've factored apart a lot of the code, so we have plenty of "hooks" to use to extend the method without copying code. Note that none of the code refers to "superbox" directly, so we can create subclasses that don't know the superclass's name.
Subclassing Widgets
Note that jQuery UI 1.9 incorporates most of these ideas, so you may not need to use
$.ui.widget.subclass
at all; it is built in. Use $.widget('ui.subclass', $.ui.baseclass);
. See my post on this.
The widget factory ($.widget
) allows you to use one widget as the base for another,
but that's not the same as subclassing; it copies all the methods from one widget to the next.
So let's use real inheritance to make a new class, supererbox
, that moves rather than jumps to its new location.
I'll use Richard Cornford's variation on Douglas Crockford's prototypal inheritance pattern to simplify
subclassing (you could use a fancier one like Dean Edward's Base,
or manipulate prototype
s yourself). I'll use Dean Edward's technique for
calling
overridden superclass functions.
var object = (function(){
function F(){}
return (function(o){
F.prototype = o;
return new F();
});
})();
And create an empty "base" widget class.
$.widget('ui.widget',{});
And add a method to create subclasses that inherit from the base.
var OVERRIDE = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
$.ui.widget.subclass = function subclass (name){
$.widget(name,{}); // Slightly inefficient to create a widget only to discard its prototype, but it's not too bad
name = name.split('.');
var widget = $[name[0]][name[1]], superclass = this, superproto = superclass.prototype;
var args = $.makeArray(arguments); // get all the add-in methods
var proto = args[0] = widget.prototype = object(superproto); // and inherit from the superclass
$.extend.apply(null, args); // and add them to the prototype
widget.subclass = subclass;
// Subtle point: we want to call superclass _create, _init and _destroy if they exist
// (otherwise the user of this function would have to keep track of all that)
// and we want to extend the options with the superclass's options. We copy rather than subclass
// so changing a default in the subclass won't affect the superclass
for (key in proto) if (proto.hasOwnProperty(key)) switch (key){
case '_create':
var create = proto._create;
proto._create = function(){
superproto._create.apply(this);
create.apply(this);
};
break;
case '_init':
var init = proto._init;
proto._init = function(){
superproto._init.apply(this);
init.apply(this);
};
break;
case 'destroy':
var destroy = proto.destroy;
proto.destroy = function(){
destroy.apply(this);
superproto.destroy.apply(this);
};
break;
case 'options':
var options = proto.options;
proto.options = $.extend ({}, superproto.options, options);
break;
default:
if ($.isFunction(proto[key]) && $.isFunction(superproto[key]) && OVERRIDE.test(proto[key])){
proto[key] = (function(name, fn){
return function() {
var tmp = this._super;
this._super = superproto[name];
try { var ret = fn.apply(this, arguments); }
finally { this._super = tmp; }
return ret;
};
})(key, proto[key]);
}
break;
}
};
And use it like this to create a new, subclassable superbox and a subclass of that:
$.ui.widget.subclass('ui.superbox',{
_init: function(){
var self = this;
this.element.click(function(){
self.move();
});
},
move: function(){
this.element.css (this._newPoint());
},
_newPoint: function(){
return {top: this._distance(), left: this._distance()};
},
_distance: function(){
return Math.round (Math.random()*this.options.distance);
},
options: {
distance: 200
}
});
$.ui.superbox.subclass ('ui.supererbox', {
// overriding and new methods
move: function(){
this.element.animate(this._newPoint(), this.options.speed);
},
home: function(){
this.element.animate({top:0, left:0}, this.options.speed);
},
options: {
speed: 'normal'
}
});
The function signature is $.namespace.widget.subclass(name <String>, [newMethods <Object>]*)
,
where you can use as many newMethod objects as you want. This lets you use mixin objects, like $.ui.mouse
,
that add a specific set of methods.
We now have a new widget called supererbox that is just like superbox but moves smoothly.
Calling Superclass Methods
If we want to use the superclass methods in our method, we use this._super
:
$.ui.supererbox.subclass('ui.superboxwithtext', {
move: function(){
this.options.count = this.options.count || 0;
++this.options.count;
this.element.text('Move number '+this.options.count);
this._super();
}
});
Aspect Oriented Programming
Aspect oriented programming allows the user of an object to modify its behavior after it has been instantiated. New methods don't so much override the old ones as supplement them, adding code before or after (or both) the original code, without hacking at the original class definition.
We'll add methods for widgets that are stolen straight from Justin Palmer's article:
$.extend($.ui.widget.prototype, { // note that we could extend $.Widget.prototype to add these to all widgets, rather than ones descended from $.ui.widget
yield: null,
returnValues: { },
before: function(method, f) {
var original = this[method];
this[method] = function() {
f.apply(this, arguments);
return original.apply(this, arguments);
};
},
after: function(method, f) {
var original = this[method];
this[method] = function() {
this.returnValues[method] = original.apply(this, arguments);
return f.apply(this, arguments);
}
},
around: function(method, f) {
var original = this[method];
this[method] = function() {
var tmp = this.yield;
this.yield = original;
var ret = f.apply(this, arguments);
this.yield = tmp;
return ret;
}
}
});
And now we can use these methods in our code.
For example, let's say we have a cool plugin to make an element pulsate (I know, UI has a pulsate
method that does this):
$.fn.pulse = function (opts){
opts = $.extend ({}, $.fn.pulse.defaults, opts);
for (i = 0; i < opts.times; ++i){
this.animate({opacity: 0.1}, opts.speed).animate({opacity: 1}, opts.speed);
}
return this;
};
$.fn.pulse.defaults = {
speed: 'fast',
times: 2
};
And we'll create a supererbox object, then make it pulse before moving:
$('#experiment4').supererbox().supererbox('before','move', function() {
this.element.pulse();
});
Or even make it pulse before and after moving:
$('#experiment5').supererbox().supererbox('around','move', function() {
this.element.pulse();
this.yield();
this.element.pulse();
});
Note that we didn't create any new classes to get this new behavior; we added the behavior to each object after the object was created.
Note that I did not use the widget factory directly. It may be possible to make this more efficient, but I haven't analyzed the code in jQuery UI 1.8 closely enough.
Ramin says:
Fantastic article. I feel +20 smarter now.
March 7, 2009, 11:51 aminktri says:
Hey,
I’m having a problem extending a widget pre-defined in jQuery UI. I’ve tried this: $.ui.widget.subclass(‘ui.dialogSubclass’, $.ui.dialog.prototype); but I get an error in the UI js file: (this.uiDialogTitlebarCloseText = c(“”)).addClass(“ui-icon ui-icon-closethick”).text(m.closeText).appendTo is not a function.
March 7, 2009, 2:12 pmDanny says:
@inktri:
That looks right, but I haven’t used ui.dialog so I don’t know anything about its internal code. Looking at the dialog code, there’s a line about
this.uiDialogTitlebarCloseText = $('<span/>')
but it ought to work. I don’t know what thec("")
is from.-Danny
March 8, 2009, 8:21 amEthan says:
Thanks ! good job ! I am going to implement the inheritance in this way.
April 2, 2009, 5:12 amJeremy says:
This is very useful but I am having some trouble with the inheritance pattern. Let’s say I subclass a button class that I made (ui.button) to be a menubutton (ui.menuButton) that pops open a menu. The button superclass has a disable function that menubutton inherits. Later, I want to disable all the buttons but
$(‘.Button’).button(‘disable’);
doesn’t disable any of the menu buttons. I have to do:
$(‘.Button’).menuButton(‘disable’);
which means I cant use the menuButton as the superclass. But when I grab all the buttons that way I don’t know which one I have. Have you run into this? Any ideas for a workaround?
Thanks,
April 21, 2009, 10:50 amJeremy
Jeremy says:
Okay, some more digging and it looks like the problem is the way the widget factory stores the reference to the widget in $.data. It uses the widget name as the secondary key so calling disable method like this:
$(‘.Button’).button(‘disable’) leads to a
$.data(element, ‘button’) call to get the instance. If it is actually a menuButton that call returns nothing.
Changing ui.core to use a static key like ‘instance’ fixes the problem and I all my inheritance starts working.
What I can’t figure out is what is gained from using the widget name as the key??
April 21, 2009, 12:36 pmDanny says:
@Jeremy:
April 22, 2009, 7:19 pmYou’re right; but it’s a feature, not a bug :). The idea is that you could have multiple widgets associated with a single element (say, $(selector).draggable().datepicker() so each needs its own key.
One workaround (with its own set of potential problems) would be to set the ‘button’ data in the _init method:
$.ui.widget.subclass(‘ui.button’, {
_init: function() { this.element.data(‘button’, this) }
}
Now all subclasses will explicitly set the data with the ‘button’ key
Jeremy says:
Hmm… I still think of it as a bug. Inheritance is really important to me (much more important than being able to have compound widgets as you suggest was the reason for the “feature”) and it seems fundamentally broken right now. I guess I will try your solution rather than mine of modifying ui.core but I really hope there will be an elegant way to extend widgets soon. Maybe you could work your solution into your widget subclassing function??
May 6, 2009, 4:53 pmDanny says:
@Jeremy:
May 6, 2009, 8:37 pmI hear you; I originally implemented it your way but changed when this way turned out to be more useful for what I wanted to do.
You could modify the $.ui.widget.subclass function; before the
for (key in proto) if (proto.hasOwnProperty(key)) switch (key){
line insert:var _init = proto._init;
proto._init = function() { this.element.data(name, this); if (proto.hasOwnProperty('_init')) _init.apply(this); };
This will make each base class add data under its own name. I think that will work.
Good luck.
–Danny
Jon says:
I have been writing a series of widgets and I want to a method that is bound as an event like
.bind(“click”, {self:this}, this.method)
then in the this.method i can access the widget instance like
method: function(event){var self = event.data.self;}
this works ok. next i want to write a child widget class which has its own this.method bound as an event in the same way. but this time i want to call the super classes event method from inside the new method, i have discovered that
method: function(event){var self = event.data.self;self._super(event)}
does not work, is this possible to fix?
Thank you
May 12, 2009, 10:07 amJon
Danny says:
@Jon:
May 12, 2009, 3:22 pmThe
_super
method is magic; the subclassing code scans the methods for calls to it, and if found, creates a function that changes_super
to refer to the superclass’s method. That means that you can’t use it in a function that is defined later.You have to call the superclass method directly:
$.ui.superclass.methodName.apply(this, arguments)
, which does the same thing but is more verbose.–Danny
Jon says:
Thanks for your help, it gave me somewhere to start looking, but $.ui.mysuperclass is a function (the constructor?) and doesnt have any of my widget methods.
function (element, options) {
var self = this;
this.namespace = namespace;
this.widgetName = name;
this.widgetEventPrefix = $[namespace][name].eventPrefix || name;
this.widgetBaseClass = namespace + “-” + name;
this.options = $.extend({}, $.widget.defaults, $[namespace][name].defaults, $.metadata && $.metadata.get(element)[name], options);
this.element = $(element).bind(“setData.” + name, function (event, key, value) {if (event.target == element) {return self._setData(key, value);}}).bind(“getData.” + name, function (event, key) {if (event.target == element) {return self._getData(key);}}).bind(“remove”, function () {return self.destroy();});
}
Jon
May 13, 2009, 7:06 amDanny says:
@jon:
May 13, 2009, 7:53 amI think I missed a phrase in there. Try:
$.ui.mysuperclass.prototype.methodName.apply(this, arguments)
–Danny
Jeremy says:
Just got back to this. Anyway, what you suggest seems to work (name should just be the second part of the name) but there are definitely issues. The one I am most bothered by is that every level of subclassing will result in a copy of the parent’s functions being added to $.data. So, if I subclass a widget that has a disable method 4 times there will be 4 disable methods hanging around.
You mention that the way you ended up implementing it was more useful – I would be interested in hearing why.
Thanks,
May 20, 2009, 5:24 pmJeremy
Danny says:
@Jeremy:
May 20, 2009, 7:38 pmYou are right about
name
; it should bename[1]
.The widget methods are part of the object’s prototype; they do not get copied when subclassed. That’s the part of the beauty of prototype-based inheritance. So:
$.ui.widget.subclass('ui.thing1', { method1: function(){} });
$ui.thing1.subclass('ui.thing2, {method2: function(){} });
does not copy
method1
;$().thing2('method1')
callsthing1
‘smethod1
.In terms of copying the $.data, each
this.element.data(name[1], this);
does not create a new copy ofthis
; it just adds a new element to the data pointing to the samethis
. So even if you subclass 4 times, when you execute_init
thethis.element.data
line is referring to the samethis
(the widget object) 4 times, assigning a new name to the data each time.The way I implemented it, the widget object is only assigned to the data under its own name, not the parent classes. This allows me to use multiple widgets on the same element.
–Danny
Ethan says:
Hey Danny,
I ‘ve been using the way you implement inheritance for a while, it is amazing. however,I come across a problem when I override Function.prototype.toString to be :
Function.prototype.toString = function() { return “function code hidden.”; };
After I did this, this regular expression [test(function(){xyz;}) ? /\b_super\b/ : /.*/; ] doesn’t work correctly so that in the conditional expression below would return a false ,then finally the ‘this._super’ mechanism is gone.
regular expression:
[test(function(){xyz;}) ? /\b_super\b/ : /.*/;
conditional expression:
$.isFunction(proto[key]) && $.isFunction(superproto[key]) && OVERRIDE.test(proto[key])
here the OVERRIDE.test(proto[key]) always return false when i override the Funtion.prototype.toString method
due to i am not good at regular expression at all, i have no idea how to fix this.how can I solve this?
June 16, 2009, 8:06 pmDanny says:
@Ethan:
June 17, 2009, 8:51 amThe purpose of the regular expression is to see if
_super
is used, because if it is not, it’s inefficient to set it up in every widget. If you’re hiding the source (not sure why, but it’s your program) then that won’t work.Remove the
&& OVERRIDE.test(proto[key])
entirely. Each method will now go through a closure to create_super
, so it may be slower, but it will work.–Danny
Ethan says:
Thanks a lot Danny. Now I understand.
June 25, 2009, 4:22 amCheers . -:)
Felix says:
Hey Danny,
i tried to extend jQuery Tabs with the AOP method. Without succes.
Could you provide a working example in a zip? Like you did for the superclass method. Would be very helpful to understand.
greetings felix
July 4, 2009, 6:19 amDanny says:
@Felix:
The code above is working with AOP. You can see other examples of it in the end of my post about flexcal.
To get it to work with an existing widget, you would have to add the methods to the widget prototype. Try:
before you use
July 5, 2009, 9:14 pm$().tabs()
.–Danny
Soheil says:
Hey Danny,
September 3, 2009, 8:03 amThanks for the useful tutorial.
I’m writing some widgets and would like to make subclasses, or inherit from the jQuery’s ui library components. e.g. I want to have a “pager” component which is a subclass of jQuery’s ui.tabs, and I would like to override the _init() or _tabify() methods in order to create a new look for my “pager” component.
If I got your tutorial right, I’ll have to copy-paste all the “ui.tabs.js” codes into a new file like “ui.tabs.subclassable.js” (because I don’t want to change the original files) and use $.ui.widget.subclass(‘ui.tabs’, {}) instead of $.widget(‘ui.tabs’, {}) … now I have a problem with this, every time a new version of ui.tabs.js is released I’ll have to change the file or copy-paste codes into subclassable file again. Is there any way to avoid this? I mean is there a way for using subclasses without changing the original ui library files?
Thanks…
Soheil says:
about my previous comment; I tried this:
September 3, 2009, 11:21 am$.widget(“ui.pager”, $.extend({}, $.ui.tabs.prototype, {…});
It is working… so why should we use this subclass widget? Isn’t it easier just to extend the widget and override some of the methods?
Danny says:
@Soheil:
You are right; there isn’t much difference between
$.ui.widget.subclass ('ui.pager, $.ui.tabs.prototype, {...})
(using my code) and$.widget('ui.pager', $.extend({}, $.ui.tabs.prototype, {...}))
. The advantages are:_super
rather than$.ui.tabs.prototype.methodName
$.ui.tabs.prototype
and$.ui.tabs.defaults
are reflected in$.ui.pager
The aspect-oriented code you could mix in to your derived widget, just as with
September 3, 2009, 11:35 pm$.ui.mouse
.Bottom line: you may find it useful; I certainly have. If you want to use it to subclass existing widgets, I would first do
$.ui.widget.subclass('ui.subclassabletabs', $.ui.tabs.prototype)
and then$.ui.subclassabletabs.subclass('ui.pager', {...}
) to get all the advantages.Soheil says:
Thnaks Danny, that’s nice…
September 4, 2009, 9:03 amjQuery UI Widget inheritance « Dans le doute, reboot ! says:
[…] jQuery UI Widget inheritance | février 13, 2010 Je n’ai trouvé que trés peu de ressources sur le web illustrant cette technique. Ma seule trouvaille fut celle-ci. […]
February 13, 2010, 10:28 amandrew says:
@inktri: @danny and for anyone trying to use this to extend jquery ui.dialog i’ve found that you’ll need to fix the .text(undefined) being thrown by the line mentioned in your comment.
for what it’s worth, it’s line 122 in v1.7.2 of ui.dialog.js
from
.text(options.closeText)
to
.text((options.closeText || ”)),
maybe you can explain why exactly extension fails on this internally???
i understand that .text(undefined) is returning a null therefore .appendTo() doesn’t exist and error, but what’s going on here under the hood?
Thanks for the great article, i’ve learned tons tonight. With this small fix i’m able to extend the ui.dialog also
February 17, 2010, 1:47 amDanny says:
@andrew:
February 19, 2010, 12:17 pmThough I haven’t looked at it directly, I suspect we’ve got a problem that exists in many of the overloaded jQuery functions:
.text('foo')
sets the text and returns a jQuery object while.text()
returns the text..text(undefined)
is probably interpreted as.text()
and doing the wrong thing.That’s my guess.
–Danny
Valentino says:
Great article. I found it really helpfull.
Just one note.
I think that this part is incorrect: “The astute reader will have noticed that level is a class variable; the same variable is used for every green3 object. This is clearly not what we want; each instance should have its own copy”
It looks to me that jQuery UI create an instance of our prototype for each object. So you coul safely use this.level, and it will be a different variable for each object.
I noticed this because some jQuery UI widgets just store variables using this.name_variable.
For instance, the accordion widget save the headers elements as “this.headers”
Thanks anyway for this great article, it’s so usefull that there should be an official copy on the jQuery UI doc
_Valentino
February 28, 2010, 4:21 amDanny says:
@Valentino:
February 28, 2010, 4:17 pmI think you actually meant this comment for the Widget Tutorial. Notwithstanding that, there’s a subtlety here about how javascript handles prototypal inheritance:
level
is a variable in the prototype, so it is not copied into each instance.this.level
refers to the prototype’slevel
, which is shared with all instances. the general rule: when I refer tothis.foo
, Javascript searched the object for a property namedfoo
, then the object’s prototype, then the prototype’s prototype, etc. If nothing is found, a new property is created in the individual object.–Danny
Christoph says:
Hey Danny,
just a minor quirk I encountered, when using Dojo Shrinksafe compression (don’t ask me why ;).
In the line: widget.subclass = subclass;
The “subclass” function reference is treated as an internal variable, and thus hashed to:
widget.subclass = _10;
Which of course fails at runtime.
I fixed that by using the namespaced function ref:
widget.subclass = $.ui.widget.subclass;
Other than that, works great.
Christoph
March 12, 2010, 4:54 amDanny says:
@Christoph:
March 14, 2010, 1:38 amThat’s got to be one of those quirk about named functions that is so inconsistent between javascript implementations. This one works in all the major browsers but evidently Dojo’s Shrinksafe parses the javascript differently. Thanks for the heads up!
(And why were you using Dojo? I had to ask! :) )
–Danny
alpha says:
very nice tutorial.
March 24, 2010, 2:52 pmI got a issue when a call to destroy is made: $.widget.prototype.apply is not a function
any clue?
Danny says:
@alpha:
March 24, 2010, 9:01 pmjQuery UI 1.8 just came out and broke everything. I’m going to have to rewrite this, sometime over the next two weeks, to use the new widget factory. I think it will be better, but don’t count on anything working (or go back to jQuery 1.7.2) until then.
–Danny
Interval an Objekt hängen (jQuery) - php.de says:
[…] ui factory. Insbesondere wäre wohl die ui.progressbar für dich interessanter. ui developer guide extending ui widgets richtig gutes Tutorial auf deutsch: ui factory am Beispiel einer canvas map I ui factory am […]
June 8, 2010, 11:40 pmLee says:
I can’t seem to catch any events I trigger in these widget subclasses. I call this._trigger as usual but can not seem to catch the event in the normal way.
July 6, 2010, 8:25 amDanny says:
@Lee:
July 13, 2010, 8:28 pmI haven’t had any problems with event triggering, but I may not be using the code the same way you are. Can you post some more details?
–Danny
Lee says:
@Danny:
Hopefully this bit of code sums it up:
$.ui.widget.subclass(‘ui.superwidget’,
{
_init: function()
{
// can’t catch this
this._trigger(‘anevent’);
// can catch this
this.element.trigger(‘superwidgetanevent’);
}
});
And creation and binding:
July 19, 2010, 6:58 am$(‘#test’).bind(‘superwidgetanevent’, function()
{
console.log(‘an event happened’)
});
$(‘#test’).superwidget();
Danny says:
@Lee
July 22, 2010, 4:04 pmUnfortunately, my life is kind of busy now, but I’ll try to take a look at this. It looks like it ought to work, but there may be something going on where the event handler is being bound before the subclass really exists, so it’s binding to the superclass.
Danny
http://bililite.nfshost.com/blog/extending-jquer… « Social Game Programming Gems says:
[…] http://bililite.nfshost.com/blog/extending-jquer… http://bililite.nfshost.com/blog/extending-jquery-ui-widgets/ […]
September 6, 2010, 10:34 pmSaudi Jobs says:
Nice work man.Thanks for sharing jQuery UI Widgets.
September 10, 2010, 5:39 pmlinks for 2010-11-14 at Here I Rule says:
[…] Hacking at 0300 : Extending jQuery UI Widgets (tags: extending jquery-ui widget howto) VN:F [1.9.6_1107]please wait…Rating: 0.0/10 (0 votes cast)VN:F [1.9.6_1107]Rating: 0 (from 0 votes) […]
November 14, 2010, 6:36 pmdarkside says:
@inktri
September 15, 2011, 4:18 pmYou should use $.extend(true, …, …) for recursive extending objects
Nolege says:
Worked Great for 1.8. Breaks for new 1.9 release. Just
January 7, 2013, 7:13 pmletting you know because I upgraded and need to fix the changes.
Thanks.
Danny says:
@Nolege:
I suspect that’s because 1.9 adds a _super method of its own, though it is not as sophisticated as mine—you have to explicitly give it the name of the method. Did you fix it? I hope that all I would have to do is to change my _super to $super or something. Google Library API is still serving 1.8.7, so I don’t feel the pressure yet.
Have you gotten it to work? What did you do?
January 7, 2013, 9:39 pm–Danny
Danny says:
@Nolege:
January 8, 2013, 8:53 amI fixed it. Turns out 1.9’s
_super
method is my method; I’d been in contact with Scott Gonzalez a while back and he incorporated many of my ideas. So that’s not the conflict.The problem is that 1.9 changed to use the prototype passed to
$.widget
(the documentation always required that second parameter, just before this having it undefined did not throw an error), so just change any$.widget('name')
to$.widget('name', {})
and you’re done. I think.–Danny
Vikram Lele says:
Hi Danny,
Thanks for an excellent article on widget subclassing.
I still have a bit of a confusion about how to achieve “virtual” function effect here. For example, in the subclass code
$.ui.widget.subclass(‘ui.superbox’,{
_init: function(){
var self = this;
this.element.click(function(){
self.move();
});
},
you have hooked the click again in the subclass. This is actually already hooked in the base widget. So, is there a way to provide a new implementation of move() in the derived widget and make it work without explicitly hooking into click once again?
December 31, 2013, 11:21 pmDanny says:
@Vikram Lele:
The base widget,
$.ui.widget
that is created with$.widget('ui.widget',{});
does not hook into the click event. The only click handler is in the first subclass,$.ui.superbox
, created with the code you quoted above. All of its subclasses just overridemove()
but rely on the same event handler.I think your confusion is looking at the sample code at the very top of the page, when I create
$.ui.superbox
without using the subclassing code. That’s just a sample of how to create a simple widget; the code you quote is supposed to replace that. Note that the actual code is almost identical.Hope this helps,
January 1, 2014, 10:58 am–Danny