jQuery radio onchange toggle class of parent element?
Asked Answered
Z

7

10

Please have a look on the following:

$('#myRadio').change(function() {           

    if($(this).is(':checked'))  {
        $(this).parent().addClass('green');
    } else {                              
        $(this).parent().removeClass('green');
    }
});

Markup lookslike somewhat as following

<table>
  <tr>
    <td>Some text 1 </td>
    <td><input type="radio" value="txt1" name="myRadio" id="text1" /></td>
    <td>Some text 2 </td>
    <td><input type="radio" value="txt2" name="myRadio" id="text2" /></td>
    <td>Some text 3 </td>
    <td><input type="radio" value="txt3" name="myRadio" id="text2" /></td>
  </tr>
</table>

When I switch radio, above javascript code applies 'green' to TD tag, which is fine. But if I change the selection to another it adds the green to another but doesnt remove the green from the previously selected radio.

How do I make it work so that selecting a radio option changes its parent TD's class to green and selecting another will reset all but add green to only the newly selected!

Can it also be made to change class of its first previous TD which contains "some text 3" etc??

Thanks.

Zymosis answered 8/6, 2009 at 13:35 Comment(0)
Z
13

Try something like this:

if($(this).is(':checked'))  {
    $(this).parent().parent().parent().find('.green').removeClass('green');
    $(this).parent().addClass('green');
}

This will find the table element of your current radio button grouping, find any elements with the green class, and remove the class.

Alternatively, if you only have one radio button group on the page, it would be simpler to just do:

$('.green').removeClass('green');
Zoan answered 8/6, 2009 at 13:40 Comment(1)
@chirs pebble -> Thanks for reply. Cool it's working as required.Zymosis
L
13

You shouldn't use the change() event on radio buttons and checkboxes. It behaves a little dodgy and inconsistent across browsers (it causes problems in all versions of IE)

Use the click() event instead (don't worry about accessibility, because the click event will also be fired if you activate/select a radio button with the keyboard)

And as the others here pointed out, resetting the green is easy as well:

So simply change your code to

$('#myRadio').click(function() {           
    $(this).parents("tr").find(".green").removeClass("green");

    if($(this).is(':checked'))  {
        $(this).parent().addClass('green');
    }
});

EDIT: as requested in comment, also change the previous td:

$('#myRadio').click(function() {           
    $(this).parents("tr").find(".green").removeClass("green");

    if($(this).is(':checked'))  {
        $(this).parent().prev().andSelf().addClass('green');
    }
});

or even better, turning all td elements of the parent row green:

$('#myRadio').click(function() {           
    $(this).parents("tr").find(".green").removeClass("green");

    if($(this).is(':checked'))  {
        $(this).parents("tr").find("td").addClass('green');
    }
});
Lengthwise answered 8/6, 2009 at 13:54 Comment(7)
@active. thanks for reply. But It just adds up but doesnt remove class.Zymosis
Strange. I threw this code and HTML in jsbin.com and it worked. You can check it right here: jsbin.com/unefaLengthwise
Yes it works as I asked for @ jsbin. Somehow it just doesnt remove the .green class but adds on my local!! strange. Any Ideas how to change the background of previous TD as well?? thanks Activa.Zymosis
@activa .. its amazing .. sorry can't vote you up yet because I havent got enough repu yet. Thanks.Zymosis
@active .. sorry I dont want to make all the TR 'green' as just want to show a particular TD has been selected (and the previous Td which contains some infor related to the next).Zymosis
@wbdvlpr- I understand that you want to show the new one selected with the color applied, but what info do you want from the previous selected?Aigrette
#wbdvlpr: Simply remove the call to .andSelf() in the second code same. I think that's what you're afterLengthwise
B
4

Try this:

if($(this).is(':checked')) {
    $(this).parent().siblings('td.green').removeClass('green');
    $(this).parent().addClass('green');
}
Bernadine answered 8/6, 2009 at 13:50 Comment(1)
If you want to be a super 1337 jquery ninja hacker, you can reduce the code above into one jquery statement by using .end(). Here's a quick example: $(this).parent().siblings('td.green').removeClass('green').end().addClass('green')President
A
4

I just wrote a solution that does not care how deeply nested the radio buttons are, it just uses the name attribute of the radio buttons. This means this code would work without modification anywhere, I think - I had to write it since I have a strange situation where one radio button is nested differently than its cohorts with the same name.

$('input[type="radio"]').change( function() {
    // grab all the radio buttons with the same name as the one just changed
    var this_radio_set = $('input[name="'+$(this).attr("name")+'"]');

    // iterate through each  
    // if checked, set its parent label's class to "selected"
    // if not checked, remove the "selected" class from the parent label
    // my HTML markup for each button is  <label><input type="radio" /> Label Text</label>
    // so that this works anywhere even without a unique ID applied to the button and label
    for (var i=0; i < this_radio_set.length;i++) {
        if ( $(this_radio_set[i]).is(':checked') ) $(this_radio_set[i]).parents('label').addClass('selected');
        else $(this_radio_set[i]).parents('label').removeClass('selected');
    }
});
Assign answered 23/3, 2010 at 3:50 Comment(0)
M
1

my proposal is :

$('#myRadio').change(function() {           
    _parent = $(this).parent();
    if($(this).is(':checked'))  {
       _parent.addClass('green');
    } else {                              
       _parent.removeClass('green');
    }
});
Mancilla answered 21/2, 2012 at 12:48 Comment(0)
M
0

Here is the solution which worked great for me:

var $boxes=$('input:radio');
var $parents = $boxes.parent();
$boxes.click(function(){
    $parents.filter('.selected').removeClass('selected');
    $(this).parent().addClass('selected');
});
$boxes.filter(':checked').parent().addClass('selected');

Features:

  • Faster. Only selects list of checkboxes once.
  • Does not rely on :checked. I'm not sure if there is a certain order in which "clicked" and "changed" will be executed across browsers.
  • uses :radio instead of [type="radio"] which is jQuery recommended
  • sets class on the parent for the default value of radio button.

Hope this helps!

Marking answered 15/11, 2011 at 21:59 Comment(0)
C
0

i think this is the best and more flexible way to do this:

forget the tables (google know many reason for that) and use wrappers like below

<div id="radio_wrapper">
    <span class="radio">
        <label for="myRadio1" class="myRadio">Some text 1 </label>
        <input type="radio" value="txt1" name="myRadio" id="myRadio1" class="myRadio" />
    </span>
    <span class="radio">
        <label for="myRadio2" class="myRadio">Some text 2 </label>
        <input type="radio" value="txt2" name="myRadio" id="myRadio2" class="myRadio" />
    </span>
    <span class="radio">
        <label for="myRadio3" class="myRadio">Some text 3 </label>
        <input type="radio" value="txt3" name="myRadio" id="myRadio3" class="myRadio" />
    </span>
</div

format with CSS like this

span.radio {
    background-color: #cccccc;
}
span.currentGreen {
    background-color: #ccffcc;
}

and using this script you can do exactly the same as you want

$('.myRadio').change(function() {           
    $('.currentGreen').removeClass('currentGreen'); // remove from all
    if ($(this).is(':checked')) {
        $(this).parent().addClass('currentGreen'); // add to current
    }
});

i don't like to use filter() and find() because they use unnecessary resources in this case.

Coca answered 27/11, 2012 at 7:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.