4

I'm a bit confused as to why this isn't working; I assume that because I'm adding the class and its not being added back into the collection I'm not sure.

Here it is on a jsbin http://jsbin.com/ayije although code is below also.

Either way I can only get the action to happen on an element once.

<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" type="text/javascript"></script>
        <script type="text/javascript" charset="utf-8">
        $(document).ready(function () {
            $('.optional').click(function () {
                $(this).removeClass('optional').addClass('selected');
                return false;
            }); 
            $('.selected').click(function () {
                $(this).removeClass('selected').addClass('rejected');
                return false;
            });
            $('.rejected').click(function () {
                $(this).removeClass('rejected').addClass('optional');
                return false;
            });
        });
        </script>
    </head>
    <body>
        <style>
            a {padding:2px;color:white;}
            .optional {background-color:blue;}
            .selected {background-color:green;}
            .rejected {background-color:red;}
        </style>


        <div id="tagContainer"> 
        <a href="#" class="rejected">a</a>
        <a href="#" class="optional"">b</a>
        <a href="#" class="selected">c</a>
    </div>
    </body>
</html>
Justin
  • 84,773
  • 49
  • 224
  • 367
Phill Price
  • 191
  • 1
  • 2
  • 12

4 Answers4

5

Not sure if you already know about this or not.... Check the jquery documentation on the .live() functionality. That way, you could do something like this.

$('.optional').live('click', function () {
                $(this).removeClass('optional').addClass('selected');
                return false;
            });

And then you don't have to worry about classes not existing at document load. As the classes change on the elements, they'll automatically be bound to.

Anthony
  • 734
  • 3
  • 9
  • 22
3

It's because the click handlers are only applied to those elements that match at document load. You should use a separate class to identify all of the links, then set up a single click handler that looks at the class that the link has and then does the appropriate class transformation.

$(document).ready(function () {
    $('.clickable').click(function () {
       var $this = $(this);
       if ($this.hasClass('optional')) {
           $this.removeClass('optional').addClass('selected');
       }
       else if ($this.hasClass('selected')) {
            $this.removeClass('selected').addClass('rejected');
       }
       else if ($this.hasClass('rejected')) {
            $this.removeClass('rejected').addClass('optional');
       }
       return false;
    });
});


<div id="tagContainer"> 
    <a href="#" class="clickable rejected">a</a>
    <a href="#" class="clickable optional">b</a>
    <a href="#" class="clickable selected">c</a>
</div>
tvanfosson
  • 524,688
  • 99
  • 697
  • 795
  • thank you; I had thought it would be just that little bit simpler but you got it - thank you! – Phill Price Sep 01 '09 at 15:17
  • gah there are two ways now; this or live - which to choose :S – Phill Price Sep 01 '09 at 15:20
  • 1
    Live applies if you are adding/removing the elements. If the elements themselves (not the classes) remain static there is no need to apply live handlers -- which come with some additional limitations. It may simplify your code somewhat, but at the cost of losing the ability to stop propagation, etc. See the limitations in the docs: http://docs.jquery.com/Events/live#typefn – tvanfosson Sep 01 '09 at 15:34
  • I probably should have said that the problem that live handlers are intended to address are applying handlers to elements that are added/removed. Of course, they can be applied otherwise. – tvanfosson Sep 01 '09 at 15:35
2

You can change your code like this

$(document).on("click", ".clickable", function(){
       var $this = $(this);
       if ($this.hasClass('optional')) {
           $this.removeClass('optional').addClass('selected');
       }
       else if ($this.hasClass('selected')) {
            $this.removeClass('selected').addClass('rejected');
       }
       else if ($this.hasClass('rejected')) {
            $this.removeClass('rejected').addClass('optional');
       }
       return false;    
});
Sanjeev Chauhan
  • 3,977
  • 3
  • 24
  • 30
0

You can also change your click handler to the live click handler:

$(document).ready(function () {
        $('.optional').live('click',function () {
            $(this).removeClass('optional').addClass('selected');               return false;
        });
        $('.selected').live('click',function () {
            $(this).removeClass('selected').addClass('rejected');               return false;
        });
        $('.rejected').live('click',function () {
            $(this).removeClass('rejected').addClass('optional'); 
        });
    });
Contra
  • 2,754
  • 4
  • 20
  • 18