困り果てていたこと
Railsアプリで、ユーザーが日付と時間を、決まったフォーマットで入力できるフォームが欲しい!
ただそれだけのことでした。
Railsには、datetime_field
というヘルパーメソッドがあり、Chrome、Safariなど多くのブラウザでは、カレンダーを表示して日付と時間を入力できます。
https://railsdoc.com/page/datetime_field
Chromeだとこんな具合に↓
しかし、なんと。
IEはまぁいいとして、Firefoxがこれに対応してくれていません。
同じページなのにFirefoxだと何もアシストしてくれない図↓
なぜかというとdatetime_field
はHTMLで下のinputタグを生成するのですが、Firefox(とIE)がこのtype="datetime-local"
に非対応だからです。。。
<input type="datetime-local">
URL:https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/datetime-local#browser_compatibility
BootstrapのTempus Dominusというプラグインを使うというアイディアがありましたが、「閉じる」ボタンをこさえても押せないし、日付と時間を行ったり来たりするボタンの表示がおかしかったりで、先輩方を巻き込んで取り組んでも全く解決しませんでした。
Tempus Dominus:https://getdatepicker.com/5-4/
あとは、カレンダーが出ないものも検討しました。
https://robinherbots.github.io/Inputmask/
が、最終的には@Y_uuu さんが、見つけてくれたflatpickrなるものが救ってくれました。
環境
ruby 2.7.2
Rails 6.1.3.1
実装!
flatpickrとはdatetimepickerの一種です。ドキュメントに"Lean, UX-driven, and extensible, yet it doesn’t depend on any libraries. "とある通り、めっちゃシンプルで拡張性があるのに、他のライブラリに依存していないという素晴らしいライブラリです。
基本的にはドキュメントがわかりやすいですが(ドキュメントもめっちゃシンプル!)、ところどころ大事な説明が抜けていて(たぶん)、ややハマりました。
インストール
まずはインストール。ドキュメントには、なぜかyarnでの方法は書いてなかったです。
yarnのサイトにはあったので、yarnの場合は下記コマンドで。
https://yarnpkg.com/package/flatpickr
$ yarn add flatpickr
JS
Railsアプリで、webpackなどのバンドラを使っている場合は、application.jsファイルに下記のように記述してインポートします。この辺はドキュメントでもわかりやすいです。
以下、例です。
// ライブラリをインポート
import flatpickr from "flatpickr";
// ローカライズが必要な場合のみ
import { Japanese } from "flatpickr/dist/l10n/ja.js";
// datetime
flatpickr("#hoge",{
// オプション設定を{}内に記述
enableTime: true,
dateFormat: "Y/m/d H:i",
defaultHour: 0,
minuteIncrement: 1,
// ローカライズ
locale: Japanese,
});
// dateのみだったら
flatpickr(".foo",{
dateFormat: "Y/m/d",
locale: Japanese,
});
flatpickrメソッドの第一引数は、inputタグのDOMを選択してあげればいいです。id#
選択なら単一の要素を選択し、クラス.
で指定してあげれば、該当クラスの要素全てに適用できます。
第二引数は、オブジェクトの形でオプション設定を定義します。
View
ビューでの実装は、ERBだとこんな感じになります↓
<!-- idなら一意のタグに -->
<%= f.text_field(:posted_at, id: "hoge", class: "bg-transparent") %>
<!-- classなら複数のタグに -->
<%= f.text_field(:edited_at, class: "foo bg-transparent") %>
<%= f.text_field(:replied_at, class: "foo bg-transparent") %>
CSS
CSSの設定も必要です。
なぜかドキュメントにはこれが書かれておらず、「あれ、ドキュメント通りに書いてるのにうまく行かないじゃん」状態に陥っていました!
@import "flatpickr/dist/flatpickr.min.css";
// もしくは別のスタイルテーマを入れる場合
// 例えばダークテーマ
// @import "flatpickr/dist/themes/dark.css";
それとinputタグにreadonly
が設定されるのですが、それによってフォームパーツがreadonlyなグレーアウトな色味になってしまうので、Bootstrapで背景色を指定してあげたら(class="bg-transparent")所望のスタイルになりました。
個人的に、日付と時間の数字のフォントサイズが小さいなと思ったのでCSSで調整を入れています。
テーマは他にダークやらカラーバリエーションがあって、どれもいい感じです!
Tempus Dominus君よ...
先述の通りflatpickrに出会う前は、Bootstrapのdatetime picker(日時をカレンダーでインプットできるやつ)のプラグインTempus Dominusを試していたのですが、うまくできませんでした。
日付と時間の切り替わりのボタンや、閉じるボタンx
がワークしなかったです。
もっともAdminLTEでは、Tempus Dominusでdatetimepickerが実装されていて、もちろんFirefoxでもきちんと動作しているので、私の設定が悪いんだとは思いますが、先輩エンジニア交えても解決できなかったので、なかなか難しい...という印象です。
他のライブラリ?との依存関係も複雑であると印象を持ちました。
AdminLTE:https://adminlte.io/themes/v3/pages/forms/advanced.html
ちなみに、他にこんな手段も
今回は採用しませんでしたが、jQueryのinputmaskという案も出てきました。これはカレンダーは出てこないですが、ユーザーに所定のフォーマットで日時入力できるようにアシストしてくれるやつみたいです。
最後に
今回、Tempus Dominusでハマっている僕を助けてくれて、flatpickrを見つけてくれて、実装のヘルプまで、@Y_uuu さんがしてくれました。他にも複数人の先輩が助けに入ってくれました。
自分のタスクではなく、自分が携わっているプロジェクトでもないのに、担当者よりも調べて助けてくれる先輩がいる会社...名をFusicと申します。宣伝の意図はなく、純粋な自慢です!(笑)
本記事に関して、何かご指摘などあればバシバシよろしくお願いします。