1

I am learning to write jquery-ui plugins using the widget-factory pattern. For cleaner organization, I have some helper methods defined inside the object literal that is passed to $.widget. I would like to access the options object in those helpers. For example in the boilerplate below, how do I access the options object inside _helper()?

;(function ( $, window, document, undefined ) {

    $.widget( "namespace.widgetName" , {

        options: {
            someValue: null
        },

        _create: function () {
            // initialize something....
        },

        destroy: function () {

            $.Widget.prototype.destroy.call(this);
        },

        _helper: function () {
            // I want to access options here.
            // "this" points to the dom element, 
            // not this object literal, therefore this.options wont work
            console.log('methodB called');
        },

        _setOption: function ( key, value ) {
            switch (key) {
            case "someValue":
                //this.options.someValue = doSomethingWith( value );
                break;
            default:
                //this.options[ key ] = value;
                break;
            }
            $.Widget.prototype._setOption.apply( this, arguments );
        }
    });

})( jQuery, window, document );

Thank you.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
Gurunandan Bhat
  • 3,544
  • 3
  • 31
  • 43
  • Aren't methods with a leading underscore considered private by the widget factory? So how are you calling `_helper`? – mu is too short Aug 12 '12 at 03:39
  • Well, in the _create method, this points to the object literal (2nd arg to $.widget) and therefore can be called inside _create as this._helper() – Gurunandan Bhat Aug 12 '12 at 03:49
  • But you say that '"this" points to the dom element' so what does the `._helper()` call look like? And `_create` is a special method that's part of the widget interface. – mu is too short Aug 12 '12 at 03:54
  • _helper is in fact a handler for a 'click' event which is set in _create like so: $(some_selector).click(this._helper). The event subsystem therefore calls it on a DOM element. I was looking for a way to use the options property inside _helper. – Gurunandan Bhat Aug 12 '12 at 06:26

1 Answers1

1

So you're doing this inside your _create:

$(some_selector).click(this._helper)

and you want this inside the _helper to be the this on this._helper (i.e. your widget).

There are various solutions:

  1. You could use $.proxy

    $(some_selector).click($.bind(this._helper, this));
    

    Underscore also has _.bind and there's a native Function.bind if you don't have to worry about JavaScript version issues). Other libraries will have their own function binding tools. You already have jQuery in play so $.proxy is already available and portable as well.

  2. You could use the standard var _this = this; trick proxy the _helper call yourself:

    var _this = this;
    $(some_selector).click(function() { _this._helper() });
    
  3. You could use the eventData form of click:

    $(some_selector).click({ self: this }, this._helper);
    

    and then in _helper:

    _helper: function(ev) {
        var self = ev.data.self;
        // 'self' is the 'this' you're looking for.
        ...
    }
    
mu is too short
  • 426,620
  • 70
  • 833
  • 800
  • In the meanwhile I tried passing options as a part of the event.data to bind and that works as expected. But Thanks for the proxy solution - it helped me add one more trick to my growing jquery skills :). Have accepted your answer – Gurunandan Bhat Aug 12 '12 at 20:20
  • 1
    @Ya.Perelman: Right, the `eventData` is another option, I'll add that for completeness. I do a lot of Backbone stuff lately so my brain always reaches for the binding solutions. – mu is too short Aug 12 '12 at 20:30