Dialogs that behave like dialogs
Close dialogs with forms
Use form method="dialog" and submit-button values to close a dialog and report the user’s choice declaratively.
Most dialogs end with a small choice: Save or Cancel, Confirm or Keep editing. A form with method="dialog" can express that choice without a separate click handler on every closing button.
Submitting a dialog-method form closes its containing dialog. The activated submit button’s value becomes dialog.returnValue. No HTTP request is sent. Listen for the dialog’s close event once, then decide what that value means.
<dialog id="editor">
<form method="dialog">
<label>Title <input name="title" required></label>
<button value="cancel" formnovalidate>Cancel</button>
<button value="save">Save task</button>
</form>
</dialog>
<script>
const editor = document.querySelector('#editor')
editor.addEventListener('close', () => {
if (editor.returnValue === 'save') console.log('save the task')
})
</script>
Leave the title empty and click Save. Browser validation keeps the dialog open. Click Cancel and it closes immediately even though the field is still empty.
Save runs constraint validation because the input is required. Cancel carries formnovalidate, so the user can leave without satisfying a field they no longer want to submit. That small detail prevents a common modal trap.
Closing the dialog is not the same as saving app data. Read FormData, run your own business rules, update the board, and talk to the server as separate steps. The free Forms course covers the full submission path when you need it.
Reset stale values on purpose. If Cancel should discard edits, call form.reset() after close or repopulate before the next open. Otherwise the browser keeps the control values and your reused editor looks like it remembers abandoned work.
Try this yourself: submit with an empty title, cancel with validation errors pending, reopen, and decide whether the old title should remain. Add a third button with value="draft" and confirm the close handler can tell it apart without another listener. If Cancel is blocked, confirm it has formnovalidate and lives inside the dialog-method form.
Lesson completed