コンテンツにスキップ

未保存ガード

入力途中のフォームを失うことは、業務アプリで最も多い苦情の類型です。 data-hc-dirty-guard(自動インストールされる installDirtyGuard())は フォームを編集状態について正直にします: 最初の実変更で data-dirty が 現れ、タブは黙って閉じなくなり、boosted ナビゲーションは先に確認し、 保存が成功すればベースラインがリセットされます。クライアント専用 — 保存自体はフォームが既に従っている契約のままです。 バージョニングポリシーの 対象です。

別名: 離脱ガード、ダーティチェック、未保存警告。

プレビューは動いています: タイトルを編集するとバッジが現れます (素の form[data-dirty] CSS フック)。元の文字列に戻すと消えます。 ダーティなままタブを閉じようとすると警告されます — このデモの フォームにはサーバーがないため、Save は何もしません。

Unsaved changes

タイミング効果
フォーム内で最初のフォーカスベースラインのスナップショット(new FormData(form) 経由 — installFormat の正準値なので、表示上の再グループ化が「ダーティ」になることはありません)
任意の input / change比較 → data-dirty をトグルし、反転時に hc:dirtychange { dirty } をディスパッチ
ダーティなままタブを閉じる / リロードブラウザの汎用プロンプト(現代のブラウザはカスタム文字列を無視します)
ダーティな状態での boosted <a> ナビゲーションdirtyguard.leave メッセージでの window.confirm(setMessages() でローカライズ)
フォーム自身のリクエストが成功再スナップショット → クリーン
フォーム内発だがフォーム自身ではないリクエストクリーンになりませんautosave のドラフトはドラフトのまま
ネイティブ送信決して警告しません(submit は制約検証を通過した後にだけ発火します)

data-dirty はただの属性です — アプリの CSS でスタイルします:

.unsaved-badge { visibility: hidden; }
form[data-dirty] .unsaved-badge { visibility: visible; }

サーバーが data-dirtyレンダリングしても構いません(復元 されたドラフトは定義上未保存です) — ガードは属性だけから警告します。

プログレッシブエンハンスメント

Section titled “プログレッシブエンハンスメント”

JavaScript がなければ何も守りませんが、何も壊れません: フォームは ネイティブに送信されます。構造からして純粋なエンハンスメントです。

  • タブを閉じる際のプロンプトはブラウザ自身のダイアログです。
  • 視覚的なバッジだけで足りないときは、hc:dirtychange で状態を aria-live のステータス行に写してください。
  • autosave — 入力と 同時にドラフトを保存し、警告の出番をほぼなくします。
  • mutating-form — ガード付きフォームが通常従う保存契約。