Cookies on ons.gov.uk

Cookies are small files stored on your device when you visit a website. We use some essential cookies to make this website work.

We would like to set additional cookies to remember your settings and understand how you use the site. This helps us to improve our services.

You have accepted all additional cookies. You have rejected all additional cookies. You can change your cookie preferences at any time.

Skip to main content

Ask users for Dates

Overview

Use this pattern to help users enter a date.

Example Date Input contents

Nunjucks

{% from "components/date-input/_macro.njk" import onsDateInput %}

{{
    onsDateInput({
        "id": "date-input-example",
        "legendOrLabel": "Date of birth",
        "description": "For example, 31 3 1980",
        "day": {
            "label": {
                "text": "Day"
            },
            "name": "day",
            "attributes": {
                "autocomplete": "bday-day"
            }
        },
        "month": {
            "label": {
                "text": "Month"
            },
            "name": "month",
            "attributes": {
                "autocomplete": "bday-month"
            }
        },
        "year": {
            "label": {
                "text": "Year"
            },
            "name": "year",
            "attributes": {
                "autocomplete": "bday-year"
            }
        }
    })
}}

Nunjucks macro options

NameTypeRequiredDescription
idstringtrueThe base HTML id for the inputs. -day, -month, and -year will be appended to this id and applied to each input
classesstringfalseClasses to apply to the fieldset
legendOrLabelstringtrueThe HTML legend for the date fieldset. If only a single field is used, the label will be overridden with this property’s value
legendClassesstringfalseClasses to apply to the HTML legend. Use to set the utility class .ons-u-vh to visually hide the legend if repeated in the page heading.
descriptionstringtrueThe hint text for the date fieldset. Use to provide guidance on the required format
dayObject<DateField>falseSettings for the day date field
monthObject<DateField>trueSettings for the month date field
yearObject<DateField>falseSettings for the year date field
mutuallyExclusiveMutuallyExclusive (ref)falseSettings object if the date is a mutually exclusive answer
dontWrapbooleanfalsePrevents the date inputs from being wrapped in the fieldset component
legendIsQuestionTitlebooleanfalseCreates an h1 inside the legend. Use when the date is the only fieldset on the page
errorError (ref)falseSettings for validation errors
DateField
NameTypeRequiredDescription
labelLabel (ref)trueLabel config for the field
namestringtrueName of the field
valuenumberfalsePreset value for the field
attributesobjectfalseHTML attributes (for example, data attributes) to add to the input
errorbooleanfalseIf set to true will style this specific field as if it has an error

HTML

<fieldset id="date-input-example" class="ons-fieldset">
  <legend aria-describedBy="date-input-example-legend-description"
    class="ons-fieldset__legend ons-fieldset__legend--with-description"><span
      class="ons-fieldset__legend-title ons-u-pb-no">Date of birth</span></legend>
  <div id="date-input-example-legend-description" class="ons-fieldset__description">For example, 31 3 1980</div>
  <div class="ons-field-group">
    <div class="ons-field">
      <label class="ons-label" for="date-input-example-day" id="date-input-example-day-label">Day</label>
      <input type="text" id="date-input-example-day"
        class="ons-input ons-input--text ons-input-type__input ons-input-number--w-2" name="day" min="1" max="31"
        maxlength="2" pattern="[0-9]*" inputmode="numeric" autocomplete="bday-day" />
    </div>
    <div class="ons-field">
      <label class="ons-label" for="date-input-example-month" id="date-input-example-month-label">Month</label>
      <input type="text" id="date-input-example-month"
        class="ons-input ons-input--text ons-input-type__input ons-input-number--w-2" name="month" min="1" max="12"
        maxlength="2" pattern="[0-9]*" inputmode="numeric" autocomplete="bday-month" />
    </div>
    <div class="ons-field">
      <label class="ons-label" for="date-input-example-year" id="date-input-example-year-label">Year</label>
      <input type="text" id="date-input-example-year"
        class="ons-input ons-input--text ons-input-type__input ons-input-number--w-4" name="year" min="1000" max="3000"
        maxlength="4" pattern="[0-9]*" inputmode="numeric" autocomplete="bday-year" />
    </div>
  </div>
</fieldset>

When to use this pattern

Use the date pattern when you need to ask users for a date they will already know. For example, their date of birth.

When not to use this pattern

Do not use the date pattern if you are asking the user about an event they are unlikely to know the exact date of.

How to use this pattern

To allow the user to enter a day, month and year, this pattern uses three input components.

The 3 input fields are grouped within a fieldset.

A <legend> that lets the user know what they need to enter is added to this fieldset.

A description is used to provide an example of the required format for the date: “For example, 31 3 1980”. Do not use acronyms such as ‘e.g.’ in this description.

Warning:

Never automatically tab the user between the fields. This can be confusing and may hinder normal keyboard control.

The date fields have a maxlength limit set to the maximum number of digits required for day and month (2), and year (4), to prevent users entering too many digits in a single field.

This prevents users who expect to be able to auto-tab between the fields from entering the full date into the first field.

Each field uses the width: <number> parameter to set the number of digits required for each field.

Date of birth

Use the autocomplete attribute when you are asking for a date of birth to help the user answer the question faster.

To do this, set the autocomplete attribute on each of the 3 date input fields to:

  • bday-day
  • bday-month
  • bday-year

See how to do this in the HTML and Nunjucks code tabs in the examples above.

You will need to use the autocomplete attribute to meet AA WCAG 2.1 accessibility requirements.

How to check dates

To help users enter a valid date, you should:

  • check they have entered something in the date fields
  • check that what they have entered is valid
  • show an error message if they have not entered anything or what they have entered is not valid

Error messages

Show the error details above the date fields and use the correct errors pattern.

Example Date Input Error contents

Nunjucks

{% from "components/date-input/_macro.njk" import onsDateInput %}
{{
    onsDateInput({
        "id": "period-from-date-input-error-example",
        "legendOrLabel": "Period from:",
        "description": "For example, 31 3 2019",
        "day": {
            "label": {
                "text": "Day"
            },
            "name": "day",
            "value": "1"
        },
        "month": {
            "label": {
                "text": "Month"
            },
            "name": "month",
            "value": "1"
        },
        "year": {
            "label": {
                "text": "Year"
            },
            "name": "year",
            "value": "2019"
        }
    })
}}

{{
    onsDateInput({
        "id": "period-to-date-input-error-example",
        "legendOrLabel": "Period to:",
        "description": "For example, 31 3 2020",
        "day": {
            "label": {
                "text": "Day"
            },
            "name": "day",
            "value": "31"
        },
        "month": {
            "label": {
                "text": "Month"
            },
            "name": "month",
            "value": "12"
        },
        "year": {
            "label": {
                "text": "Year"
            },
            "name": "year",
            "value": "2018"
        },
        "error": {
            "text": "Enter a date that is after 1 January 2019"
        }
    })
}}
Nunjucks macro options
NameTypeRequiredDescription
idstringtrueThe base HTML id for the inputs. -day, -month, and -year will be appended to this id and applied to each input
classesstringfalseClasses to apply to the fieldset
legendOrLabelstringtrueThe HTML legend for the date fieldset. If only a single field is used, the label will be overridden with this property’s value
legendClassesstringfalseClasses to apply to the HTML legend. Use to set the utility class .ons-u-vh to visually hide the legend if repeated in the page heading.
descriptionstringtrueThe hint text for the date fieldset. Use to provide guidance on the required format
dayObject<DateField>falseSettings for the day date field
monthObject<DateField>trueSettings for the month date field
yearObject<DateField>falseSettings for the year date field
mutuallyExclusiveMutuallyExclusive (ref)falseSettings object if the date is a mutually exclusive answer
dontWrapbooleanfalsePrevents the date inputs from being wrapped in the fieldset component
legendIsQuestionTitlebooleanfalseCreates an h1 inside the legend. Use when the date is the only fieldset on the page
errorError (ref)falseSettings for validation errors
DateField
NameTypeRequiredDescription
labelLabel (ref)trueLabel config for the field
namestringtrueName of the field
valuenumberfalsePreset value for the field
attributesobjectfalseHTML attributes (for example, data attributes) to add to the input
errorbooleanfalseIf set to true will style this specific field as if it has an error
HTML
<fieldset id="period-from-date-input-error-example" class="ons-fieldset">
  <legend aria-describedBy="period-from-date-input-error-example-legend-description"
    class="ons-fieldset__legend ons-fieldset__legend--with-description"><span
      class="ons-fieldset__legend-title ons-u-pb-no">Period from:</span></legend>
  <div id="period-from-date-input-error-example-legend-description" class="ons-fieldset__description">For example, 31 3
    2019</div>
  <div class="ons-field-group">
    <div class="ons-field">
      <label class="ons-label" for="period-from-date-input-error-example-day"
        id="period-from-date-input-error-example-day-label">Day</label>
      <input type="text" id="period-from-date-input-error-example-day"
        class="ons-input ons-input--text ons-input-type__input ons-input-number--w-2" name="day" value="1" min="1"
        max="31" maxlength="2" pattern="[0-9]*" inputmode="numeric" />
    </div>
    <div class="ons-field">
      <label class="ons-label" for="period-from-date-input-error-example-month"
        id="period-from-date-input-error-example-month-label">Month</label>
      <input type="text" id="period-from-date-input-error-example-month"
        class="ons-input ons-input--text ons-input-type__input ons-input-number--w-2" name="month" value="1" min="1"
        max="12" maxlength="2" pattern="[0-9]*" inputmode="numeric" />
    </div>
    <div class="ons-field">
      <label class="ons-label" for="period-from-date-input-error-example-year"
        id="period-from-date-input-error-example-year-label">Year</label>
      <input type="text" id="period-from-date-input-error-example-year"
        class="ons-input ons-input--text ons-input-type__input ons-input-number--w-4" name="year" value="2019"
        min="1000" max="3000" maxlength="4" pattern="[0-9]*" inputmode="numeric" />
    </div>
  </div>
</fieldset>
<div class="ons-panel ons-panel--error ons-panel--no-title">
  <span class="ons-panel__assistive-text ons-u-vh">Error: </span>
  <div class="ons-panel__body">
    <p class="ons-panel__error">
      <strong>Enter a date that is after 1 January 2019</strong>
    </p>
    <fieldset id="period-to-date-input-error-example" class="ons-fieldset">
      <legend aria-describedBy="period-to-date-input-error-example-legend-description"
        class="ons-fieldset__legend ons-fieldset__legend--with-description"><span
          class="ons-fieldset__legend-title ons-u-pb-no">Period to:</span></legend>
      <div id="period-to-date-input-error-example-legend-description" class="ons-fieldset__description">For example, 31
        3 2020</div>
      <div class="ons-field-group">
        <div class="ons-field">
          <label class="ons-label" for="period-to-date-input-error-example-day"
            id="period-to-date-input-error-example-day-label">Day</label>
          <input type="text" id="period-to-date-input-error-example-day"
            class="ons-input ons-input--text ons-input-type__input  ons-input--error ons-input-number--w-2" name="day"
            value="31" min="1" max="31" maxlength="2" pattern="[0-9]*" inputmode="numeric" />
        </div>
        <div class="ons-field">
          <label class="ons-label" for="period-to-date-input-error-example-month"
            id="period-to-date-input-error-example-month-label">Month</label>
          <input type="text" id="period-to-date-input-error-example-month"
            class="ons-input ons-input--text ons-input-type__input  ons-input--error ons-input-number--w-2" name="month"
            value="12" min="1" max="12" maxlength="2" pattern="[0-9]*" inputmode="numeric" />
        </div>
        <div class="ons-field">
          <label class="ons-label" for="period-to-date-input-error-example-year"
            id="period-to-date-input-error-example-year-label">Year</label>
          <input type="text" id="period-to-date-input-error-example-year"
            class="ons-input ons-input--text ons-input-type__input  ons-input--error ons-input-number--w-4" name="year"
            value="2018" min="1000" max="3000" maxlength="4" pattern="[0-9]*" inputmode="numeric" />
        </div>
      </div>
    </fieldset>
  </div>
</div>

If all fields are empty

Use “Enter [whatever date is being asked for]”.

For example, “Enter your date of birth”.

If one or two of the fields are empty

Use “Enter the [whatever part or parts of the date is missing]”.

For example, “Enter the year you were born” or “Enter the month and year you were born”.

If what is entered in one of the fields is not a number

Use “Enter a number for [invalid field], for example, [appropriate number]”.

For example, “Enter a number for months, for example, 7”.

If what is entered in a field is above the maximum value for that field

Use “Enter a number that is less than [whatever the maximum is for that part of the date]”.

For example, “Enter a number that is less than 12” for months.

If what is entered is not within the required date range

Use “Enter a date that is between [whatever the minimum is] and [whatever the maximum is]”.

For example, “Enter a date that is between 1 April 2019 and 31 March 2020”.

If the date range entered is not valid

Use “Enter a date that is after [whatever the start date is]”.

For example, “Enter a date that is after 1 January 1999”.

Help improve this page

Let us know how we could improve this page, or share your user research findings. Discuss the ‘Dates’ pattern on GitHub (opens in a new tab)