Ask Anvil

Answers to questions about automating PDFs, e-signatures, Webforms, and other paperwork problems.
Webforms
Categories

Why won't my web form submit when a conditional section is hidden, and how do I fix it?

You have a form with a section that only appears when the user checks a box, say company details for business applicants. Individual applicants leave it hidden, click Submit, and nothing happens. No error bubble, no request in the network tab. In Chrome, the only clue is a console message along the lines of: An invalid form control with name='companyName' is not focusable.

The cause

The inputs in the hidden section are still required. Hiding an element with the hidden attribute, display: none, or visibility: hidden changes how it renders, not whether it takes part in validation. On submit, the browser checks every required control, finds an empty one, and tries to focus it to show the error. It cannot focus a control that is not displayed, so it blocks the submission and gives the user nothing to act on.

The fix: disable what you hide

Per the HTML standard, a disabled control is barred from constraint validation, and every control inside a disabled fieldset counts as disabled. So wrap each conditional section in a fieldset and toggle disabled alongside hidden. This runs in Node with jsdom; the toggleSection function works unchanged in a browser:

const { JSDOM } = require('jsdom')

const dom = new JSDOM(`
<form id="apply">
  <label><input type="checkbox" id="isBusiness" name="isBusiness" value="yes"> Applying as a business</label>
  <fieldset id="companyFields" hidden>
    <input name="companyName" required>
    <input name="ein" required pattern="\\d{2}-\\d{7}">
  </fieldset>
  <input name="email" type="email" value="ada@example.com" required>
</form>`)

const { document, FormData } = dom.window
const form = document.getElementById('apply')
const section = document.getElementById('companyFields')

// Broken: hidden only changes rendering. The required inputs still validate.
console.log('hidden only:', form.checkValidity()) // false

// Fixed: hide AND disable, so the inputs are barred from validation.
function toggleSection(el, show) {
  el.hidden = !show
  el.disabled = !show
}

toggleSection(section, false)
console.log('hidden + disabled:', form.checkValidity()) // true
console.log([...new FormData(form).keys()]) // [ 'email' ]

// Wire it to the checkbox so the section validates only when shown.
document.getElementById('isBusiness').addEventListener('change', (e) => {
  toggleSection(section, e.target.checked)
})

While the section is only hidden, checkValidity() returns false, which is exactly the silent block your users hit. Once the fieldset is also disabled, the form is valid. Check the box and the fields validate again.

Two tempting alternatives are worse. Stripping the required attribute when you hide a section works, but you have to remember which fields to restore, and it misses other constraints: a half-typed EIN that no longer matches its pattern will still block the submit. Adding novalidate to the form makes the symptom go away by skipping the browser's validation for every field on submit, which is rarely what you want.

Caveats

Disabled controls are also left out of the submitted data, so in the example the payload contains only email. For a conditional section that is usually what you want, since values from a section the user backed out of should not reach your server. If you do need those values, disabling is the wrong tool; copy them into input type="hidden" fields, which are submitted but never validated.

Client-side validation is a convenience, not a guarantee. Apply the same condition on the server: require companyName and ein only when isBusiness is present in the submission.

Back to All Questions

The fastest way to build software for documents

Anvil Document SDK is a comprehensive toolbox for product teams launching document flows where PDF filling, signing, and complex conditional scenarios are necessary.
Explore Anvil
Anvil Webforms
Marketing Mode