1

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.

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I know it's an old post and everything; but it still comes up when you search around. This solution is somewhat outdated, bind should be used instead it seems: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.