概要
Choices.jsを使ってセレクトボックスを作成しました
はじめに
現在、フィヨルドブートキャンプでチーム開発をしています。
Choices.jsというライブラリを使って、セレクトボックスを作成しましたが、情報が少なかったのでQiitaに記事として残しておきます。
初学者向けの内容となっています。
Choices.jsについて
軽量な選択ボックス/テキスト入力プラグインです。リッチなセレクトボックスが作れます→DEMO
Select2およびSelectizeに似ていますが、jQueryの依存関係はありません。
2年ほどリリースが止まっていたようですが、2021年の12月より再びメンテナンスされているようです。
インストール
- npm
npm install choices.js
- yarn
yarn add choices.js
- stylesheet
導入したらしっかりstylesheetで読み込みましょう。
自分はこれを忘れて無駄な時間を過ごしてしまいました😅(忘れるのは初学者の自分だけだと思います)
CDNは以下、その他ディレクトリで読み込むものなど多数あります(README参照)
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/choices.js@9.0.1/public/assets/styles/choices.min.css"/>
用語
専門用語というほどではないんですが、ここを読み解かないとうまく使いこなせませんでした。
ほとんどREADMEを翻訳したものだけど載せておきます。
(今回はセレクトボックスを作るので、テキストボックスとしての使い方は割愛)
用語 | 説明 |
---|---|
Choice | ユーザーが実際に選択できる値で、<option> 要素と同等 |
Group | 選択肢の集まりでその名の通りグループ。<optgroup> 要素と同等 |
Item | 選択された要素の<option value = "item"> 要素と同等 |
HTMLでのセレクトボックスはというと
<select name="spice">
<option value="">スパイスを選択</option>
<option value="garammasala">ガラムマサラ</option>
<option value="coriander">コリアンダー</option>
<option value="cumin">クミン</option>
</select>
となっているのでChoiceは<option>
のこと、Itemは<option>
のvalue
だとわかります。
ということでChoices.jsを使って、もっとも簡単だと思われるコードを書いてみました
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Spice select</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/choices.js@9.0.1/public/assets/styles/choices.min.css"
/>
<script src="https://cdn.jsdelivr.net/npm/choices.js@9.0.1/public/assets/scripts/choices.min.js"></script>
</head>
<body>
<select name="spice" id="hoge">
<option value="">スパイスを選択</option>
<option value="garammasala">ガラムマサラ</option>
<option value="coriander">コリアンダー</option>
<option value="cumin">クミン</option>
</select>
<script>
document.addEventListener("DOMContentLoaded", () => {
new Choices("#hoge")
})
</script>
</body>
</html>
セレクトボックスにhoge
というidを振って、Choicesオブジェクトを作る際に紐づけるだけです。
これでインクリメンタルサーチが簡単に使えるし、上の通りvalue属性でもヒットします。
選択肢が多くなったときに便利ですね。
開発者ツールを見てみるとclass="choices"
やdata-type="select-one"
などのタグが使われています。
<select>
はselect-one、<select multiple>
とselect-multipleとなっていて、
オプションが反映できるか否かは、この入力タイプを確認するとわかりやすいと思います。
Railsでの使い方
再び簡単な復習になるんですが、既にSpiceモデルがあるとして、selectを使うと
select(:spice, :name, Spice.pluck(:name, :id), { include_blank: "スパイスを選択" })
collection_select(:spice, :name, Spice.all, :id, :name, prompt: "スパイスを選択")
これをHTMLで出力すると、いずれも
<select name="spice[name]" id="spice_name">
<option value="">スパイスを選択</option>
<option value="1">ガラムマサラ</option>
<option value="2">コリアンダー</option>
<option value="3">クミン</option>
</select>
のようになります。
こちらもこのセレクトボックスにidさえ付与すれば、Choices.jsが使用可能です。
ここからは実際に自分がチーム開発で実装したコードに、一部修正を加えたものを記載していきます。
環境とgem
- ruby 3.1.0
- Rails 6.1.4.4
- webpacker 5.4.3
- Choices.js
- slim-rails
UserモデルとSpiceモデルが存在し、UserはSpice(好みのスパイス)を1つ持つような関係です。
CSSに関してはnode_modulesから読み込むように設定しています。
view
= f.label :spice, class: 'a-form-label'
= f.collection_select :spice_id, all_spices_with_empty, :id, :name, {}, { id: 'js-spice-select' }
フォーム内でのセレクトボックスです。
セレクトボックスにjs-spice-select
というidを付与しています。
all_spices_with_empty
は選択肢なしを含めた配列です。
def all_spices_with_empty
Spice.all.to_a.unshift(Spice.new(name: '好みのスパイスなし'))
end
javascript
import '../spice-select.js'
JavaScriptファイルをWebpacker経由で読み込んでいます。
import Choices from 'choices.js'
document.addEventListener('DOMContentLoaded', () => {
const element = document.getElementById('js-spice-select')
if (element) {
return new Choices(element, {
removeItemButton: true,
allowHTML: true,
searchResultLimit: 10,
searchPlaceholderValue: '検索ワード',
noResultsText: '一致する情報は見つかりません',
itemSelectText: '選択'
})
}
})
以上のように、少しだけオプションをつけてみます。
allowHTML
オプションをつけないと、以下のようなwarningが出ます。
Deprecation warning: allowHTML will default to false in a future release.
To render HTML in Choices, you will need to set it to true.
Setting allowHTML will suppress this message.
また、Choices.js関連の要素がなければ、下記のコンソールエラーが出てしまうのでif文を使っています。
Uncaught TypeError: Expected one of the following types text|select-one|select-multiple
と、ここまで作り終えたところで
Choices.jsを使ったセレクトボックスが完成しました🎉
これがRailsでChoices.jsを使う初歩的な方法だと思います。
他にも選択肢を他からfetchして作成したり、複数の選択肢を選んだり、タグをつけたり、、、
などなどカスタマイズが可能なので、少しリッチなセレクトボックスを作成するのにいかがでしょうか?
最後に
最後までご覧いただきありがとうございました。本記事がどなたかのご参考になれば幸いです。
何かご意見やご感想などありましたら、お気軽にコメントや編集リクエストをお待ちしております🙏
参考文献
執筆にあたり、以下の記事を参考とさせていただきました。ありがとうございました🙇♂️