1

I have a problem with one jQuery script. I use this code:

<span class="follow" data-id="<?=$m['id']; ?>" ></span>

-

        $('.follow').click(function(){

        $.ajax({
            type: "POST",
            url:"../ajax/settings/follow.php", 
            async: false,
            dataType:'html',
            data: {'id':$(this).attr('data-id')},
            success:function(rs){
               $(this).removeClass("follow"); 
                $(this).addClass("unfollow"); 

            },

            error:function (xhr, ajaxOptions, thrownError){
                alert("ERROR !!!");
                alert(xhr.status);
                alert(ajaxOptions);
                alert(thrownError);

            }  
        });   

    });

After click the span with style image TICK changed to CROSS, and changed attr class to unfollow. After click unfollow class must change to follow, but not working.

        $('.unfollow').click(function(){

        $.ajax({
            type: "POST",
            url:"../ajax/settings/follow.php", 
            async: false,
            dataType:'html',
            data: {'id':$(this).attr('data-id')},
            success:function(rs){
               $(this).removeClass("unfollow"); 
                $(this).addClass("follow"); 

            },

            error:function (xhr, ajaxOptions, thrownError){
                alert("ERROR !!!");
                alert(xhr.status);
                alert(ajaxOptions);
                alert(thrownError);

            }  
        });   

    });

What's wrong?

I apologize for my English!

5 Answers 5

5
 $('.unfollow').click(function(){

   // you need keep a reference of '.unfollow' here
   // otherwise you can't get it within success()
   // because success() is another scope

   var reference = this; 

   $ajax({
      ...
      success: function() {  
        $(reference ).removeClass("unfollow"); 
        $(reference ).addClass("follow"); 
        ....
      }
   });
  });

and do same for your follow:

 $('.follow').click(function(){

   // you need keep a reference of '.unfollow' here
   // otherwise you can't get it within success()
   // because success() is another scope

   var reference = this; 

   $ajax({
      ...
      success: function() {  
        $(reference ).removeClass("follow"); 
        $(reference ).addClass("unfollow"); 
        ....
      }
   });
  });

Here one important thing to note that, changing of class not done immediately with click, because you're changing class within ajax success function, which will take some time to change the class. If you want to change the class instantly on click then take away those change statement outside of ajax success function.

Another important note

When you change the class of span then it becomes dynamic element to DOM. suppose you have span with class follow and on click event to span.follow you change the class to unfollow. As the .unfollow was not belong to DOM at page load so it becomes an dynamic element and on ordinary bind will not work here. Same for when you change class from unfollow to follow.

So in both case you need delegate event handler (aka live) event handler like following:

$(document).ready(function() {
    $('#container').on('click', 'span.follow', function() {
        var reference = this;
        alert('follow');
        $(reference).removeClass("follow");
        $(reference).addClass("unfollow");
    }).on('click', 'span.unfollow', function() {
        var reference = this;
        alert('unfollow');
        $(reference).removeClass("unfollow");
        $(reference).addClass("follow");
    });
});

DEMO

Sign up to request clarification or add additional context in comments.

2 Comments

After second click on unfolow, don't change to follow.
This not working. In the end of follow refference I added alert('follow'), and In the end of unfollow reference i added alert('unfollow'), after I click on follow the alert is follow, and class change to unfollow, but if I click on unfolow again the alert is again follow ...
0

.click() is not a live hander; it only binds the events to elements that exist with those classes at the time of execution. Try using a live handler instead:

$('body').on('click', '.follow', function() { });
$('body').on('click', '.unfollow', function() { });

Comments

0

Are you searching for this?

 $('.follow').live('click',function(){
    var t=$(this);
    $.ajax({
        type: "POST",
        url:"../ajax/settings/follow.php", 
        async: false,
        dataType:'html',
        data: {'id':$(this).attr('data-id')},
        success:function(rs){
           t.addClass("unfollow"); 
           t.removeClass("follow"); 


        },

        error:function (xhr, ajaxOptions, thrownError){
            alert("ERROR !!!");
            alert(xhr.status);
            alert(ajaxOptions);
            alert(thrownError);

        }  
    });   

});

    $('.unfollow').live('click',function(){
    var t=$(this);
    $.ajax({
        type: "POST",
        url:"../ajax/settings/follow.php", 
        async: false,
        dataType:'html',
        data: {'id':$(this).attr('data-id')},
        success:function(rs){
          t.addClass("follow"); 
          t.removeClass("unfollow"); 


        },

        error:function (xhr, ajaxOptions, thrownError){
            alert("ERROR !!!");
            alert(xhr.status);
            alert(ajaxOptions);
            alert(thrownError);

        }  
    });   

});

1 Comment

.live() is deprecated, try to avoid using it.
0

"this" inside of the function will not pointing on your object, try to save it in the variable or use id attribute try

    $('.unfollow').click(function(){
            var _my_obj=$(this);
            $.ajax({
                type: "POST",
                url:"../ajax/settings/follow.php", 
                async: false,
                dataType:'html',
                data: {'id':$(this).attr('data-id')},
                success:function(rs){
                    _my_obj.removeClass("unfollow"); 
                    _my_obj.addClass("follow"); 

                },
...

or

<span id='myspan' class="follow" data-id="<?=$m['id']; ?>" ></span>

$('myspan').removeClass('unfollow');
$('myspan').addClass('follow');

Comments

0

Are you looking more for something like this?

$("div.follow").click(function () {
    $(this).toggleClass("unfollow").toggleClass("follow");
});

Demo: http://jsfiddle.net/mikecruz/b6ggd/

Here is how to do it with the ajax: I used test2.php as a test to just echo a random number to change the inner text to something random. used classes red/blue (change the code to your classnames) just to change font color to show the change (See fiddle, but can't put the php ajax call there)

$(document).ready(function(){
    $("div.red").click(function () {
        var t = this;
        $.ajax({
            type: "POST",
            url: "./test2.php",
            cache: false,
            success: function(text){
                $(t).toggleClass("blue").toggleClass("red");
                $(t).text(text);
            }
        });     
    });
});

3 Comments

You are not actually removing the red class, you are just tacking on the blue class and overwriting the red class rules... (if you inspect the element it is now class="red blue"), while this works for the limited example it may cause complications down the road.
@rlemon Opps. good catch. Can fix that with chaining toggleClass. updated answer / fiddle.
They don't need to be chained IIRC you can just write .toggleClass("red blue") and it will toggle both. yes, yes it will... see here and api.jquery.com/toggleClass/#toggleClass1 for API ref

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.