0

I'm overlooking something here with scope resolution in this jQuery plugin. Here is a simplified example of what I'm trying to achieve:

(function($) {
    $.fn.dashboard = function(options) {
        this.onClick = function(e) {
            alert("do something");
            return false;
        };

        var createButton(parent) {
            //This should call the onClick method defined above when the link is clicked.
            var button = $('<a href="#">Reply</a>').click(this.onClick);
            parent.append(button);
        };

        return this.each(function() {
            var doc = $('body');
            createButton(doc);
        });
    };
})(jQuery);

The issue is that onClick never gets called. Definitely seems to be some manner of scope issue.

3 Answers 3

2

Inside the plugin this points to jQuery object. The issue in your code is with this.onClick which is just added a new property onClick to jQuery object.

Try this.

(function($) {
    $.fn.dashboard = function(options) {
        var doSomething = function(){
            alert("do something");
            return false;
        };

        var createButton(parent) {
            parent.append($('<a href="#">Reply</a>').click(doSomething));
        };

        return this.each(function() {
            var doc = $('body');
            createButton(doc);
        });
    };
})(jQuery);
Sign up to request clarification or add additional context in comments.

2 Comments

I didn't want to set it to an anonymous, inline function, but rather a function on my "dashboard" object.
Interesting that I didn't think this would work, hah. Thank you.
1

this is going to be a jQuery object wrapping the set of matched elements. You can either iterate over the set and assign to onClick, or (more correctly) you use jQuery's click event handler instead of assigning directly to onClick:

$.fn.dashboard = function(options) {
    this.each(function () {
        $(this).click(function(e) {

        });
    });
}

You should read the jQuery page Plugins/Authoring.

1 Comment

I want to assign the click event to a method on my plugin, rather than using inline anonymous function.
1

In your example, 'this' in the createButton method is actually referring to the createButton function itself, NOT the jQuery collection passed to the plugin.

To make this work, simply assign 'this' to a variable in the plugin method, and use that variable in your createButton (and other) functions.

(function($) {
    $.fn.dashboard = function(options) {

        var $this = this;

        this.onClick = function(e) {
            alert("do something");
            return false;
        };

        var createButton = function(parent) {
            //This should call the onClick method defined above when the link is clicked.
            var button = $('<a href="#">Reply</a>').click($this.onClick);
            parent.append(button);
        };

        return this.each(function() {
            var doc = $('body');
            createButton(doc);
        });
    };
})(jQuery);

Note that this answer only deals with the scope resolution, and in fact, as this answer mentions, you should probably assign the click function directly.

2 Comments

I figured that was the case. I like this example the best so far since I don't want to use an anonymous inline function.
Another option is to use an object to store your various plugin functions... i.e., var methods = { 'click' : function(){}, 'another' : function(){} } etc. You can then call reference the function as methods.click

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.