Search code examples
javascriptjqueryhtmltoggleclassuniform

Updating child element classes when table row is clicked


I have a table of product options, each tr is one option. One is selected by default, to select another, a radio button must be checked before the form is submitted. This is easy enough but the entire tr must be clickable and check the radio button accordingly.

I think I've managed to get this to work using the script below:

$('.product-options tr').click(function() {
    $(this).find('td input[type=radio]').prop('checked', true);
});

In addition to this I also need to add a class of .selected to the tr. I tried with the following code but I also need to check if another tr already has a class of .selected and remove it.

$('.product-options tr').click(function() {
    $(this).find('td input[type=radio]').prop('checked', true);
    $(this).toggleClass('selected', true);
});

Obviously this will only toggle the class if you click the same radio button. This is where my limited javascript knowledge falls down. Can anyone help?

Finally, I also use a plugin called uniform.js which allows, selects/radio/checkboxes to be fully customisable. As this wraps a div then a span around the radio input a class of .checked is added to the span to toggle the checked/unchecked styling. This only changes if you click directly on the input. So I'll also need to factor in a similar bit of script to the tr.selected class for when any part of the tr is clicked, the custom radio button also has an updated class.

For reference mark-up for the javascript generated radio is:

<div class="radio">
    <span>
        <input type="radio" name="" />
    </span>
</div>

EDIT: Here's a CodePen with uniform.js included which should demonstrate the issue(s) better:

http://codepen.io/moy/pen/yeGRmO

Thanks, really hope someone can help with this. It seemed simple enough ...but as it's 'layered up', I'm a bit lost! :)


Solution

  • If I understand correctly you can simply access the siblings of the tr and put the checked radio on false.

    $('.product-options tr').click(function() {
        $(this).find('td input[type=radio]').prop('checked', true);
        $(this).toggleClass('selected', true);
        $(this).siblings().find('td input[type=radio]').prop('checked', false);
        $(this).siblings().removeClass('selected');
    });
    

    This should find all radios and put them all on false, except for the row you clicked on.

    UPDATE

    To work with uniform, you can call $.uniform.update() directly when changing properties.

    $(function() {
        $('input[type="radio"]').uniform();
    
        $('.product-options tr').click(function() {
            var tr = $(this),
                radio = tr.find('td input[type=radio]'),
                siblings = tr.siblings(),
                otherRadios = siblings.find('td input[type=radio]');
    
            tr.addClass('selected');
            siblings.toggleClass('selected', false);
    
            $.uniform.update(radio.prop('checked', true));
            $.uniform.update(otherRadios.prop('checked', false));
        });
    });
    

    DEMO