Managing checkbox states based on various user behaviors

I have a list of checkboxes and I want to be able to check all of them when I click on the “All campuses” box. Alternatively, I want to the “All campuses” checkbox to uncheck when one of the campuses from the list gets unchecked and stay unchecked unless I manually check the campuses I previously unchecked. To be a bit clearer, here are the scenarious i’m looking for the program to handle:

  1. User clicks on “All campuses” and all checkboxes are checked
  2. User clicks on every single individual checkboxes for each campus and the “All campuses” checkbox automatically gets checked.
  3. User unchecks the “All campuses” checkbox and everything gets unchecked.
  4. User clicks on the “All campuses” checkbox and then all checkboxes get checked. Afterward, the user unchecks one of the campuses from the list and the “All campuses” checkbox is unchecked, but the rest of the campuses stay the same.

I added a jsFiddle with what I currently have. It currently handles scenario 1, 3 and 4 but I’m having trouble with it handling 2. Any ideas?

<input name="statewideCampus" type="checkbox" value="New" class="radio allCampuses" />All Campuses
<br />
<br />
<table style="width: 100%" class="campuses">
    <tr>
        <td>
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Apache Junction
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Aravaipa
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Bullhead City
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Chandler-Gilbert
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Chinle
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Communiversity @ Surprise
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />East Valley
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Fort Defiance
            <br />
        </td>
        <td>
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Ganado
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />GateWay
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Glendale
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Kayenta
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Keams Canyon
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Lake Havasu City
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Mesa
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />North Valley
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Paige
            <br />
        </td>
        <td>
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Paradise Valley
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Phoenix
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Phoenix Biomedical
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Prescott
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Scottsdale
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Show Low
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Signal Peak
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />South Mountain
            <br />
        </td>
        <td>
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Thatcher
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Tuba City
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Tucson
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Tucson North
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Verde Valley
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />West Valley
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Whiteriver
            <br />
            <input name="statewideCampus" type="checkbox" value="New" class="radio" />Yavapai
            <br />
        </td>
    </tr>
</table>

Here is the jQuery:

$('.allCampuses').attr('checked', true);
$('.campuses input').attr('checked', true);

$('.allCampuses').click(function () {
    if ($(this).is(':checked')) {
        $('.campuses input').attr('checked', true);
    } else {
        $('.campuses input').attr('checked', false);
    }
});

$('.campuses input').click(function () {
    if ($(this).is(':checked')) {
        $('.allCampuses').attr('checked', true);
    } else {
        $('.allCampuses').attr('checked', false);
    }
});

http://jsfiddle.net/E9KnM/

Thanks!

Answer

I would compare the length of the lists of checked and list of inputs. Also, you need to use prop instead of attr when you are changing it:

$('.allCampuses, .campuses input').attr('checked', true);

$('.allCampuses').on('change', function () {
    $('.campuses input').prop('checked', $(this).is(':checked'));
});

$('.campuses input').on('change', function() {
  $('.allCampuses').prop('checked', $('.campuses input').length == $('.campuses input:checked').length);
});

Fiddle: http://jsfiddle.net/E9KnM/2/

Leave a Reply

Your email address will not be published. Required fields are marked *