user1015214
user1015214

Reputation: 3071

not understanding jquery $(this) correctly

I think that I am misunderstanding something about how jquery $(this) works. In my code below:

$(document).delegate(".ISBN_number", "change", 
        function()
        {
            var isbnNum = $(this).val();
            console.log("isbnNum = " + isbnNum);
            $.get("validate_isbn.php", {isbn: isbnNum},
                function(answer) 
                {                   
                    console.log("answer = " + answer);    //this does display the correct content
                    if (answer == true)
                    {   console.log("entered answer");
                        $(this).after("<img src='pics/green_checkmark.png' class='checkmark'>");
                    }
                    else 
                    {
                        $(this).after("nope");
                    }
            });             
    });

I am trying to select any input tag when its contents are changed. When I call $(this) in the code, I assumed that it would refer back to this input tag but it doesn't. What is my issue? Is it because I used .delegate? (I needed to use this because the input tags are generated dynamically later on, they don't exist in the original code.) How can I fix this?

Upvotes: 0

Views: 184

Answers (5)

Umesh Patil
Umesh Patil

Reputation: 10685

If you have inputBox for ISBN number, #(this).val() gives you the value entered/changed in the text Box.

Upvotes: 0

jfriend00
jfriend00

Reputation: 707148

If you want to access this from the .delegate() call, then you have to save it into a local variable because this is set to something different in the completion function for the ajax call. You can do that like this:

$(document).delegate(".ISBN_number", "change", 
        function()
        {
            var self = this;
            var isbnNum = $(this).val();
            console.log("isbnNum = " + isbnNum);
            $.get("validate_isbn.php", {isbn: isbnNum},
                function(answer) 
                {                   
                    console.log("answer = " + answer);    //this does display the correct content
                    if (answer == true)
                    {   console.log("entered answer");
                        $(self).after("<img src='pics/green_checkmark.png' class='checkmark'>");
                    }
                    else 
                    {
                        $(self).after("nope");
                    }
            });             
    });

Upvotes: 1

Blazemonger
Blazemonger

Reputation: 92893

this may change for code inside a callback function. However, you should be able to circumvent that by using a caching variable:

$(document).delegate(".ISBN_number", "change", function () {
    var $this = $(this);
    var isbnNum = $this.val();
    console.log("isbnNum = " + isbnNum);
    $.get("validate_isbn.php", {
        isbn: isbnNum
    }, function (answer) {
        console.log("answer = " + answer); //this does display the correct content 
        if (answer == true) {
            console.log("entered answer");
            $this.after("<img src='pics/green_checkmark.png' class='checkmark'>");
        } else {
            $this.after("nope");
        }
    });
});

Upvotes: 0

Jasper
Jasper

Reputation: 75993

this (var isbnNum = $(this).val();) refers to the .ISBN_number element that had the change event fire on it. $(this) refers to that same DOM element wrapped in a jQuery object so you can call jQuery functions on it.

When you make an AJAX call or any other type of function call that uses an anonymous function it is good practice to cache the original this:

$(document).delegate(".ISBN_number", "change", 
        function()
        {
            var $this   = $(this),
                isbnNum = $this.val();
            console.log("isbnNum = " + isbnNum);
            $.get("validate_isbn.php", {isbn: isbnNum},
                function(answer) 
                {                   
                    console.log("answer = " + answer);    //this does display the correct content
                    if (answer == true)
                    {   console.log("entered answer");
                        $this.after("<img src='pics/green_checkmark.png' class='checkmark'>");
                    }
                    else 
                    {
                        $this.after("nope");
                    }
            });             
    });

That way you know you're always referring to the same this.

Upvotes: 4

Josh Smith
Josh Smith

Reputation: 15032

$(this) refers to the current scope. In your case the first $(this) refers to the .ISBN_number, and the other $(this) are in a different scope.

You should be caching the first $(this) like so:

$(document).delegate(".ISBN_number", "change", 
    function()
    {
        $isbn = $(this);
        var isbnNum = $isbn.val();
        console.log("isbnNum = " + isbnNum);
        $.get("validate_isbn.php", {isbn: isbnNum},
            function(answer) 
            {                   
                console.log("answer = " + answer);    //this does display the correct content
                if (answer == true)
                {   console.log("entered answer");
                    $isbn.after("<img src='pics/green_checkmark.png' class='checkmark'>");
                }
                else 
                {
                    $isbn.after("nope");
                }
        });             
});

Upvotes: 0

Related Questions