はじめに

jQuery Select2 で、ajax で選択肢を取得する方法方法を調べた。

TL;DR

  • ajax オプション内で設定
  • url, data オプションで API Request に関する設定
  • processResults オプションで API Response を受信した後の処理
  • templateResult, templateSelection オプションで見た目(HTML)の設定

目次

  1. はじめに
  2. TL;DR
  3. 環境・条件
  4. 詳細
    1. ミニマムコード
      1. data オプション
      2. processResults オプション
    2. カスタマイズ
      1. delay オプション
      2. url オプション
      3. cache オプション
      4. templateResult, templateSelection オプション
  5. まとめ
  6. その他・メモ
  7. 参考文献

環境・条件

  • jquery v3.4.1 (CDN)
  • select2 v4.0.12 (CDN: JS, CSS)

詳細

Ajax (remote data) | Select2 にドキュメントあるけど、正直わかりづらい。

JQuery Select2プラグインのリモート検索(インクリメンタルサーチ) - Qiita も読みつつ、手元で色々と試してようやく理解できた。

ミニマムコード

動作サンプル。

See the Pen select2 simple ajax sample by 17num (@17num) on CodePen.

HTML ファイル。CDN から読み込んで、空の select タグだけ配置。
※諸々細かい部分は省略

1
2
3
4
5
6
7
8
<head>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2@4.0.12/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.0.12/dist/js/select2.min.js"></script>
</head>
<body>
<select class="select2"></select>
</body>

JS 部分。GitHub のリポジトリ検索 APIを実行して、その結果を選択肢として表示する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$(document).ready(function() {
$("select.select2").select2({
ajax: {
url: "https://api.github.com/search/repositories",
dataType: 'json',
data: (params) => {
return {
q: params.term,
}
},
processResults: (data, params) => {
const results = data.items.map(item => {
return {
id: item.id,
text: item.full_name || item.name,
};
});
return {
results: results,
}
},
},
});
});

data オプション

data が API Request に関するオプション。params.term に検索ワード(ユーザー入力値)が入っている。上記例では {q: params.term} を返却することで、?q=xxxx というクエリパラメータが付与された API を実行している。

もし ?name=xxxx のようなクエリパラメータで API を実行したい場合は、以下のように指定すれば良い。

1
2
3
4
5
6
7
8
9
10
11
$("select.select2").select2({
ajax: {
// 略
data: (params) => {
return {
name: params.term,
}
},
// 略
},
})

processResults オプション

processResults が API Response に関するオプション。

まず、結果を表示するためのデータは下記の構造でなければならないことに注意しておく(processResults で最終的に以下のデータを返却する)。

1
2
3
4
5
6
7
8
9
10
11
12
13
{
results: [
{
id: 1,
text: 'first',
},
// 略
{
id: 9,
text: 'ninth',
},
]
}

「『id, text を持つ Object』の配列」を、キー results に対応する値とした ObjectprocessResults で返却する。

第一引数 data に API Response が格納されているため、data.items の値をもとに上記構造のデータを生成して返却している。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$(document).ready(function() {
$("select.select2").select2({
ajax: {
// 略
processResults: (data, params) => {
const results = data.items.map(item => {
return {
id: item.id,
text: item.full_name || item.name,
};
});
return {
results: results,
}
},
},
});
})

カスタマイズ

前述の内容がミニマムコードで、あとは良くあるカスタマイズについて。

使えるオプションは jQuery $.ajax options にまとまっている。

delay オプション

最終キー入力から API 実行まで、どのぐらいの間隔を空けるか。単位は msec。

1
2
3
4
5
6
7
$(document).ready(function() {
$("select.select2").select2({
ajax: {
delay: 500, // 最終キー入力から 500msec 後に API 実行
},
});
})

url オプション

/search?q=xxxx ではなく /search/xxxx のように、クエリパラメータではない形式にしたい場合などは、url に関数を指定すると良い。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$(document).ready(function() {
// ↓だと /search?q=xxxx になる
$("select.select2").select2({
ajax: {
url: "/search",
data: (params) => { return {q: params.term} },
},
});

// ↓だと /search/xxxx になる
$("select.select2").select2({
ajax: {
url: (params) => `/search/${params.term}`,
},
});
})

cache オプション

特に何も説明が書かれてないが、たぶんキャッシュが効くようになる(無駄なリクエストが減る)のだと思われる。

1
2
3
4
5
6
7
$(document).ready(function() {
$("select.select2").select2({
ajax: {
cache: true,
},
});
})

templateResult, templateSelection オプション

ajax のオプションではないが、選択肢や選択結果の見た目を変更したい場合は templateResult, templateSelection オプションを使う。

processResults で返却したデータが利用可能なので、以下のように画像パスを含めておくことで、選択肢内にサムネイルを表示するということも可能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
results: [
{
id: 1,
text: 'first',
image: '/path/to/image/1.png',
},
// 略
{
id: 9,
text: 'ninth',
image: '/path/to/image/9.png',
},
]
}

まとめ

  • ajax オプション内で設定
  • url, data オプションで API Request に関する設定
  • processResults オプションで API Response を受信した後の処理
  • templateResult, templateSelection オプションで見た目(HTML)の設定

その他・メモ

ちなみに、CDN の jQuery で最初 slim 版を使ってたら、Uncaught TypeError: o.ajax is not a function というエラーが出て動かずにどハマりした。

jQueryでajaxが使えない($.ajax is not a function) │ Web備忘録

参考文献

関連記事