Components Form validator

Important

This component is archived

This component is not sufficiently accessible to be used in live services.

You must validate forms on the server-side. If you require client-side validation, start with native browser form validation. For more complex validation, use an accessible validation library.

Last updated: 31 July 2019

<div tabindex="-1" role="group" id="errorSummary" class="govuk-error-summary moj-hidden" aria-labelledby="error-summary-title" data-module="error-summary">

</div>

<h1 class="govuk-heading-xl">Your details</h1>

<form novalidate>

  <div class="govuk-form-group">
    <label class="govuk-label govuk-!-font-weight-bold" for="email">
      Email
    </label>

    <input class="govuk-input" id="email" name="email" type="text">
  </div>

  <div class="govuk-form-group">
    <label class="govuk-label govuk-!-font-weight-bold" for="password">
      Password
    </label>

    <input class="govuk-input" id="password" name="password" type="password">
  </div>

  <div class="govuk-form-group">

    <fieldset class="govuk-fieldset">

      <legend class="govuk-fieldset__legend govuk-fieldset__legend--s">

        Where do you live?

      </legend>

      <div class="govuk-radios">

        <div class="govuk-radios__item">
          <input class="govuk-radios__input" id="location" name="location" type="radio" value="england">
          <label class="govuk-label govuk-radios__label" for="location">
            England
          </label>

        </div>

        <div class="govuk-radios__item">
          <input class="govuk-radios__input" id="location-2" name="location" type="radio" value="scotland">
          <label class="govuk-label govuk-radios__label" for="location-2">
            Scotland
          </label>

        </div>

        <div class="govuk-radios__item">
          <input class="govuk-radios__input" id="location-3" name="location" type="radio" value="wales">
          <label class="govuk-label govuk-radios__label" for="location-3">
            Wales
          </label>

        </div>

        <div class="govuk-radios__item">
          <input class="govuk-radios__input" id="location-4" name="location" type="radio" value="northern-ireland">
          <label class="govuk-label govuk-radios__label" for="location-4">
            Northern Ireland
          </label>

        </div>

      </div>

    </fieldset>

  </div>

  <div class="govuk-form-group">
    <fieldset class="govuk-fieldset" role="group" aria-describedby="dob-hint">

      <legend class="govuk-fieldset__legend govuk-fieldset__legend--s">

        What is your date of birth?

      </legend>

      <div id="dob-hint" class="govuk-hint">
        For example, 31 3 1980
      </div>

      <div class="govuk-date-input" id="dob">

        <div class="govuk-date-input__item">
          <div class="govuk-form-group">
            <label class="govuk-label govuk-date-input__label" for="dob-day">
              Day
            </label>

            <input class="govuk-input govuk-date-input__input govuk-input--width-2" id="dob-day" name="dob-day" type="text" pattern="[0-9]*" inputmode="numeric">
          </div>
        </div>

        <div class="govuk-date-input__item">
          <div class="govuk-form-group">
            <label class="govuk-label govuk-date-input__label" for="dob-month">
              Month
            </label>

            <input class="govuk-input govuk-date-input__input govuk-input--width-2" id="dob-month" name="dob-month" type="text" pattern="[0-9]*" inputmode="numeric">
          </div>
        </div>

        <div class="govuk-date-input__item">
          <div class="govuk-form-group">
            <label class="govuk-label govuk-date-input__label" for="dob-year">
              Year
            </label>

            <input class="govuk-input govuk-date-input__input govuk-input--width-4" id="dob-year" name="dob-year" type="text" pattern="[0-9]*" inputmode="numeric">
          </div>
        </div>

      </div>

    </fieldset>

  </div>

  <button class="govuk-button" data-module="govuk-button">
    Save and continue
  </button>

</form>


{%- from "govuk/components/input/macro.njk" import govukInput -%}
{%- from "govuk/components/radios/macro.njk" import govukRadios -%}
{%- from "govuk/components/date-input/macro.njk" import govukDateInput -%}
{%- from "govuk/components/button/macro.njk" import govukButton -%}

<div tabindex="-1" role="group" id="errorSummary" class="govuk-error-summary moj-hidden" aria-labelledby="error-summary-title" data-module="error-summary">

</div>

<h1 class="govuk-heading-xl">Your details</h1>

<form novalidate>
  {{ govukInput({
    id: "email",
    name: "email",
    label: {
      text: "Email",
      classes: 'govuk-!-font-weight-bold'
    }
  }) }}

  {{ govukInput({
    id: "password",
    name: "password",
    type: "password",
    label: {
      text: "Password",
      classes: 'govuk-!-font-weight-bold'
    }
  }) }}

  {{ govukRadios({
    idPrefix: "location",
    name: "location",
    fieldset: {
      legend: {
        text: "Where do you live?",
        classes: 'govuk-fieldset__legend--s'
      }
    },
    items: [
      {
        id: 'location',
        value: "england",
        text: "England"
      },
      {
        value: "scotland",
        text: "Scotland"
      },
      {
        value: "wales",
        text: "Wales"
      },
      {
        value: "northern-ireland",
        text: "Northern Ireland"
      }
    ]
  }) }}

  {{ govukDateInput({
    id: "dob",
    namePrefix: "dob",
    fieldset: {
      legend: {
        text: "What is your date of birth?",
        classes: 'govuk-fieldset__legend--s'
      }
    },
    hint: {
      text: "For example, 31 3 1980"
    }
  }) }}

  {{ govukButton({
    text: "Save and continue"
  }) }}
</form>
const validator = new MOJFrontend.FormValidator(document.forms[0]);
validator.addValidator('email', [{
  method: function(field) {
    return field.value.trim().length > 0;
  },
  message: 'Enter your email address'
}, {
  method: function(field) {
    return (field.value.indexOf('@') > -1);
  },
  message: 'You need to enter the ‘at’ symbol in your email address'
}]);
validator.addValidator('password', [{
  method: function(field) {
    return field.value.trim().length > 0;
  },
  message: 'Enter your password'
}, {
  method: function(field) {
    return field.value.length > 8;
  },
  message: 'Your password must contain at least 8 characters'
}, {
  method: function(field) {
    return /\d/.test(field.value);
  },
  message: 'Your password must contain at least one number'
}]);
validator.addValidator('location', [{
  method: function(field) {
    return field.value.trim().length > 0;
  },
  message: 'Select your location'
}]);
validator.addValidator('dob-day', [{
  method: function(field, params) {
    return (params.day.value.length !== 0 && params.month.value.length !== 0 && params.year.value !== 0);
  },
  message: 'Enter your date of birth',
  params: {
    day: document.getElementById('dob-day'),
    month: document.getElementById('dob-month'),
    year: document.getElementById('dob-year')
  }
}, {
  method: function(field, params) {
    var d = new Date(parseInt(params.year.value, 10), parseInt(params.month.value, 10) - 1, parseInt(params.day.value, 10) - 1);
    return d instanceof Date && !isNaN(d);
  },
  message: 'Enter a valid date of birth',
  params: {
    day: document.getElementById('dob-day'),
    month: document.getElementById('dob-month'),
    year: document.getElementById('dob-year')
  }
}]);

When to use

Use the form validator component to validate forms without a server-side round-trip while also conforming to the established standards set out in the GOV.UK Design System.

How to use

In alignment with established GOV.UK Design System standards:

  • validation is performed on submit. Forms should never be validated as the user types or blurs the field.
  • when the form is submitted with errors, focus moves to the error summary; errors are shown above the field and the <title> is prefixed with the error count.
  • submit buttons are never disabled.