Skip to content

Unsaved changes

Losing a half-filled form is the top complaint class in business apps. data-hc-dirty-guard (the auto-installed installDirtyGuard()) makes a form honest about its edit state: data-dirty appears on the first real change, the tab refuses to close silently, boosted navigation asks first, and a successful save resets the baseline. Client-only — the save keeps whatever contract the form already follows. Covered by the versioning policy.

Also known as: dirty check, leave confirmation, beforeunload guard.

The preview is live: edit the title and the badge appears (a plain form[data-dirty] CSS hook); revert the exact text and it disappears. Closing the tab while dirty would prompt — the demo form has no server, so Save here is inert.

Unsaved changes

Moment Effect
first focus in the form baseline snapshot (via new FormData(form) — installFormat’s canonical values, so display regrouping is never “dirty”)
any input / change compare → toggle data-dirty, dispatch hc:dirtychange { dirty } on flips
tab close / reload while dirty the browser’s generic prompt (custom strings are ignored by modern browsers)
boosted <a> navigation while dirty window.confirm with the dirtyguard.leave message (localize via setMessages())
the form’s own request succeeds re-snapshot → clean
a request from inside the form but not by it not clean — the autosave draft stays a draft
native submit never prompts (submit fires only after constraint validation passes)

data-dirty is a plain attribute — style it in app CSS:

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

A server may also render data-dirty (a restored draft is unsaved by definition) — the guard warns from the attribute alone.

Without JavaScript nothing guards and nothing breaks: the form submits natively. Pure enhancement by construction.

  • The tab-close prompt is the browser’s own dialog.
  • Mirror the state into an aria-live status line via hc:dirtychange when a visual badge alone is not enough.
  • autosave — make the warning mostly moot by drafting as the user types.
  • mutating-form — the save contract the guarded form usually follows.