SOFTELメモ

</> 技術者募集

【JavaScript】並んだチェックボックスを範囲で一括チェック

問題

検索結果などでチェックボックスが並んでいるような場面で、
全チェックではなくて、
「範囲でここからここまでまとめてチェック」をしたい。

Gmailの画面などでそんな操作ができますよね。

check range

答え

Gmailと同じ方式で、以下の操作で範囲でチェックのON、OFFができるようにしてみる。

1.始点クリック
2.Shift + 終点クリック

チェックがONになるかOFFになるかは、始点のチェック状態に従うことにする。

HTMLは次のような状態だとすると、

<ul>
  <li><input type="checkbox" class="check-range" name="x" value="1"> 検索結果 1</li>
  <li><input type="checkbox" class="check-range" name="x" value="2"> 検索結果 2</li>
  <li><input type="checkbox" class="check-range" name="x" value="3"> 検索結果 3</li>
  <li><input type="checkbox" class="check-range" name="x" value="4"> 検索結果 4</li>
  <li><input type="checkbox" class="check-range" name="x" value="5"> 検索結果 5</li>
  <li><input type="checkbox" class="check-range" name="x" value="6"> 検索結果 6</li>
  <li><input type="checkbox" class="check-range" name="x" value="7"> 検索結果 7</li>
  <li><input type="checkbox" class="check-range" name="x" value="8"> 検索結果 8</li>
  <li><input type="checkbox" class="check-range" name="x" value="9"> 検索結果 9</li>
  <li><input type="checkbox" class="check-range" name="x" value="10"> 検索結果 10</li>
</ul>

jQueryで書くとこんな風。

$(function(){

    var checked_last = null;
    $('.check-range').on('click', function(event){
        if (event.shiftKey && checked_last) {
            //Shiftを押してクリックした場所は終点として処理をする
            var $targets = $('.check-range');
            var p1 = $targets.index(checked_last)
            var p2 = $targets.index(this)
            for (var i = Math.min(p1, p2); i <= Math.max(p1, p2); ++i) {
                $targets.get(i).checked = checked_last.checked;
            }
        } else {
            //Shiftを押さずにクリックした場所は始点として覚えておく
            checked_last = this;
        }
    });

});

デモ

クリックしたチェックボックスが始点、Shiftと一緒にクリックしたチェックボックスが終点。
チェックONになるか、チェックOFFになるかは始点のチェック状態に従う。

関連するメモ

コメント