tags:

views:

106

answers:

2

Hi All, I have structure:

<table style="width: 100%;">
    <tr>
        <td>
            <a href="#" class="yy">one</a>
        </td>

    </tr>
    <tr>
        <td>
            <a href="#" class="xx">Two</a>
        </td>

    </tr>
    <tr>
        <td>
            <a href="#" class="xx">Three</a>
        </td>

    </tr>
</table>

CSS:

.xx {
    border: 5px solid green;    
}

.yy {
    border: 5px solid red;    
}

now on click of <a> it's class should get changed. i.e. if it's 'xx' then it should turn 'yy' and vice-versa, and rest of the <a> should remain as it is, I tried something like (ref:http://stackoverflow.com/questions/3569165/how-to-change-class-of-a-tags-in-jquery)

$("a.xx").click(function() {
  $(".yy").not(this).removeClass("yy");
  $(this).toggleClass("yy");
});​

but it didnt work that way, I tried to tweak the code, but it's not working. Can somebody help.

EDIT: May b my question was not clear enough: if I click on 2nd <a>/ any other <a> then it should turn red and rest of the tag should be green.i.e. if the <a>is having red color, then it should turn green and and rest of the should be in red, and vice-versa .

EDIT for more clear requirement (based on replies from sje397 ): say I am clicking on a having class xx/yy and i.e. I click on it again it should change i.e. if xx then it should go back to yy, if u again click on it, it should go back to xx. –

+12  A: 
$("a").click(function() {
  $(this).toggleClass("yy").toggleClass("xx");
});​

EDIT (due to author's comment)

If you want to have only one highlighted tag (i.e. having the class 'yy') and all others having the class 'xx', you can do:

$("a").click(function() {
  var $this = $(this); // this is just for performance
  if(!$this.hasClass('yy'))
    $('.yy').toggleClass("yy").toggleClass("xx");
  $this.toggleClass("yy").toggleClass("xx");
});​

Usually, however, you would use the 'cascading' property of css to simplify things. For example, rather than switching classes, just add an additional class to the selected element. Then organise your CSS so that in this more specific case, the display properties which you want for the highlight override. For example, with this CSS:

.xx {
    border: 5px solid green;    
}

.xx.yy {
    border: 5px solid red;    
}

You just need to add and remove the 'yy' class and leave the 'xx' class alone.

sje397
+1 for correctness. Except that `$('a')` would grab every link on the page.
Stephen
if I click on 2nd <a>/ any other <a> then it should turn red and rest of the tag should be green.This code is not working in that way.
Wondering
@Stephen: True. I considered that but (a) all 'a' elements in the example need the above treatment, and (b) it's simple to apply it to a subset via an additional class.
sje397
@Wondering: edited
sje397
I have edited my post
Wondering
Thanks. But see let say I am clicking on a <a> having class xx/yy and ig I click on it again it should change i.e. if xx then it should go back to yy, if u again click on it, it should go back to xx.
Wondering
@Wondering: edited again
sje397
I have edited my post for more clarification
Wondering
A way to make the code a little easier to read would be to write `$('.yy').removeClass("yy").toggleClass("xx");` instead of `$('.yy').toggleClass("yy").toggleClass("xx");`.
Peter Ajtai
+3  A: 

See update below

If the structure will never change, you can do this:

$("a.xx, a.yy").click(function() {
    var $this = $(this);
    if ($this.hasClass("xx")) {
         $this.removeClass("xx").addClass("yy");
    }
    else {
         $this.removeClass("yy").addClass("xx");
    }
});

Like this: http://jsbin.com/ecidi3

Or you can make that a bit shorter (example), but I didn't want to sacrifice clarity above:

$("a.xx, a.yy").click(function() {
    var $this = $(this);
    var classes = $this.hasClass("xx") ? ["xx", "yy"] : ["yy", "xx"];
    $this.removeClass(classes[0]).addClass(classes[1]);
});

If your structure may change, you might consider live:

$("a.xx, a.yy").live("click", function() {
    var $this = $(this);
    if ($this.hasClass("xx")) {
         $this.removeClass("xx").addClass("yy");
    }
    else {
         $this.removeClass("yy").addClass("xx");
    }
});

Like this: http://jsbin.com/ecidi3/2 This has the advantage that it will automatically keep working even if you add more links. And of course, you can change the body as shown above (example) if you want it a bit shorter.


From your update, it seems you don't just want to toggle that one link, but have it be exclusive. So:

$("a.xx, a.yy").click(function() {
  var $this, c;
  $this = $(this);
  c = $this.hasClass("xx")
            ? {us: "yy", them: "xx" }
            : {us: "xx", them: "yy" };
   $("a." + c.us).removeClass(c.us).addClass(c.them);
   $this.removeClass(c.them).addClass(c.us);
});

Live example http://jsbin.com/ecidi3/5

And of course, using live you just change how you hook it up:

$("a.xx, a.yy").live("click", function() {
             // ^-- change here

Live example: http://jsbin.com/ecidi3/6

T.J. Crowder
+1 for live, often overlooked, at least i forget it !
Ross