views:

79

answers:

6
$(document).ready(function () {
    $('.raj').click(function () {
        if (!$(this).hasClass('already')) {

            $('.infos').html('');

            $('.infos').hide("fast");

            $.ajax({
                type: "POST",
                dataType: "json",
                url: "ggg/hhh/rrr.php",
                success: function (msg) {
                    $('.infos').html(msg['ats']);
                    arr = msg['valid'];
                }
            });

            $('.infos').show("slow");

            if (arr == 1) {
                $(this).css("cursor", "default");
                $(this).addClass('already');
                $(this).animate({
                    opacity: 0.1
                }, 1000);
            }
        }
    })
})

When I click an element with class raj (it's an image), nothing happens. Only once it is clicked a second time does my event seem to fire. Why is this happening?

edit: this part is f*cked up:

if(arr == 1)
{
    $(this).css("cursor", "default");
    $(this).addClass('already');
    $(this).animate({
        opacity: 0.1
    }, 1000);
}

But msg['valid'] is really always 1, so I do not get it.

+1  A: 

try running the if(arr==1) statement inside your ajax callback (the success function)

bvh
What a hell?!?! It works with arr=1, not arr==1 the first time. How can it be?! Really, maybe I died?
hey
`arr==1` is true if `arr` is 1 and false if it isn't. `arr=1` is always true.
David Dorward
+1  A: 

You know that your "arr" is set in the post function, and that is executed after you test....

Your ajax-request is not synchronous, you only configure the browser that you want to do an ajax-request, but you never know when it will be executed.

That's why it works the second time, since then the ajax-request has been executed.

some
Then how should I check? And why it works if I write `if(arr=1)` not `if(arr=2`?
hey
with arr=1 you set the variable arr to 1, with arr==1 you test if it set to 1.
some
You should move the test into the success function like Vinzenz have written in his reply. That's the first time you can test for msg["valid"]
some
+3  A: 

I am wondering shouldn't it be like this?

$(document).ready(function() { 
    $('.raj').click(function(){
        var thisObj = $(this);
        if(!$(this).hasClass('already'))
        {
            $('.infos').html('');
            $('.infos').hide("fast");
            $.ajax({
                type: "POST",
                dataType: "json",
                url: "ggg/hhh/rrr.php",
                success: function(msg) {
                    $('.infos').html(msg['ats']);
                    arr = msg['valid'];
                    $('.infos').show("slow");

                    if(arr == 1) {
                        thisObj.css("cursor", "default");
                        thisObj.addClass('already');
                        thisObj.animate({
                            opacity: 0.1
                        }, 1000);
                    }
                }
            });         

        }
    })            
})

It seems like that because of the somehow hard to read indention it was misplaced.

Edit:

Additional info: The ajax call is asynchronous. That means, that arr is not set to 1 the first time, but the second time it is because the callback was triggered already (my only explanation for this)

Vinzenz
Try it like that. However the processing of the result must be done once the ajax call returns. You already checked the result before it was actually finished.
Vinzenz
@Vinzenz: Why doesn't work here `$(this)` and we have to use `thisObj`?
hey
+1 Another thing to keep in mind is that `$.ajax` has a `context:` property you can set to give `this` in the callbacks the value you want. So you could add `context: this,` to have `this` reference the element in the callback.
patrick dw
because of the context. $this refers to a different object in a different context. So we need to save this to a variable so we can use the object. For more information see here: http://www.quirksmode.org/js/this.html
Vinzenz
@patrick dw: Cool good to know. I did not know that :-)
Vinzenz
@Vinzenz: really, thank you for a help. Now I think, how many nerves can be destroyed because of programming... :)
hey
A: 

Everything from $('.infos').show("slow"); onwards runs after the Ajax request has been sent, but before the response has been received and thus before the success function has run.

This means that arr isn't set the first time, and is only set the second time because you have made it a global.

Have everything you need to happen in response to the data coming back from the server happen inside the success function, and don't forget to use the var keyword to keep your variables local.

David Dorward
A: 

best way is to have firebug and have break point and check how the flow. you can easlily resolve with this approach.

If that is not working , try click operation with live , so that you won't be having any binding problems.

gov
The delay introduced by stepping through manually will likely give the response time to come back, so the global will be set, and the script will mysteriously start working. Setting the click handler with `live` won't help either, since no HTML is being overwritten and the script works on the second attempt (if it worked first time and failed thereafter a `live` is more likely to be the solution)
David Dorward
Well inserting two alert messages would show it. first just before the condition (arr == 1) and the second in the ajax call. You would see that they are called in the wrong order that would make it obvious why it did not work
Vinzenz
A: 

You should add your f-cked part in 'success' property of AJAX request. In other hand arr equals 0 first time.

        var that = $(this);

        $.ajax({
            type: "POST",
            dataType: "json",
            url: "ggg/hhh/rrr.php",
            success: function (msg) {
                $('.infos').html(msg['ats']);
                arr = msg['valid'];

                $('.infos').show("slow");

               if (arr == 1) {
                   that.css("cursor", "default");
                   that.addClass('already');
                   that.animate({
                     opacity: 0.1
                   }, 1000);
               }

            }
        });
Aliaksei Shytkin