LoginSignup
7
2

More than 1 year has passed since last update.

Select2の代替にTom Selectを使ってみる

Last updated at Posted at 2022-10-03

概要

インクリメンタルでドロップダウンの選択肢を絞り込めるselect2-railsのgemはとても便利なんだけど、jQueryに依存しているので、Rails 7 + StimulusなどのjQueryを使わないモダンな環境では使用をためらってしまうかと思います。

スクリーンショット 2022-10-03 19.15.27.png

Select2の代わりに使えるTom SelectがSelect2同様に簡単で便利だったので紹介します。

環境

  • Rails 7.0.3
  • stimulus-rails
  • jsbundling-rails(importmap-railsでもいけるはず)
  • Bootstrap 5(なくてもいけます)

コマンド

1. yarnでライブラリをTom Selectを追加する

これでTom SelectのJavaScriptがコンパイルされるようになります。

yarn add tom-select

2. Tom SelectのCSSをインポートする

これをやらないとスタイルが適用されず、崩れたドロップダウンが2つ表示される感じになります。公式ドキュメントでは見つけにくくて、はまりました。

プロジェクトでBootstrapを使っている場合は、以下のようになります。

app/assets/stylesheets/application.scss
@import "tom-select/dist/css/tom-select.bootstrap5";

Bootstrapを使っていない場合は、以下のようになります。

app/assets/stylesheets/application.scss
@import 'tom-select/dist/css/tom-select';

3. JavaScriptをインポートする

まず、Stimulusのコントローラーを作成します。

bin/rails g stimulus SelectController

作成されたファイルで、TomSelectをimportして使います。

app/javascript/controllers/select_controller.js
import { Controller } from "@hotwired/stimulus"
import TomSelect from "tom-select"

// Connects to data-controller="select"
export default class extends Controller {
  connect() {
    // 初期化処理を書く
    const config = {};
    new TomSelect(this.element, config);
  }
}

以下の記述はimportmap-railsでは不要です。jsbundling-railsでは自動で追加されます。

app/javascript/controllers/index.js
import { application } from "./application"
...
import SelectController from "./select_controller"
application.register("select", SelectController)

4. viewsにselectを追加する

Shopモデルにareaというプロパティーがあるとすると、こんな感じになります。

<%= bootstrap_form_with(model: @shop, url: shops_path) do |form| %>
  <div class="col-6">
    <%= form.select :area, Area.all.pluck(:name, :id), { include_blank: 'エリアを選択' }, data: { controller: "select" } %>
  </div>
<% end %>

Bootstrapなしのform_withでもいけるし、selectの代わりにcollection_selectでもいけます。

<%= form_with(model: @shop, url: shops_path) do |form| %>
  <div class="col-6">
    <%= form.collection_select :area_id, Area.all, :id, :name, { include_blank: 'エリアを選択' }, data: { controller: "select" } %>
  </div>
<% end %>

できたもの

スクリーンショット 2022-10-03 19.55.01.png

この例では、ドロップダウンの選択肢を静的に取得していますが、動的に取得する方法もあります。公式のサンプルを見てみてください!

参考

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2