jQueryで高機能マルチセレクト「jQuery multi select」検索可能・グループ全選択可能!

【記事テーマ】
・複数選択の部品が欲しい
・マルチセレクトボックスで検索可能なものが欲しい

webシステム開発では、複数データを選択するUIが必要になることがよくあります。

例えば全部署の中から特定の人を複数人選ぶ」や「複数商品の中から、特定の商品を指定という時ですね。

そういうときは、下記機能を有した高機能マルチセレクトボックスのjQueryライブラリ「multi select jquery」がおすすめです!

機能概要

◆グルーピングしたデータを一括選択可能
◆全選択・全選択解除などの関数作成可能
◆データ選択時にコールバック関数設定可能

◆検索可能multi select jqueryとは別のライブラリが必要

サンプルとサンプルソース

サンプル

「部分一致検索できます」の欄に文字を入力すると検索可能です。
また、各ラベル「役員」「営業」「事務」をクリックするとすべて選択されます。

デモ

空のhtmlファイル(demo.html等)を作成し、当ページのサンプルソースを貼り付けて、ブラウザで実行すると、すぐに動作確認できます!

サンプルソース

ライブラリは自分でダウンロードして読み込ませてください。(「公式からダウンロードしてね」の部分です)

HTML / JavaScript / jQuery / css
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8"><title>デモ</title>

  <!--   jQuery・bootstrapライブラリ読み込み -->
  <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
  <!--  /jQuery・bootstrapライブラリ読み込み -->

  <!--  公式からダウンロードしてね -->
  <link rel="stylesheet" href="https://appsol-one.com/custom/726_multi-select-jquery/css/multi-select.css">
  <script src="https://appsol-one.com/custom/726_multi-select-jquery/jquery.multi-select.js"></script>
  <script src="https://appsol-one.com/custom/726_multi-select-jquery/jquery.quicksearch.js"></script>
  <!--  /公式からダウンロードしてね -->

</head>
<body>


<div class="p-4">
  <select id='optgroup' multiple='multiple'>
    <optgroup label='役員'>
      <option value='1'>佐藤</option>
      <option value='2' selected>田中(selected属性で初期選択状態)</option>
    </optgroup>
    <optgroup label='営業'>
      <option value='3'>鈴木</option>
      <option value='4'>木下</option>
      <option value='5'>下田</option>
    </optgroup>

    <optgroup label='事務'>
      <option value='6'>田上</option>
      <option value='7' disabled>上島(disabled属性で非活性)</option>
      <option value='8'>島袋</option>
    </optgroup>

  </select>
</div>

<!-- ############ javascript  ############ -->
<script type="text/javascript">
$(function(){

  // マルチセレクトボックス化
  $('#optgroup').multiSelect({
    selectableOptgroup: true,
    selectableHeader: "<input type='text' class='search-input form-control mb-2' autocomplete='off' placeholder='部分一致検索できます'><div>選択候補</div>",
    selectionHeader: "<input type='text' class='search-input  form-control mb-2' autocomplete='off' placeholder='部分一致検索できます'><div>選択済み</div>",
    afterInit: function(ms){
      var that = this,
          $selectableSearch = that.$selectableUl.prev(),
          $selectionSearch = that.$selectionUl.prev(),
          selectableSearchString = '#'+that.$container.attr('id')+' .ms-elem-selectable:not(.ms-selected)',
          selectionSearchString = '#'+that.$container.attr('id')+' .ms-elem-selection.ms-selected';

      that.qs1 = $selectableSearch.quicksearch(selectableSearchString)
      .on('keydown', function(e){
        if (e.which === 40){
          that.$selectableUl.focus();
          return false;
        }
      });

      that.qs2 = $selectionSearch.quicksearch(selectionSearchString)
      .on('keydown', function(e){
        if (e.which == 40){
          that.$selectionUl.focus();
          return false;
        }
      });
    },
    afterSelect: function(){
      this.qs1.cache();
      this.qs2.cache();
    },
    afterDeselect: function(){
      this.qs1.cache();
      this.qs2.cache();
    }
    
  });

});
</script>
<!-- ############ /javascript  ############ -->


<!-- ############  style  ############ -->
<style>
.ms-container{ width:90%;}
.ms-container .ms-optgroup-label{background: #f3f3f3;}
ul.ms-optgroup {padding:0 !important;}
.ms-list{height:400px !important;}
</style>
<!-- ############  /style  ############ -->


</body>
</html>

公式サイト(検索可能ライブラリも含む)

公式サイトはこちらになります。
http://loudev.com/

検索も可能にする場合は、以下の「quicksearch」というライブラリも必要です。
https://github.com/riklomas/quicksearch

使い方(検索可能ライブラリも含む)

マルチセレクトボックス本体

公式サイト(http://loudev.com/)にアクセスし、右上の「Download」ボタンをクリックし、ライブラリをダウンロードしましょう。

画像はイメージです

以下の3つ取得してください。
lou-multi-select-57fb8d3\js\jquery.multi-select.js
lou-multi-select-57fb8d3\css\multi-select.css
lou-multi-select-57fb8d3\imgフォルダ


ソースへの読み込みは以下の二つとなります。
multi-select.css
jquery.multi-select.js

注意点

「multi-select.css」はcssフォルダというフォルダを作成し、その中に配備してください。また、cssフォルダと同じ階層にimgフォルダを配備しましょう。cssの中で、imgフォルダの相対パスが指定されてますので、ファイルの配置構成によって正しく表示されないので、注意してください。



jQueryのライブラリも必要なので取得・読込をしてください!
https://code.jquery.com/jquery-3.4.1.min.js
CDNでよければ、以下のコードを置いておけばOKです。

  <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>

あとは以下をコピペすれば、実行可能です。ただし、このライブラリだけだと当ページ上部のサンプルのような検索機能はつきません

HTML / JavaScript / jQuery / css
<div class="p-4">
  <select id='optgroup' multiple='multiple'>
    <optgroup label='役員'>
      <option value='1'>佐藤</option>
      <option value='2' selected>田中(selected属性で初期選択状態)</option>
    </optgroup>
    <optgroup label='営業'>
      <option value='3'>鈴木</option>
      <option value='4'>木下</option>
      <option value='5'>下田</option>
    </optgroup>

    <optgroup label='事務'>
      <option value='6'>田上</option>
      <option value='7' disabled>上島(disabled属性で非活性)</option>
      <option value='8'>島袋</option>
    </optgroup>

  </select>
</div>

<!-- ############ javascript  ############ -->
<script type="text/javascript">
$(function(){

  // マルチセレクトボックス化
  $('#optgroup').multiSelect({
    selectableOptgroup: true
    
  });

});
</script>
<!-- ############ /javascript  ############ -->


<!-- ############  style  ############ -->
<style>
.ms-container{ width:90%;}
.ms-container .ms-optgroup-label{background: #f3f3f3;}
</style>
<!-- ############  /style  ############ -->

検索を可能にするライブラリ

jQueryの検索可能ライブラリの公式のgit(https://github.com/riklomas/quicksearch)にアクセスし、「Code」ボタンをクリックし、ライブラリをダウンロードしましょう。

画像はイメージです

以下のファイルを取得し、ソースに読み込ませてください
quicksearch-master\jquery.quicksearch.js

あとはサンプルソースのbody部分を貼り付ければ、完成です。

解説

1、まずはHTMLを用意

以下の構成でHTMLを作成します。今回はグループ単位でラベルを付けた部品とします。

HTML
  <select id='optgroup' multiple='multiple'>
    <optgroup label='役員'>
      <option value='1'>佐藤</option>
      <option value='2' selected>田中(selected属性で初期選択状態)</option>
    </optgroup>
    <optgroup label='営業'>
      <option value='3'>鈴木</option>
      <option value='4'>木下</option>
      <option value='5'>下田</option>
    </optgroup>

    <optgroup label='事務'>
      <option value='6'>田上</option>
      <option value='7' disabled>上島(disabled属性で非活性)</option>
      <option value='8'>島袋</option>
    </optgroup>

  </select>

各optionタグの前にoptgroupタグを置いていきます。

optionタグにselected属性を付けると初期状態で選択されている状態になります。optionタグにdisabled属性を付けると非活性となり、選択が不可になります。

2、JavaScriptを作成

検索が不要な場合は以下だけです!

JavaScript
  // マルチセレクトボックス化
  $('#optgroup').multiSelect({
    selectableOptgroup: true    
  });

検索もできるようにしたい場合は以下となります。

JavaScript
  // マルチセレクトボックス化
  $('#optgroup').multiSelect({
    selectableOptgroup: true,
    selectableHeader: "<input type='text' class='search-input form-control mb-2' autocomplete='off' placeholder='部分一致検索できます'><div>選択候補</div>",
    selectionHeader: "<input type='text' class='search-input  form-control mb-2' autocomplete='off' placeholder='部分一致検索できます'><div>選択済み</div>",
    afterInit: function(ms){
      var that = this,
          $selectableSearch = that.$selectableUl.prev(),
          $selectionSearch = that.$selectionUl.prev(),
          selectableSearchString = '#'+that.$container.attr('id')+' .ms-elem-selectable:not(.ms-selected)',
          selectionSearchString = '#'+that.$container.attr('id')+' .ms-elem-selection.ms-selected';

      that.qs1 = $selectableSearch.quicksearch(selectableSearchString)
      .on('keydown', function(e){
        if (e.which === 40){
          that.$selectableUl.focus();
          return false;
        }
      });

      that.qs2 = $selectionSearch.quicksearch(selectionSearchString)
      .on('keydown', function(e){
        if (e.which == 40){
          that.$selectionUl.focus();
          return false;
        }
      });
    },
    afterSelect: function(){
      this.qs1.cache();
      this.qs2.cache();
    },
    afterDeselect: function(){
      this.qs1.cache();
      this.qs2.cache();
    }
    
  });

3、CSSで微調整

デフォルトだとグループラベルのデザインが寂しいので少し調整しています。

css
.ms-container .ms-optgroup-label{background: #f3f3f3;}

ほかにもールバック関数や全選択や全選択解除などの機能もありますので、今後ご紹介出来たらしてきたいと思います!


よかったら、SNSでシェアして頂けると嬉しいです!
今後の励みにもなりますので、よろしくお願いします!