Select2で作ったセレクトボックスで選択肢がない場合に「No results found」が出ないようにしてみる

- 環境
    - OS : macOS Mojave バージョン10.14.1
    - ブラウザ : Chrome バージョン: 70.0.3538.102（Official Build） （64 ビット）
    - jQuery : 3.3.1
    - Slect2 : 4.0.6

[Select2でマルチ選択できるセレクトボックスを作ってみました](https://qiita.com/ponsuke0531/items/9e71690caadc246e8f58)

# 選択肢がない場合に「No results found」が出ます
![manage.gif](https://qiita-image-store.s3.amazonaws.com/0/159761/085173f3-62f8-aff0-6fd6-244afcc81298.gif)


```html:mySelect2.html
<!DOCTYPE html>
<html>
<head>
    <!-- jQueryの読み込み -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <!-- Select2の読み込み -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
    <script type="text/javascript" src="js/mySelect2.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
    <title>Select2で作ったセレクトボックスで選択肢がない場合に「No results found」が出ないようにしてみる</title>
</head>
<body>
    <!-- Select2で作るセレクトボックス -->
    <select class="pillbox" multiple="multiple"></select>
    <select class="single-select-boxes" name="state"></select>
</body>
</html>
```
```js:mySelect2.js
/**
 * セレクトボックスの中身.
 * @type {Object}
 */
var nothing = {
    // セレクトボックスの選択肢はDB何かから取ってくることが多いと思います
    // でも、うっかりレコードがなかったりするかもしれません。
    // 日本人なので「No results found」と表示されるとがーーーんって思うかもしれません。
};

/**
 * DOM要素が読み込まれてからSelect2でセレクトボックスを作るため$(document).ready()で実行する.
 */
$(document).ready(function() {
    // マルチ選択できるセレクトボックスを作る
    let multi = $('.pillbox');
    createSelectBox(multi, nothing);
    // シングル選択できるセレクトボックスを作る
    let single = $('.single-select-boxes');
    createSelectBox(single, nothing);
});

/**
 * Select2でセレクトボックスを作る.
 * @param  {Object} selectObj セレクトボックスのjQueryオブジェクト.
 * @param  {array} arrayObj   セレクトボックスの選択肢に設定する配列.
 */
function createSelectBox(selectObj, arrayObj) {
    let options = createOptions(arrayObj);
    // セレクトボックスの中身を設定する.
    selectObj.append(options);
    // セレクトボックスの幅を設定する.
    selectObj.width(200);
    // Select2でセレクトボックスをつくる.
    selectObj.select2();
}

/**
 * 配列からセレクトボックスのoption要素を作成する.
 * @param  {array} arrayObj   セレクトボックスの選択肢に設定する配列.
 */
function createOptions(arrayObj) {
    return $.map(arrayObj, function(text, value) {
        let option = $('<option>', {value: value, text: text});
        return option;
    });
}
```

# CSSでなんとかする
[javascript - Disable &quot;No matches found&quot; text and autocomplete on select2 - Stack Overflow](https://stackoverflow.com/questions/18470917/disable-no-matches-found-text-and-autocomplete-on-select2)

開発ツールで選択肢の`<li>`タグのclass属性を見ると選択肢がなくて「No results found」がでると **select2-results__message** というclassがくっついている。
なのでこれを表示しないようにする。

```html
<!-- 選択肢がある場合 -->
<li class="select2-results__option" id=....>さる</li>

<!-- 選択肢がない「No results found」の場合 -->
<li role="treeitem" aria-live="assertive" class="select2-results__option select2-results__message">No results found</li>
```

## 結果
![manage.gif](https://qiita-image-store.s3.amazonaws.com/0/159761/912cab90-dbc9-cccb-086a-123512fb9c47.gif)

### 変えた部分のコード

```html:mySelect.html
<!-- 省略 -->
    <!-- 自作スタイルシートの読み込み -->
    <link rel="stylesheet" href="css/mySelect2.css">
    <title>Select2で作ったセレクトボックスで選択肢がない場合に「No results found」が出ないようにしてみる</title>
</head>
<!-- 省略 -->
```
```css:mySelect2.css
.select2-results__message {
    display: none !important;
}
```


# JavaScriptでなんとかする
- [select の操作について - ロックとチュウーハイとこりんがるな日々](http://box406.hatenablog.com/entry/2012/12/19/225602)
- [要素の存在チェックまとめ: 小粋空間](http://www.koikikukan.com/archives/2012/04/18-022222.php)

「No results found」の代わりに「選択肢はありません」という選択肢を作る。「選択肢はありません」のところを空文字にするのもあり。
## 結果
![manage.gif](https://qiita-image-store.s3.amazonaws.com/0/159761/b74458bd-5d6a-df6e-db45-18580abc4828.gif)

### 変えた部分のコード

```js:mySelect2.js
/**
 * 配列からセレクトボックスのoption要素を作成する.
 * @param  {array} arrayObj   セレクトボックスの選択肢に設定する配列.
 */
function createOptions(arrayObj) {
    if (arrayObj && arrayObj.length > 0) {
        return $.map(arrayObj, function(text, value) {
            let option = $('<option>', {value: value, text: text});
            return option;
        });
    }
    // 選択肢がない場合の処理.
    return cleateCanNotSelectOption();
}

/**
 * 選択できない選択肢を追加する.
 */
function cleateCanNotSelectOption() {
    // 「選択肢はありません」を選択肢にする.
    let option = $('<option>', {value: 'non', text: '選択肢はありません'});
    // 選択できないようにする.
    option.attr("disabled", "disabled");
    return option;
}
```



# Select2のオプションでなんとかする
> Message translations
When necessary, Select2 displays certain messages to the user. For example, a message will appear when no search results were found or more characters need to be entered in order for a search to be made. These messages have been translated into many languages by contributors to Select2, but you can also provide your own translations.
> [Internationalization | Select2 - The jQuery replacement for select boxes](https://select2.org/i18n#message-translations)

「No results found」の代わりに「選択肢はありません」という選択肢を作る。「選択肢はありません」のところを空文字にするのもあり。

## 結果
![manage.gif](https://qiita-image-store.s3.amazonaws.com/0/159761/59af451c-f39f-a0bf-e52a-066b1446454c.gif)

### 変えた部分のコード

```js:mySelect2.js
function createSelectBox(selectObj, arrayObj) {
    // <省略>
    selectObj.select2(
        {
            language: {"noResults": function(){ return "選択肢はありません";}}
        }
    );
}
```