次のような表示になる Bootstrap3 対応の select2 を導入する手順です

1. webpacker gem を Gemfile に追加して bundle install します
$ bundle add webpacker
エディタで Gemfile に追加してもよいです。
rails new したときに --webpack オプションがあれば、すでに入っています。
2. webpacker 関連ファイルをごっそりインストールします
$ rails webpacker:install
webpacker 2 系で生成した謎の設定ファイルや項目が webpacker 3系でほとんどなくなっていたりするので、更新する場合はここで大量の差分がでるかもしれません。なのでよくわからなくなった場合は、いったん config 下の webpacker 関連を消して webpacker 3 系で綺麗に入れなおすのがおすすめです。
3. yarn で必要なライブラリをインストールします
$ yarn add jquery
$ yarn add select2
$ yarn add select2-bootstrap-theme
yarn add のあとにパッケージ名を並べて実行してもよいです
4. jQuery はどこからでも $ で参照できるようにしておく
config/webpack/environment.js
const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
environment.plugins.set(
'Provide',
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery",
"window.$": "jquery",
})
)
module.exports = environment
参考
- Rails5.1 + Webpacker で Bootstrap4-beta を読み込む https://qiita.com/mokuo/items/6d792986e63598370b30
- Webpack Plugins https://github.com/rails/webpacker/blob/master/docs/webpack.md#plugins
webpacker 2 のときの plugin の設定場所が、 webpacker 3 になって消えていたので困っていましたが、こうやればよかったんですね。
5. bootstrap と select2 を読み込んで設定します
app/javascript/packs/application.js
// bootstrap 本体
require("bootstrap/dist/css/bootstrap")
require("bootstrap/dist/css/bootstrap-theme")
// select2 の CSS
require("select2/dist/css/select2") // select2 本体のCSSの読み込み
require("select2-bootstrap-theme/dist/select2-bootstrap") // select2 用の bootstrap テーマの読み込み
// select2 の JS
import Select2 from "select2"
// エラーメッセージの日本語化
require("select2/dist/js/i18n/ja")
// グローバルなオプションの指定
$.fn.select2.defaults.set("allowClear", true) // 空にできるようにする
$.fn.select2.defaults.set("placeholder", "") // allowClear だけだとエラーになるため
$.fn.select2.defaults.set("width", "100%") // tdタグの中に入れたときにだんだん大きくなっていくのを防ぐ
$.fn.select2.defaults.set("theme", "bootstrap") // テーマの指定
// 実行
document.addEventListener("DOMContentLoaded", () => {
$(".js-searchable").select2()
})
css をどこで読み込めばいいのかずっとわからなくて、sprokects の方で読み込んだりしていましたが、なんと js の中でそのまま読み込めばよかったんですね(?)
6. webpacker で管理している方のを読み込む
app/views/layouts/application.html.slim
/ head タグの中に追加
/ application.js で読み込んだ css と js がここで分離、変換、結合されている
= javascript_pack_tag "application"
= stylesheet_pack_tag "application"
sprokects (app/assets の方で管理しているの) と共存できます
7. ビューはこんな感じで js-searchable クラスを指定します
(view)
= form_with do |form|
= form.collection_select(:key, ['foo', 'bar', 'baz'].inject({}) { |a, e| a.merge(e => e) }, :last, :first, {include_blank: false}, {class: ['form-control', 'js-searchable']})
以上です。
試行錯誤しているところもあるので、おかしいところがあったら教えてください。