Mike
Mike

Reputation: 1

Checkboxes Disabled When other Checkbox is Clicked - All With Different IDs

I am trying to customize a pre-formatted sign-up form for customers to join our mailing list. Basically I have three different 'Interest Groups' - one interest group that receives information about Dogs a few times a week, another interest group that receives information about Cats a few times a week and then a third group that just receives a once-a-week update on both subjects. Customers can subscribe to both interest groups one and two at the same time, however if they subscribe to group three, they can't subscribe to the other two.

Working with the code below that was provided by the e-mail service provider - I need the first two check boxes to be disabled if the customer clicks the third check box.

Existing Java Script (the page appears to be using jquery):

<script type="text/javascript" src="http://www.google.com/jsapi"></script> 
    <script type="text/javascript"> 
        google.load("jquery", "1.4.2");
    </script> 
    <script type="text/javascript"> 
        $(document).ready(function(){   
            try {
            $('#archive-list li:even').addClass("odd");
            $('.field-group, .field-group input, .field-group select').live('click',function(event){                    
                if (event.type == 'click') {
                    if ($(this).hasClass('field-group')){
                        var fg = $(this);
                        $(this).find('input, select').slice(0,1).focus();
                    } else {
                        var fg = $(this).parents('.field-group');
                        $(this).focus();
                    }
                    fg.not('.focused-field').addClass('focused-field').children('.field-help').slideDown('fast');
                    $('.focused-field').not(fg).removeClass('focused-field').children('.field-help').slideUp('fast');
                }
            });
            } catch(e){ console.log(e); }
        });     
    </script>

And then the HTML:

<ul class="interestgroup_field" id="interestgroup_field_400000">
                <li class="interestgroup_row"><input type="checkbox" id="group_128" name="group[1][128]" value="1">&nbsp;<label for="group_128">E-mails about Dogs</label></li>
                <li class="interestgroup_row"><input type="checkbox" id="group_256" name="group[1][256]" value="1">&nbsp;<label for="group_256">E-mails about Cats</label></li>
            </ul>
            <br>
            <ul class="interestgroup_field" id="interestgroup_field_400000">
                <li class="interestgroup_row"><input type="checkbox" id="group_2" name="group[1][2]" value="1">&nbsp;<label for="group_2" >Once A Week - Summary E-mail</label></li>
            </ul>

Note the unique IDs - these are used to sync with the database. I've searched for an answer, however the best solution I could find used the the same ID for all check boxes, which doesn't work for my application.

Thank you for your time - any help would be much appreciated!

Cheers, Mike

Upvotes: 0

Views: 1003

Answers (1)

Brandon
Brandon

Reputation: 39182

As mentioned, you cannot have your 2 ULs have the same id. This is bad and will lead to problems. If you need to store the database record identifier, then use HTML5 data-* attributes or use classes:

<ul class="interestgroup_field" data-id="interestgroup_field_400000">
    <li class="interestgroup_row"><input type="checkbox" id="group_128" name="group[1][128]" value="1">&nbsp;<label for="group_128">E-mails about Dogs</label></li>
    <li class="interestgroup_row"><input type="checkbox" id="group_256" name="group[1][256]" value="1">&nbsp;<label for="group_256">E-mails about Cats</label></li>
</ul>
<br />
<ul class="interestgroup_field" data-id="interestgroup_field_400000">
    <li class="interestgroup_row"><input type="checkbox" id="group_2" name="group[1][2]" value="1">&nbsp;<label for="group_2" >Once A Week - Summary E-mail</label></li>
</ul>

Then, something along the lines of this should do it:

$(document).ready(function() {
    $('ul.interestgroup input:checkbox').change(function() {
        // see if this is the 3rd checkbox that is by itself
        if ($(this).closest('ul').children().length > 1) return; // nope
        // grab the other 2 checkboxes so we can fiddle with them
        var cbs = $(this).closest('ul').prev().prev().find('input:checkbox');

        if ($(this).attr('checked')) {
            // disable the others
            cbs.attr({ 'checked': false, 'disabled': 'disabled' });
        } else {
            // enable the others
            cbs.attr({ 'disabled': '' });
        }
    });
});

Here's another solution that is less-dependent on your HTML structure if your checkboxes are not always laid out like the above:

To make it work, when generating your checkboxes you need to put a couple of bits of information on each checkbox. On the "combined" checkbox, you want to add a special CSS Class to mark the checkbox as a combined checkbox. Checkboxes with this class will trigger the special behaviour. Second, on the combined checkbox, you want to leave the ids of the checkboxes it is meant to disable:

<input type="checkbox" id="group_128" name="group[1][128]" value="1">Cats</input>
<input type="checkbox" id="group_256" name="group[1][256]" value="1">Dogs</input>
<!-- random html --!>
<input type="checkbox" id="group_2" name="group[1][2]" value="1"
    class="combined" data-other-cb="#group_128,#group_256">
    Cats and dogs</input>

See how we put "combined" as the css class of the checkbox? Use any css class you want and it does not need any style rules. We just need to use it as a marker class. And see how we used a "data-other-cb" attribute to put a comma-delimited list of the ids of the other checkboxes? Also note that we placed a '#' in front of each id. This makes it a valid jQuery selector string so we can just pass this entire value to jQuery to get back all of the checkboxes in question

Now we can write the following jquery delegate method:

$(document).ready(function() {
    $('body').delegate('.combined', 'change', function() { // hookup to change event of all current and future .combined elements
        // get the ids of the checkboxes we need to control
        var ids = $(this).attr('data-other-cb');
        if (!ids) return; // no other ids

        // find the checkboxes and manipulate them
        var cbs = $(ids);

        if ($(this).attr('checked')) {
            // disable the others
            cbs.attr({ 'checked': false, 'disabled': 'disabled' });
        } else {
            // enable the others
            cbs.attr({ 'disabled': '' });
        }
    }); // delegate()
}); // ready()

Upvotes: 1

Related Questions