Railsでflatpickrを使ってみる


はじめに

フォームから日付を入力する際、カレンダーから直感的に日付選択できるようにする"datetimepicker"等の日付ピッカー。
その一種であるflatpickrをRailsで使う方法がQiitaに見当たらなかったので記事にしてみました。
なお、当方初学者かつ初投稿なので、間違いなどございましたらご指摘いただけますと幸いです。

環境

  • ruby 2.6.6
  • Rails 5.2.4.4

flatpickrについて

flatpickrは非常に軽量で導入も簡単です。
flatpickr以外の日付ピッカーとしてbootstrap-datetimepickerが有名ですが、bootstrapやjQueryに依存していたり、bootstrapのバージョンの互換性などなにかと面倒です。
私のような初学者でもポートフォリオへの導入がしやすいかと思います。

関連ページ

flatpickrは色々細かく設定できるようなので、上記サイトを御覧ください。

  • flatpickr-rails (github)
    Railsで簡単に使えるようgemパッケージ化してくれています。
    今回はこちらを使って導入していきます。

flatpickrインストール

今回は先程のGemを使用するので、Gemfileに以下を記述し、インストールします。

gemfile
gem 'flatpickr'
tarminal
$ bundle install

app/assets/stylesheets/application.cssの拡張子cssをscssに変更
上部にflatpickrを読み込ませる記述を追加します。

application.scss
/* 
 ...
 ...
// 〜〜〜〜 以下を追加 〜〜〜〜
 *= require flatpickr
// 〜〜〜〜 以上を追加 〜〜〜〜
 */

app/assets/javascripts/application.jsも同様に記述します。
日本語化するのであれば、一緒にflatpickr/l10n/jaも導入しましょう。

application.js
//= require rails-ujs
//= require activestorage
// 〜〜〜〜 以下を追加 〜〜〜〜
//= require flatpickr
//= require flatpickr/l10n/ja
// 〜〜〜〜 以上を追加(require turbolinksより上に追加) 〜〜〜〜
//= require turbolinks
//= require_tree 

以上でflatpickrの準備は整いました。次は、viewでフォームから実際にflatpickrを表示してみましょう。

表示してみる

今回はnewページで、Taskモデルのdate型のaction_atというカラムにデータを入れる場合を想定しましょう。
モデルやカラム名は適宜読み替えて実装してください。

viewではRailsのいつもの感じでform_withを使ってフォームを作りましょう。

views/tasks/new.html.erb
<%= form_with(model: @task, local: true) do |f| %>
  <%= f.text_field :action_at, id: "flatpickr", type: "text", readonly: "" %>
<% end %>

text_fieldにわかりやすくid: "flatpickr"と記述しました。
idの名前は何でもいいですが、次のjsに書くflatpickrの第一因数と一致させるようにしてください。
また、readonly:""でユーザーにflatpickr以外から文字入力をさせないようにしましょう。

続いてJavaScriptの設定に移ります。
新しいjsファイルを作成する場合、ファイル名をflatpickr.jsにすると//= require flatpickrと被って動かなくなるので注意しましょう。
turbolinksを使用していない場合は最初の行は必要ありません。

datetime.js
document.addEventListener('turbolinks:load', () => {
  flatpickr('#flatpickr')
})

これでフォームをクリックするとflatpickrが表示されるはずです!

カスタマイズ例

jsでのカスタマイズ例なんかは既にいろいろ記事が上がっていたり、公式サイトにも載っているのですが、少しだけ例を挙げておきます。

日本語化とスマホ対応

datetime.js
document.addEventListener('turbolinks:load', () => {
  // カレンダーの日本語化
  flatpickr.localize(flatpickr.l10ns.ja)
  // カレンダー表示
  flatpickr('#flatpickr', {
    // スマートフォンでもカレンダーに「flatpickr」を使用する設定
    disableMobile: true,
  });
})

//= require flatpickr/l10n/jaで日本語化を読み込んでいるので、これで曜日などが日本語になります。

選択可能日を設定

datetime.js
document.addEventListener('turbolinks:load', () => {
  const TODAY = new Date(new Date().setHours(0, 0, 0, 0))

  flatpickr.localize(flatpickr.l10ns.ja)
  flatpickr('#flatpickr', {
    disableMobile: true,
  //今日までを選択可能にする
    maxDate: TODAY
  });
})

今日までを選択可能にしました。minDate:とかで一ヶ月前までを選択可能にしたりもできます。

11月28日時点なら、29日、30日と来月以降の文字は選択不可になっています。

テーマ変更

application.scss
/* 
 ...
 ...
 *= require flatpickr
 *= require flatpickr/themes/dark.css
 */

flatpickrには色々なテーマが用意されており、scssに読み込ませるだけで変更できます。
公式サイト日本語約ページにサンプルがあります。
Themes

上の例はdarkテーマを採用していますが、darkのところを他のテーマ名に変えるだけで適用できます。

material_blue.css

airbnb