views:

108

answers:

2

I have three check boxes and need to disable the third if either and/or of the other two are checked. I'm sure there's a easier way than what I have currently. It's turning into what I believe is a mess and I'm hoping that someone with more jquery knowledge can shine the light here.

Here's my simple html form:

<html>
<head>
    <script type="text/javascript" src="jquery.js"></script>
    <script src="custom.js" type="text/javascript"></script>
</head>
<body>
        <input type="checkbox" class="class" id="1">First
        <input type="checkbox" class="class" id="2">Second
        <input type="checkbox" class="class" id="3">Third
    </body>
</html>

Here's the javascript I'm using with jquery v1.4.2

jQuery(document).ready(function() {
// watches the events of all checkboxes
$(":checkbox").click(function(){
if(
    // if both 1 and 2 are checked we don't want to enable Third until both are unchecked.
    (($('#1:checkbox').attr('checked'))&&($('#2:checkbox').attr('checked')))||
    ((($('#1:checkbox').attr('checked'))&&($('#2:checkbox').attr('checked')))&&($('#3:checkbox').attr('disabled')))||
    ((($('#1:checkbox').attr('checked'))||($('#2:checkbox').attr('checked')))&&($('#3:checkbox').attr('disabled')))
){
    // we don't want to do anything in the above events
} else if( 

    // handles the First check box
    (($('#1:checkbox').attr('checked'))||(!$('#1:checkbox').attr('checked')))||
    // handles the Second check box
    (($('#2:checkbox').attr('checked'))||(!$('#2:checkbox').attr('checked')))

){
// call the disableThird function
disableThird();
}
});

// handles enabling and disabling the Third checkbox
function disableThird(){
    var $checkbox = $('#3:checkbox');
    $checkbox.attr('disabled', !$checkbox.attr('disabled'));
};
});

For some reason checking #3 will disable it's self. I don't understand why.

This works, but one of the requirements is that a non programmer should be able to edit and maintain this. Ideally it'd be great if he could just add new check boxes to the html and it would work. The class for these are define and as far as I know can't be changed. The last check box in the list of check boxes will disable if any of the ones above are selected. Like wise if the last check box is selected, it will disable all the ones above it. I haven't even begun writing and testing that portion as this is quickly becoming too complicated for a non programmer to handle. I myself am more of a PHP coder than a js, let alone jquery, coder. Any help would be greatly appreciated.

+1  A: 

Okay, so the id attribute can't begin with a number. Also, the <label> tag is a nice thing to add to make the text adjacent to a checkbox clickable.

Here's how I would change your HTML:

<label><input type="checkbox" class="chkGroup" id="chk1">First</label>
<label><input type="checkbox" class="chkGroup" id="chk2">Second</label>
<label><input type="checkbox" class="chkGroup" id="chk3">Third</label>

And here's the JavaScript code:

$('.chkGroup').bind('click', function(){
    if ($('#chk1:checked,#chk2:checked').length > 0) {
        $('#chk3').attr('disabled', 'disabled').removeAttr('checked');
        $('#chk3').parent('label').css({color: '#ccc'});
    } else {
        $('#chk3').removeAttr('disabled');
        $('#chk3').parent('label').css({color: '#000'});
    }
});

To check to see if something is checked, you can just use the :checked selector. I also added a css() call to make the label gray if the adjacent checkbox is disabled.

artlung
A: 

Thank you for your very quick reply. That is some concise code and the type of thing I'm after. I knew jquery could really simplify this and I'm making it more difficult. Too true about id not beginning with a number. Thanks for the reminder. I don't have the option to really add a label or edit the html as it's generated vi a CMS. I'm trying to keep it simple for now and just nail down the js on the side outside of the larger picture. I forgot to mention that the class is shared among other control on the page. Controls that I'm not interested in. Nice code! I took what you provided and made a couple of modifications and it works nicely.

Here's what I have:

$(":checkbox").click(function(){
    if ($('#chk1:checked,#chk2:checked').length > 0) {
        $('#chk3').attr('disabled', 'disabled').removeAttr('checked');
    } else {
        $('#chk3').removeAttr('disabled');
    }
});

Works like a charm in disabling #chk3 when either or both #chk1 and #chk2 are checked. Now I just need to disable #chk1 and #chk2 when #chk3 is enabled and checked. Would you mind adding that functionality?

Moj
Go ahead and update your question, don't provide clarifications in an answer.
artlung