株式会社HRBrain
🗓️

【DateRangePicker】インターン生が挑んだバリデーション設計のトレードオフ

に公開

この記事は、HRBrain Advent Calendar 2025-17日目の記事です!

https://adventar.org/calendars/12091

0. はじめに:DateRangePickerが私に突きつけた問い

こんにちは!インターン生のyutakabaです。

最近、実務で DateRangePicker(日付範囲選択インプット)のコンポーネントを実装する機会がありました。最初は「よし、バリデーションもサクッと組んでしまおう!」と思っていたのですが、そこでピタッと手が止まってしまいました。

「…あれ、これ、バリデーションの発火タイミングって、何を正解にすればいいんだ?」

通常のテキストインプットなら、onBlur(フォーカスが外れた時)か onChange(値が変わった時)に、形式や必須チェックをすれば大体OKです。しかし、この DateRangePicker は厄介でした。

なぜなら、期間は 「開始日」と「終了日」という 2 つの値で、初めて 1 つの期間(意味)を成するから です。
つまり、ユーザーの操作によって、「入力途中(片方だけ入力)」や 「修正中(片方削除)」 といった、曖昧な中間状態が爆発的に増えるのです。

  • 「開始日だけ入れて、他のフィールドに移った…これはエラー?」
  • 「終了日をカレンダーで選んだら、開始日より過去の日付だった!エラー?」
  • 「一回入力したけど、修正のために片方だけ消した。これもエラー?」

このように、ユーザーの「入力の意図」 と UI の「未完成な状態」 が複雑に絡み合うからこそ、いつ、どんなフィードバック(エラー)を出すのが、ユーザー体験(UX)として最適なのか、という問いが立ち上がりました。

もしタイミングを間違えれば、ユーザーの集中力を削いだり、「このフォーム壊れてる?」と誤解を与えたり、アクセシビリティ(A11y) の観点からも不親切になります。

また、『Webアプリケーションアクセシビリティ――今日から始める現場の改善』ではエラーの頻度がユーザーの集中力を削ぐことにつながると書かれています。

エラーの発生頻度によってはユーザーの集中を削いでしまいます。極端な例では1文字目を入力したときにエラーを通知してしまい、ユーザーが入力を中断するきっかけになってしまいます。
伊原 力也、小林 大輔、桝田 貴、山本 怜 他. 『Webアプリケーションアクセシビリティ――今日から始める現場の改善』. 技術評論社, 2019年, p.253(電子書籍版)

本記事は、私がこの課題に挑み、「正解のない」トレードオフの決断を、いかに論理的なフレームワークで言語化していったかの記録です。ぜひ、温かい目で見ていただけると嬉しいです!

1. 大前提:バリデーションは「入力確定後」に介入する

すごく大事だけど忘れがちな大前提として、
バリデーションは「常に入力を監視する仕組み」ではなく、入力が確定したと判断できたときに、その結果が理想状態から外れていないかを評価するための仕組みだと考えています。

また、入力途中でエラーを出すことはアンチパターンとして挙げられます。
Luke Wroblewski氏によって2008年に出版された、Webフォームのデザインに特化したUX(とユーザビリティに関する決定版とされる書籍では以下のように述べられています。

A much better approach is to only provide feedback when it’s clear someone is done providing an answer.
Luke Wroblewski,"WEB FORM DESIGN: FILLING IN THE BLANKS (ENGLISH EDITION)"2008年,p.198

意訳:「遥かに良いアプローチは、誰かが回答を終えたことが明確になったときにのみフィードバックを提供することです」

フォームにおいてエラーメッセージは、ユーザーにとって、ストレスだし、作業の中断(フローの阻害) にもなるし、最終的には 修正負担 に繋がります。

2. じゃあ入力途中か確定かってどう見極める?

前章で、バリデーションは「入力が確定したタイミングで評価するのが理想」と整理しました。
でも、実務でこの理想を考えたとき、すぐに立ちはだかる疑問があります。

「そもそも、ユーザーが入力を終えたかどうか、どうやって判断すればいいんだろう?」

テキスト入力のように単純なケースなら onBlurEnter でほぼ確定とみなせます。
でも、ちょっと複雑な入力になると、これが途端に曖昧になります。

  • まだ入力途中なのか
  • 一旦入力を終えたのか
  • 修正のために値を消しただけなのか

見た目の状態だけでは、絶対に判断できません。
どれだけ考えても、結局は憶測です。
つまり、「入力確定かどうか」を判定するのは本質的に難しいという問題に直面したのです。

3. なぜ DateRangePicker は特に難しいのか

さて、ここで具体例として DateRangePicker を振り返ります。
このコンポーネントは「開始日」と「終了日」の 2 つの値で 1 つの期間を構成しています。

  • 開始日だけ入力している状態
  • 終了日だけ入力している状態
  • 両方入力済みだけど修正中

こうした 「入力途中の状態」が非常に多く存在します。

例えば、以下のように両方の値を入力した後に終了日の値を削除したケースだとどうでしょうか。

ユーザーは修正中である意図が極めて高いと考えられます。
もしその場合だと先程の引用に限って言うのであれば、ここではエラーを出すべきではないという判断になりそうです。
しかし、実務上は 「長いフォームの修正コスト(入力負担)を避ける」 ために、即時エラーを出さなければならないかもしれません。

ここで気づきました。
単純なテキスト入力ならほぼ決まっているタイミングでも、2つ以上の値で意味を持つ入力になると、入力途中か確定かの境界が極めて曖昧になるということです。
この構造的な複雑さこそが、DateRangePicker のバリデーション設計が難しい理由であり、特殊なケースであると言えるわけです。

4. 困難な選択を論理化したい!判断をサポートする3つの観点

「入力途中のユーザーの意図を尊重すべきか?」という問いは、突き詰めても推測にしかなりません。開発者側(私)が勝手にユーザーの心理を想像しているに過ぎないからです。

そこで私は、「理想論(UX)」と「現実論(コスト)」 の間で決断を下すための、より客観的な観点を構築する必要があると考えました。

私が矛盾を乗り越えるために採用した、3つの判断軸を紹介します。

  1. フィードバック観点(認知負荷)
    入力途中のユーザーに即時でエラーを出すと、フローが途切れてストレスになる。
    だから「入力中だと考えられる状態」では、即時フィードバックを留保する、という書籍でも紹介
    されている普遍的な判断軸です。
  2. エラー修正コスト観点(後工程の負担)
    一方で、入力を途中と見なしてエラーを留保すると、あとで修正が大変になる可能性があります。
    長いフォームや必須項目が多い場合は、「ここで早めにエラーを通知した方がユーザー負担が少ない」と判断できます。
  3. 実装的統一一貫性(開発効率)
    複雑な例外ロジックを組みすぎると、コードが煩雑になりバグの温床になりかねません。
    UXの理想を追求するにしても、どこまで許容するかは冷静に判断する必要があります。

この 3 つの観点で、私は 「いつ、何を優先するか」 という決断を、論理的に、かつ責任を持って下せるようになりました。

5. DateRangePicker の最終対応例

ここで紹介するのは、最適解の提示ではなく、私がさきほど整理した観点1~3を用いて、どのように判断したかの実演例です。

今回のDateRangePickerにおける前提条件

今回扱った DateRangePicker には、以下の前提条件がありました。

  • 公的な申請フォームで、入力項目数が非常に多い
  • DateRangePicker は必須/任意両方あり(実装的制約)
  • 2つのインプットで構成(実装的制約)
  • 開始日・終了日はテキスト入力+カレンダー選択の併用型(実装的制約)

つまり本件は、
「Submit 時にエラーが出ると、ユーザーの修正コストが非常に高い」
という文脈を持ったフォームでした。

例1: 開始日のみ入力された状態をどう扱うか

image.png

状態(観測可能な操作) 評価イベント 観点1:フィードバック(認知負荷) 観点2:エラー修正コスト(入力負担) 観点3:実装的統一一貫性(開発効率) 総合評価
開始日選択後(カレンダー内) onChange 高い(選択の度に警告が出るため煩わしい) 常に高い(入力途中で遮られるストレス) 抑制可能(onChange内の分岐で制御が必要) 評価しない
開始日のみ入力済み onBlur 許容可能(入力を終えたタイミングのため自然) 高い(早期検知により、後の手戻りを防げる) 統一しやすい(項目ごとの独立性が高い) 評価する
送信ボタン押下時 Submit 許容(最終確認としての位置づけ) 最終防衛線(エラーが多いと再入力の手間が最大化) 全項目一括(最もシンプルに統一可能) 評価する

入力途中なのかそれとも確定したのか、というユーザーの操作意図の推測に頼らず、3つの観点で考えてみました。
その結果以下のの決断をしました。

  • 開始日選択直後 → 評価しない
    • (入力途中でのエラー表示はアンチパターン) + 認知負荷の抑制を優先
  • 開始日のみ入力されたままフォーカスが外れた時 → 評価する
    • 入力項目が多いため、エラー修正コストの抑制を優先

例2: 両方入力後に終了日だけ削除した状態をどう扱うか

開始日と終了日の両方が入力済みの状態から、終了日だけ削除されたケースを考えます。この状態は一見「不正な期間」としてエラー判定できそうですが、経験則だとユーザーは修正中の可能性が非常に高いです。

状態(観測可能な操作) 評価を行うイベント 観点1:フィードバック(認知負荷) 観点2:エラー修正コスト(入力負担) 観点3:実装的統一一貫性(開発効率) バリデーション評価
終了日削除後 onChange onChangeで評価:許容可能 高い:早期検知が重要 統一しやすい 評価する
送信(Submit) Submit Submitで評価:許容 最終防衛線 全項目統一 評価する

このケースでは、ユーザーの操作意図を尊重しつつ、修正コストが高い状況では早期にエラーを通知するという判断をしました。

このように考えると、当たり前のようにも感じますが、判断軸から論理的に決定ができたかどうかが非常に大事だと考えています。

6. まとめ:私が辿り着いたバリデーション設計の「哲学」

「DateRangePickerのバリデーションの評価タイミングって、何を正解にすればいいんだ?」
この素朴な問いから始まった私の考察は、単なる実装の議論ではなく、設計者の価値観と哲学に関するものとなりました。

DateRangePickerは、「開始日と終了日のペアで一つの意味」という性質上、「入力完了」 と 「入力途中」 の境界線が極めて曖昧です。
この曖昧さこそが、バリデーション設計における理想と現実の衝突を浮き彫りにしました。

結論:正解ではなく「判断のフレームワーク」

この困難なトレードオフを乗り越えるために必要だったのは、以下の 5 つの階層的な観点に基づく、論理的な判断プロセスでした。

観点 役割 定義
フィードバック観点(認知負荷) 認知負荷を避け、留保すべきか? ユーザーに即時フィードバックを返すか、あえて遅らせて負担を軽減すべきかを判断する視点
エラー修正コスト観点(後工程の負担) 留保することで、後で高い負担を負わせないか? エラー検出タイミングを遅らせた場合、後工程で修正コストが増大しないかを評価する視点
実装的統一一貫性(開発効率 理想のUXのために、開発コストを犠牲にするか? UXの理想形を優先するために、実装負荷増大を許容するかどうかを判断する視点

バリデーション設計に普遍的な正解を見つけるのは難しいと感じました。
最終的なバリデーション評価は、このフレームワークを通して認知負荷と修正コストのどちらを優先するのかを明確に言語化し、実装的統一一貫性をどこまで犠牲にできるかというトレードオフの決断を下すプロセスだと考えています。

これまでは「なんとなくこれが親切だろう」という感覚でUIを設計していましたが、今回のDateRangePickerの経験を通じて、その背景にある論理的な軸と、実務での複雑な制約を知ることができました。
今後は、なぜそのUXを選択したのかを自信を持って説明できるエンジニアを目指します。

最後までお読みいただき、ありがとうございました!

引用文献・参考資料

株式会社HRBrain
株式会社HRBrain

Discussion