[jQuery/Select2]動的なselectボックスにSelect2を適用する方法

# はじめに

公式：[Select2](https://select2.org/)

Select2ではselectボックス時に、
入力フォームも使えるようになる素敵なJSライブラリ。
挙動イメージはこんな感じ。

![image1.gif](https://qiita-image-store.s3.amazonaws.com/0/335844/e28433f0-0380-7a87-671f-8f7b51ad178b.gif)

## 検証環境

以下の環境で実施しました。

```
[client]
・MacOS Mojave(10.14.2)
・Vagrant 2.2.2
・VBoxManage 6.0.0

[virtual]
・CentOS 7.6
```

ご参考までに。

# やりたいこと

・「＋」ボタンを押した際に動的に入力フォームを増やす
・追加されたselectボックスにSelect2を適用する

**・事前準備**

jQueryとSelect2はちゃんとincludeすること。

```html:index.html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script> 
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
```

**・実装**

まず、

>・「＋」ボタンを押した際に動的に入力フォームを増やす

まずはSelect2は後にしてこの機能を作りました。

```html:index.html
<form id="sample" action="#">
  <table id="form_table" border="1">
    <thead>
    <tr>
      <td>データ１</td>
      <td>データ２</td>
      <td>データ３</td>
      <td>行削除</td>
    </tr>
    </thead>
    <tbody>
    <tr style="display: none;">
      <td>
        <select>
          <option value="">データ１</option>
          <option value="111">111</option>
          <option value="222">222</option>
          <option value="333">333</option>
          <option value="334">334</option>
        </select>
      </td>
      <td>
        <select>
          <option value="">データ２</option>
          <option value="444">444</option>
          <option value="555">555</option>
          <option value="666">666</option>
          <option value="667">667</option>
        </select>
      </td>
      <td><input type="number" value="0"></td>
      <td><button type="button" id="delete_form">×</button></td>
    </tr>
    </tbody>
  </table>
  <button type="button" id="add_form">＋</button>
</form>
```

```javascript:sample.js
$(function () {
  $("#add_form").click(function(){
    $("#form_table tbody tr:first-child").clone(true).appendTo("#form_table tbody");
    $("#form_table tbody tr:last-child").css("display", "table-row");
  });

  $("#delete_form").click(function(){
    $(this).parent().parent().remove();
  });
});
```

上記を実装すると、

![image2.gif](https://qiita-image-store.s3.amazonaws.com/0/335844/6956aa17-8e1a-2dd2-ab52-ccb579917ac6.gif)

このように動的に増やしたり減らしたりが出来ます。

で本題。

>・追加されたselectボックスにSelect2を適用する

「＋」ボタンで１行追加した際に、
追加されたselectボックスに都度Select2を適用するようにJSを修正します。

```javascript:sample.js
$("#add_form").click(function(){
  $clone = $("#form_table tbody tr:first-child").clone(true);
  $clone.find("span").remove();
  $clone.find("select").select2();
  $clone.appendTo("#form_table tbody");
  $("#form_table tbody tr:last-child").css("display", "table-row");
});
```

Select2を適用していると、自動的にspanタグが発行されるため、
cloneした際に元のspanタグをremoveしてから再度Select2を付与するようにしています。
なぜそのようにしているかの理由は

[Cloned Select2 is not responding](https://stackoverflow.com/questions/17175534/cloned-select2-is-not-responding)

のstackoverflowにも上がっていますが、動的に増やした際、
Select2がうまいこと適用されなかったためです。
(一度Select2を消し去ってから再付与する必要があるとのこと。)

Select2を実装したので確認してみましょう。

![image3.gif](https://qiita-image-store.s3.amazonaws.com/0/335844/70680d78-0808-d6d6-a692-5616badc9865.gif)

追加したもの全てにSelect2が適用されていますね。
(CSSイジってないので見た目の崩れはご了承を)

# 所感

大量に選択肢が出てくるようなselectボックスには、
ぜひSelect2を導入したいですね。

# おわりに

何かお気づきの点がありましたら、
ご指摘やアドバイス等頂けると大変助かります！