Agent Wranglers

Forms Required

Never lose what people typed

Keep every value people entered after a failed submit, a lost connection, an expired session or an accidental reload. Never clear a form unless it was saved.

How to do it

After a failed submit, leave the fields as they are, or render them again with the submitted values on the server. Save a draft of long forms, with more than 5 fields or any free-text area, to sessionStorage or the server on every change. Restore it on load. Never store passwords or card numbers in a draft. Clear the draft only after the server confirms the save.

Example

const DRAFT_KEY = `draft:${location.pathname}`;
const SECRET_FIELDS = new Set(['password', 'cardNumber']);

export function keepDraft(form: HTMLFormElement) {
  const saved = JSON.parse(sessionStorage.getItem(DRAFT_KEY) ?? '{}');
  for (const [name, value] of Object.entries(saved)) {
    const field = form.elements.namedItem(name);
    const isTextField = field instanceof HTMLInputElement || field instanceof HTMLTextAreaElement || field instanceof HTMLSelectElement;
    if (isTextField && field.type !== 'file') field.value = String(value);
  }
  form.addEventListener('input', () => {
    const values = Object.fromEntries([...new FormData(form)].filter(([name, value]) => typeof value === 'string' && !SECRET_FIELDS.has(name)));
    sessionStorage.setItem(DRAFT_KEY, JSON.stringify(values));
  });
}
export const clearDraft = () => sessionStorage.removeItem(DRAFT_KEY);
@app.post("/invoices")
def create_invoice():
    try:
        invoice = InvoiceInput.model_validate(request.form.to_dict())
    except ValidationError as error:
        return render_template("invoices/new.html", values=request.form, errors=field_errors(error)), 422
    saved = invoices.create(invoice)
    return redirect(url_for("show_invoice", invoice_id=saved.id), code=303)

How to check

A browser test fills a form with more than 5 fields, reloads the page and finds the values again. A second test submits with a 500 from the server, and every field still holds its value.

For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers app interface playbook: https://agentwranglers.se/playbook/app-ui/forms/keep-user-input.