I'm trying to create a jQuery
control using the widget factory. The idea is that I turn a button into a jQuery button, give it an icon, and register the click
event for that button such that when invoked, it displays a calendar control on a textbox
, whose id is passed in as an option to the widget method:
$.widget("calendarButton", {
options: {
textFieldId: ''
},
_create: function () {
this.element.button(
{
icons: {
primary: "ui-icon-calendar"
}
}).click(function () {
if (this.options.textFieldId != '') {
$(this.options.textFieldId).datetimepicker('show');
return false;
}
});
}
});
The problem with this however, is that this.options
is undefined when the click handler is invoked; which makes sense since the method has a different scope. So I tried to see if there is a way to define a "static" variable which then can be accessed inside the callback method. I found this answer that explained how to create variables inside a wrapper function like this:
(function ($) {
var $options = this.options;
$.widget("calendarButton", {
options: {
textFieldId: ''
},
_create: function () {
this.element.button(
{
icons: {
primary: "ui-icon-calendar"
}
}).click(function () {
if ($options.textFieldId != '') {
$($options.textFieldId).datetimepicker('show');
return false;
}
});
}
});
})(jQuery);
But it still reports that $options
is undefined. Is there a way to achieve this? I'm trying to avoid requiring the callback function be passed in since it'll be pretty much the same for all instances. Any help is appreciated.
After playing with it for a few hours, I finally came across the jQuery Proxy method which is exactly what I was looking for. I changed the code a little bit to look like this:
$.widget("calendarButton", {
options: {
textFieldId: ''
},
_create: function () {
this.element.button(
{
icons: {
primary: "ui-icon-calendar"
}
}).on("click", $.proxy(this._clickHandler, this));
},
_clickHandler: function () {
if (this.options.textFieldId != '') {
$(this.options.textFieldId).datetimepicker('show');
}
}
});
Notice that instead of implementing the click
callback directly, I'm essentially creating a delegate that points to my private _clickHandler
function, which itself runs on the same context as the $.widget()
method (since the second argument of $.proxy(this._clickHandler, this)
returns $.widget()
's context) hence availablity of the options
variable inside the method.