【jQuery】「すべてを選択」の実装完全ガイド|indeterminate・グループ全選択・選択件数・一括操作まで

テーブル型のUIやアンケートフォームで「すべてを選択」チェックボックスは定番の機能です。基本的な全選択/全解除から、indeterminate(中間)状態・グループ単位の全選択・選択件数のカウント・一括操作ボタンの活性化まで、実務で使えるパターンを体系的に解説します。

この記事でわかること

  • 「すべてを選択」チェックボックスの基本実装
  • 子チェックが全てオンになったとき親チェックも自動でオンにする連動処理
  • indeterminate(一部チェック時の中間状態)の実装
  • グループ単位での全選択(カテゴリ別に独立した全選択)
  • 選択件数をリアルタイムに表示する方法
  • 全選択+1件以上選択を必須にするバリデーション
  • チェックした項目に対する一括操作ボタンの活性化制御
スポンサーリンク

1. 基本実装:全選択・全解除

「すべてを選択」チェックボックスをオン/オフするだけで、配下の全チェックボックスを連動させます。

<label><input type="checkbox" id="check-all"> すべてを選択</label>
<hr>
<ul id="item-list">
  <li><label><input type="checkbox" class="item-check"> りんご</label></li>
  <li><label><input type="checkbox" class="item-check"> みかん</label></li>
  <li><label><input type="checkbox" class="item-check"> ぶどう</label></li>
  <li><label><input type="checkbox" class="item-check"> いちご</label></li>
</ul>
$(function () {
  // 「すべてを選択」チェックを操作したとき
  $('#check-all').on('change', function () {
    var isChecked = $(this).prop('checked');
    $('.item-check').prop('checked', isChecked);
  });

  // 個別チェックを操作したとき
  $('.item-check').on('change', function () {
    var total   = $('.item-check').length;
    var checked = $('.item-check:checked').length;
    // 全てチェックされていれば「すべてを選択」もオンに
    $('#check-all').prop('checked', total === checked);
  });
});
prop(“checked”) でチェック状態を操作する
prop("checked", true/false) でチェックの状態を取得・設定します。attr("checked") は初期値しか反映しないため、動的な操作には必ず prop() を使ってください。詳細はチェックボックスを操作する完全ガイドを参照してください。

2. indeterminate(中間)状態を実装する

一部だけチェックされているとき、「すべてを選択」チェックボックスをindeterminate(ダッシュ記号で表示される中間状態)にすると、より直感的なUIになります。Google スプレッドシートなどで広く使われているパターンです。

$(function () {
  function updateParentState() {
    var total   = $('.item-check').length;
    var checked = $('.item-check:checked').length;

    if (checked === 0) {
      // 全解除
      $('#check-all').prop({ checked: false, indeterminate: false });

    } else if (checked === total) {
      // 全選択
      $('#check-all').prop({ checked: true, indeterminate: false });

    } else {
      // 一部選択 → indeterminate
      $('#check-all').prop({ checked: false, indeterminate: true });
    }
  }

  $('#check-all').on('change', function () {
    // indeterminate状態からクリックされた場合は全選択に
    var toCheck = $(this).prop('checked');
    $('.item-check').prop('checked', toCheck);
    $(this).prop('indeterminate', false);
  });

  $('.item-check').on('change', updateParentState);
});
indeterminateはHTMLで設定できない
indeterminate状態はHTMLの属性では設定できず、JavaScriptの .prop("indeterminate", true) でのみ設定可能です。またindeterminateはあくまで見た目の状態であり、フォーム送信時には未チェック(false)として扱われます。

3. グループ単位での全選択

カテゴリ別に「全選択」を独立して持たせるパターンです。「果物をすべて選択」「野菜をすべて選択」のように、グループごとに制御できます。

<div class="check-group" data-group="fruits">
  <label><input type="checkbox" class="group-all" data-group="fruits"> 果物をすべて選択</label>
  <ul>
    <li><label><input type="checkbox" class="group-item" data-group="fruits"> りんご</label></li>
    <li><label><input type="checkbox" class="group-item" data-group="fruits"> みかん</label></li>
  </ul>
</div>

<div class="check-group" data-group="vegs">
  <label><input type="checkbox" class="group-all" data-group="vegs"> 野菜をすべて選択</label>
  <ul>
    <li><label><input type="checkbox" class="group-item" data-group="vegs"> にんじん</label></li>
    <li><label><input type="checkbox" class="group-item" data-group="vegs"> ほうれん草</label></li>
  </ul>
</div>
$(function () {
  // 「グループ全選択」チェック操作
  $('.group-all').on('change', function () {
    var group     = $(this).data('group');
    var isChecked = $(this).prop('checked');
    $('.group-item[data-group="' + group + '"]').prop('checked', isChecked);
  });

  // 個別チェック操作で親チェックを更新
  $('.group-item').on('change', function () {
    var group   = $(this).data('group');
    var $items  = $('.group-item[data-group="' + group + '"]');
    var total   = $items.length;
    var checked = $items.filter(':checked').length;

    $('.group-all[data-group="' + group + '"]').prop({
      checked:       total === checked,
      indeterminate: checked > 0 && checked < total
    });
  });
});
data属性でグループを識別する
data-group="fruits" のようにdata属性でグループ名を管理することで、グループ数が増えてもJavaScriptを修正せずに対応できます。data属性の詳細はdata属性の取得・設定・入れ子活用完全ガイドを参照してください。

4. 選択件数をリアルタイムに表示する

何件選択しているかをリアルタイム表示することで、ユーザーの確認ミスを防げます。削除確認ダイアログや一括処理のUIで特に有用です。

<label><input type="checkbox" id="ca-all"> すべてを選択</label>
<span id="count-display">0件選択中</span>
<ul id="ca-list">
  <li><label><input type="checkbox" class="ca-item"> 項目A</label></li>
  <li><label><input type="checkbox" class="ca-item"> 項目B</label></li>
  <li><label><input type="checkbox" class="ca-item"> 項目C</label></li>
  <li><label><input type="checkbox" class="ca-item"> 項目D</label></li>
</ul>
$(function () {
  function updateCount() {
    var count = $('.ca-item:checked').length;
    $('#count-display').text(count + '件選択中');
  }

  $('#ca-all').on('change', function () {
    $('.ca-item').prop('checked', $(this).prop('checked'));
    updateCount();
  });

  $('.ca-item').on('change', function () {
    var total   = $('.ca-item').length;
    var checked = $('.ca-item:checked').length;
    $('#ca-all').prop({
      checked:       total === checked,
      indeterminate: checked > 0 && checked < total
    });
    updateCount();
  });
});

5. 全選択+1件以上選択を必須にするバリデーション

フォームの送信前に「1件以上選択されているか」を検証し、0件のときは送信ボタンをグレーアウトして操作を阻止します。

<form id="bulk-form">
  <label><input type="checkbox" id="val-all"> すべてを選択</label>
  <ul>
    <li><label><input type="checkbox" class="val-item" value="a"> 項目A</label></li>
    <li><label><input type="checkbox" class="val-item" value="b"> 項目B</label></li>
    <li><label><input type="checkbox" class="val-item" value="c"> 項目C</label></li>
  </ul>
  <p id="val-error" style="color:red; display:none;">1件以上選択してください。</p>
  <button type="submit" id="submit-btn" disabled>選択した項目を処理する</button>
</form>
$(function () {
  function syncAll() {
    var total   = $('.val-item').length;
    var checked = $('.val-item:checked').length;
    $('#val-all').prop({
      checked:       total === checked,
      indeterminate: checked > 0 && checked < total
    });
    // 送信ボタン: 1件以上選択で有効化
    $('#submit-btn').prop('disabled', checked === 0);
    $('#val-error').hide();  // 操作中はエラーを隠す
  }

  $('#val-all').on('change', function () {
    $('.val-item').prop('checked', $(this).prop('checked'));
    syncAll();
  });
  $('.val-item').on('change', syncAll);

  $('#bulk-form').on('submit', function (e) {
    if ($('.val-item:checked').length === 0) {
      e.preventDefault();
      $('#val-error').show();
    }
  });
});
送信ボタンを disabled で制御するUX
送信ボタンを初期状態で disabled にしておき、1件以上チェックされたタイミングで有効化することで、ユーザーが誤って空送信するのを防げます。フォームバリデーション全般はフォームバリデーション完全ガイドも参照してください。

6. チェックした項目に対する一括操作ボタンを活性化する

管理画面のリストでよく見られる「選択した項目を削除」「選択した項目をエクスポート」のような一括操作ボタンを、チェック状態に連動して活性化/非活性化するパターンです。

<div id="toolbar" style="display:flex; gap:8px; margin-bottom:8px;">
  <label><input type="checkbox" id="tb-all"> すべてを選択</label>
  <span id="tb-count" style="color:#666;">(0件選択中)</span>
  <button class="bulk-btn" id="btn-delete" disabled>削除</button>
  <button class="bulk-btn" id="btn-export" disabled>エクスポート</button>
</div>
<table id="data-table">
  <tbody>
    <tr><td><input type="checkbox" class="tb-item" value="1"></td><td>レコード 1</td></tr>
    <tr><td><input type="checkbox" class="tb-item" value="2"></td><td>レコード 2</td></tr>
    <tr><td><input type="checkbox" class="tb-item" value="3"></td><td>レコード 3</td></tr>
  </tbody>
</table>
$(function () {
  function updateToolbar() {
    var checked = $('.tb-item:checked').length;
    var total   = $('.tb-item').length;

    // 件数表示を更新
    $('#tb-count').text('(' + checked + '件選択中)');

    // 一括操作ボタンの活性化
    $('.bulk-btn').prop('disabled', checked === 0);

    // 全選択チェックの状態更新
    $('#tb-all').prop({
      checked:       total === checked,
      indeterminate: checked > 0 && checked < total
    });

    // チェック行に is-selected クラスを付けてハイライト
    $('.tb-item').closest('tr').each(function () {
      var isChecked = $(this).find('.tb-item').prop('checked');
      $(this).toggleClass('is-selected', isChecked);
    });
  }

  $('#tb-all').on('change', function () {
    $('.tb-item').prop('checked', $(this).prop('checked'));
    updateToolbar();
  });

  $('.tb-item').on('change', updateToolbar);

  // 削除ボタン
  $('#btn-delete').on('click', function () {
    $('.tb-item:checked').closest('tr').remove();
    updateToolbar();
  });
});
チェック行をハイライトするとUXが上がる
チェックされた行の tris-selected クラスを付与し、CSSで背景色を変えることで「何を選択しているか」が視覚的に明確になります。toggleClass("is-selected", bool) を使うと条件式が不要でコードがスッキリします。

パターン選択の目安まとめ

要件 推奨パターン
シンプルな全選択/全解除 セクション1(基本実装)
一部チェック時に中間状態を表示 セクション2(indeterminate)
カテゴリ別に独立した全選択 セクション3(グループ全選択)
選択件数の常時表示 セクション4(カウント表示)
1件以上の選択を必須にする セクション5(バリデーション)
管理画面の一括操作UI セクション6(ツールバー連動)

まとめ

「すべてを選択」の実装は、基本のprop(“checked”)連動から始まり、indeterminate状態・グループ管理・件数表示・一括操作UIまで幅広く展開できます。本記事のパターンを組み合わせて、使いやすいUIを構築してください。

関連記事: チェックボックスを操作する完全ガイド / フォームバリデーション完全ガイド / 読み込み時にチェックボックスを判定・チェックする方法

よくある質問(FAQ)

Q「すべてを選択」を押しても子チェックボックスが動きません。
Aセレクターが子チェックボックスを正しく取得できていない可能性があります。$(".item-check") のクラス名や $("input[type=checkbox]") の指定を確認してください。また、動的に追加した要素は $(document).on("change", ".item-check", fn) のように委譲イベントを使う必要があります。
Qindeterminate状態はブラウザによって見た目が違いますか?
Aはい、ブラウザとOSの組み合わせによって見た目が異なります(Windowsではダッシュ、macOSではハイフンなど)。デザインを統一したい場合は、チェックボックスをカスタムCSSで描画する方法(appearance:none)を検討してください。
Q動的に追加したチェックボックスにも全選択を適用したいです。
A$(".item-check").on("change", fn) はイベント登録時に存在する要素にしか効きません。動的に追加した要素には $(document).on("change", ".item-check", fn) のように親要素に委譲イベントを登録してください。
Q選択した項目のvalue値を配列で取得するには?
A$(".item-check:checked").map(function(){ return $(this).val(); }).get() でチェックされた全項目のvalue値を配列として取得できます。これをAjaxのパラメーターとして送信すると一括処理が実装できます。
Qページ読み込み時にチェック済み項目がある場合、「すべてを選択」の初期状態をどうすれば?
A$(function(){}) の中で updateParentState() を一度呼べば、ページ読み込み時のチェック状態に合わせて「すべてを選択」の状態が自動的に設定されます。