コード例

モーダル

ウェブUIでよく見かけるモーダルですが、Hotwireで実装したというブログ記事はよく見かけます。そして多くの場合は「JavaScriptをほとんど使わないでできた!」っていうことを誇っています。

しかしモーダルってそんな簡単なものでしょうか?私はそう思いません。 Hotwireを使えば、画面にモーダルを表示するのは簡単です。しかしそのようなUIは本当に価値があるでしょうか?普通に画面遷移するのと比較して、良いUI/UXを提供しているでしょうか?私はそう思いません。細かい動作からアクセシビリティまでをJavaScriptなしで実装するのは無理だからです。

ここではモーダルUIの難しさをしっかり見つめて、ちゃんとしたモーダルをHotwireで作る方法を考えたいと思います。またHotwireでできる最高のものを紹介したのちに、トーンダウンした簡単なものの作り方を紹介します。

なお、ここでお見せするものは、私が普段作成するモーダルよりも随分と柔軟性が高いものです。通常はもっと簡単に実装します。いざとなったときでも対応できる最終兵器ぐらいに考えていただければと思います。

またHTMLネイティブのdialogもありますが、これは別途議論が必要だと思います(話は単純ではないです)

また多少脱線しますが、そもそもモーダルが本当に必要かどうかもこの機会に再考していただければと思います。これについては、個人的な意見ですが、別途議論しました

デモはここからご覧いただけます

モーダルで実装する上で、以下のことを検討しておくべきかと思います。簡易的なモーダルの作り方だと、この一部は対応できますが、すべてには対応できません。

  • サーバから非同期でデータ(HTML)を取得する必要があるか?:
    • サーバ通信をすると、レスポンス遅延が発生します。レスポンスが得られる前に、ユーザに的確にフィードバックします(pending UI)
  • キーボードショートカットを含め、 モーダルダイアログに期待されるアクセシビリティ要件はかなり多い。視覚障害のある人だけでなく、健常人から期待されるごく一般的なものを含めて実装するかどうか?
  • モーダルの中でCRUDをするか?:
    • CRUDがあり、かつサーバサイドバリデーションのフィードバックをする場合は動作が複雑になります
    • サーババリデーションをフィードバックする際、成功失敗によって動作を変えます
      • 例えば成功した場合の動作として、自動的にモーダルを閉じて、背景画面も更新します
      • 一方で失敗した場合はモーダルを開いたままにし、エラーを表示します
    • 成功した時に自動的にモーダルを閉じる例を挙げましたが、一方で開いたままにするケースもあります
    • CreateやUpdateが成功したのちに、別のページにリダイレクトするかもしれしれません。あるいは背景のページを更新するだけかもしれません

今回の設計のポイント

モーダルは複数のアクションがあり、条件によって処理が分岐しますので、しっかり作ろうと思う場合は比較的複雑なUIになります。Hotwireを使えばコードの量は少なく済みますが、考えること自体を省略できるわけではありませんので、一つ一つ解説します。

モーダルダイアログでCRUDをする場合は、検討すべき項目が多いので、分割して紹介します。

  1. モーダルの表示・非表示
    1. モーダルのDOMをどこに配置するか
    2. モーダルをクリックするボタンとの距離の課題の解決
    3. 表示内容をサーバから取得するところ
    4. レスポンス遅延の対応
    5. モーダルをクローズする処理
  2. フォームを送信してモーダルを隠す
    1. フォームの送信
    2. 変更されたデータを使って背景にある画面を更新
    3. トーストの表示
    4. 成功した場合は自動的にモーダルを閉じる
    5. 失敗した場合はモーダルを表示したままにして、エラーを表示する
  3. より簡単なモーダルの作り方

詳細はリンク先のページをご確認ください

まとめ

シンプルに作るのであればモーダルダイアログは簡単です。しかしそのような簡易的なモーダルのUI/UXは十分とは言えません。「私はUI/UXにはこだわっていないので平気」とお考えかもしれませんが、もしこだわっていないのであれば、そもそもモーダルの必要があったのかどうかを再考すると良いと思います。MPA的に画面遷移をする方が実装は簡単ですし、UI/UXや今後の拡張性の面でもプラスなことが多いです

とはいえ、このサイトではHotwireで優れたUI/UXが作成できることを紹介していますので、例え何ページにわたったとしても、十分な機能を持ったモーダルの作り方を紹介します。その場合は下図の下半分の青色のTurboのところ、および一番下の緑色のStimulusで補完す るTurbo前後の2箇所をすべて行う感じになります。

なお、より単純化したケースの考え方については別途解説します。要件が限定できれば、単純化したものでも十分です。むしろモーダルを使うのをやめるか、要件を明確に限定してくださいという私の切実な願いです。

interactive-flow-hotwire.webp