will
will

Reputation: 4575

Using $(this) when calling an element-based plugin

I'm creating a plugin for jQuery. I wont attempt to explain the plugin here, so lets say for simplicity that my plugin opens an alert when you click on the targeted element. Here is a simple version of my plugin.

(function($) {  

    // Options
    var defaults = {
        message:    'Default message'
    };

    var options = $.extend(defaults, options);

    $.fn.jAlert = function(options) {
        return this.each(function(){

            var $this = $(this);

            $this.click(function(){
                alert(options.message);
            });

        });
    };
})(jQuery);

I can get that far. It works great. However, if I call my plugin like this:

$('h1.simon').plugin({ message: 'Hello ' + $(this).attr('class') });

The message returns as 'Hello undefined', I'd prefer it to be 'Hello simon' (the class of the H1 tag).

I'm sure this is the simplest thing to do, but I'm not even sure what I should be Googling to find the solution.

Any help would be greatly appreciated!

Cheers,
Will

Update:

After playing about a bit, this seems to work... And I have no idea why! I don't think I really understand scope yet. I think I'll go do some reading.

$('h1.simon').click(function(){
    $(this).jAlert({
        icon:   'Hello ' + $(this).attr('class')
    });
});

Upvotes: 2

Views: 116

Answers (3)

user113716
user113716

Reputation: 322452

If you want to be able to use this for convenience, you could allow message to accept a function that returns the value you want to display.

Try it out: http://jsfiddle.net/9hyJc/

(function($) {  

    $.fn.jAlert = function(options) {

    // Options
    var defaults = {
        message:    'Default message'
    };

    var options = $.extend(defaults, options);

        return this.each(function(){

            var $this = $(this);

            $this.click(function(){
                if($.isFunction(options.message)) {
                       // If it is a function, call it, 
                       //    setting "this" to the current element
                    alert(options.message.call(this));
                } else {
                       // Otherwise, assume it is a string
                    alert(options.message);
                }
            });

        });
    };
})(jQuery);

$('h1.simon').jAlert({ message: function() { return 'Hello ' + $(this).attr('class'); } });

Upvotes: 2

meder omuraliev
meder omuraliev

Reputation: 186562

Save a reference to the element:

var $el = $('h1.simon');
$el.plugin({ message: 'Hello ' + $el.attr('class') }); 

Otherwise this refers to window which doesn't have a class.

Upvotes: 2

Scott Evernden
Scott Evernden

Reputation: 39940

at the time you are calling the plugin and passing the options .. this refers to window and NOT the element as you seem to expect

Upvotes: 0

Related Questions