Validating Form Input

Beyond the attributes of Validation and Autofill, script adds cross-field rules and controls how a form is submitted.

A cross-field rule, formnovalidate and requestSubmit(submitter)HTMLLive
<form action="/age" style="font-family: system-ui, sans-serif">
  <label>Age <input name="age" type="number" min="0" required></label>
  <label><input name="consent" type="checkbox"> Parent agrees</label>
  <button name="go">Proceed</button> <button name="back" formaction="/" formnovalidate>Back</button>
</form>
<pre id="log"></pre>
<script type="module">
  const form = document.querySelector('form');
  const { age, consent, go, back } = form.elements;
  const log = (text) => document.querySelector('#log').append(`${text}\n`);
  age.value = '9';                                       // '' below marks the field valid again
  age.setCustomValidity(age.value < 13 && !consent.checked ? 'Under-13s need a parent.' : '');
  form.addEventListener('invalid', (e) => { e.preventDefault(); log(e.target.validationMessage); },
    true);                                               // invalid does not bubble: capture it
  form.addEventListener('submit', (e) => {
    e.preventDefault();                                  // demo: stay on the page
    log(`submitted by ${e.submitter.name}`);
  });
  form.requestSubmit(go);                                // blocked by the custom error
  form.requestSubmit(back);                              // formnovalidate skips validation
</script>
Browser output of Listing 8.34
Browser output of 34

requestSubmit(submitter) (Baseline widely available since September 2022) acts like a click: it honors formnovalidate and formaction, validates, and fires submit with event.submitter; form.submit() does none of that. Always repeat the checks on the server.