Skip to main content

Address input

Allows users to find an address using an address finder or enter one manually.

When to use this component

Use this component to help users either:

There is specific guidance on how to ask users for addresses.

How to use this component with the ONS Address Index API

The address input extends the code base used for the autosuggest component.

There are two main ways to use this component with the ONS Address Index API. Addresses can be either:

Non-editable address finder

Include the parameter isEditable: false. You will also need to set other parameters as shown in the Nunjucks options in the example.

When a user selects an address it is displayed in the address finder input.

The UPRN (unique ID) for the selected address is added to a hidden input. This is posted with the rest of the form data when it is submitted.

If there is an issue with the API, the component will disable the address finder and show an error message.

Important information:

If you cannot use the address finder in the following example you will need to email the Design System working group at ons.design.system@ons.gov.uk to ask for access to the API.

<div id="address" class="ons-field ons-address-input ons-address-input--search ons-js-address-autosuggest">
  <input type="hidden" id="address-uprn" class="ons-input ons-input--text ons-input-type__input ons-js-hidden-uprn ons-u-d-no" name="address-uprn" />
  <div class="ons-js-address-input__search">
    <div id="address-autosuggest-container" class="ons-js-address-not-editable ons-js-address-mandatory  ons-autosuggest-input" data-instructions="Use up and down keys to navigate suggestions once you&#39;ve typed more than two characters. Use the enter key to select a suggestion. Touch device users, explore by touch or with swipe gestures." data-aria-you-have-selected="You have selected" data-aria-min-chars="Enter 3 or more characters for suggestions." data-aria-one-result="There is one suggestion available." data-aria-n-results="There are {n} suggestions available." data-aria-limited-results="Results have been limited to 10 suggestions. Type more characters to improve your search" data-more-results="Enter more of the address to improve results" data-results-title="Select an address" data-no-results="No results found. Try entering a different part of the address" data-type-more="Enter more of the address to get results" data-api-domain="https://whitelodge-eq-ai-api.census-gcp.onsdigital.uk" data-authorization-token="some_token" data-error-title="There is a problem with your answer" data-error-enter="Enter an address" data-error-select="Select an address" data-aria-grouped-results="There are {n} for {x}" data-group-count="{n} addresses" data-too-many-results="{n} results found. Enter more of the address to improve results" data-error-api="Sorry, there is a problem. We are working to fix it. Please try again later or" data-error-api-link-text="contact us for more help" data-options-region-code="gb-eng" data-options-address-type="residential">
      <div class="ons-field">
        <label class="ons-label ons-js-autosuggest-label " for="address-autosuggest" id="address-label">Enter address or postcode and select from results
        </label>
        <input type="text" id="address-autosuggest" class="ons-input ons-input--text ons-input-type__input ons-js-autosuggest-input ons-address-input__autosuggest ons-u-mb-no ons-input--w-50" autocomplete="new-password" />
      </div>
      <div class="ons-autosuggest-input__results ons-js-autosuggest-results">
        <header class="ons-autosuggest-input__results-title ons-u-fs-s">Select an address</header>
        <ul class="ons-autosuggest-input__listbox ons-js-autosuggest-listbox" role="listbox" id="address-autosuggest-listbox" aria-labelledby="" tabindex="-1"></ul>
      </div>
      <div class="ons-autosuggest-input__instructions ons-u-vh ons-js-autosuggest-instructions" id="address-autosuggest-instructions" tabindex="-1">Use up and down keys to navigate suggestions once you&#39;ve typed more than two characters. Use the enter key to select a suggestion. Touch device users, explore by touch or with swipe gestures.</div>
      <div class="ons-autosuggest-input__status ons-u-vh ons-js-autosuggest-aria-status" aria-live="assertive" role="status" tabindex="-1"></div>
    </div>
  </div>
</div>
{% from "components/address-input/_macro.njk" import onsAddressInput %}

{{ onsAddressInput({
    "id": "address",
    "dontWrap": true,
    "label": {
        "text": "Enter address or postcode and select from results",
        "id": "address-label"
    },
    "isEditable": false,
    "mandatory": true,
    "externalInitialiser": true,
    "autocomplete": "new-password",
    "APIDomain": "https://whitelodge-eq-ai-api.census-gcp.onsdigital.uk",
    'APIDomainBearerToken': "some_token",
    "instructions": "Use up and down keys to navigate suggestions once you\'ve typed more than two characters. Use the enter key to select a suggestion. Touch device users, explore by touch or with swipe gestures.",
    "ariaYouHaveSelected": "You have selected",
    "ariaMinChars": "Enter 3 or more characters for suggestions.",
    "ariaResultsLabel": "Address suggestions",
    "ariaOneResult": "There is one suggestion available.",
    "ariaNResults": "There are {n} suggestions available.",
    "ariaLimitedResults": "Results have been limited to 10 suggestions. Type more characters to improve your search",
    "ariaGroupedResults": "There are {n} for {x}",
    "groupCount": "{n} addresses",
    "moreResults": "Enter more of the address to improve results",
    "resultsTitle": "Select an address",
    "noResults": "No results found. Try entering a different part of the address",
    "tooManyResults": "{n} results found. Enter more of the address to improve results",
    "typeMore": "Enter more of the address to get results",
    "errorTitle": "There is a problem with your answer",
    "errorMessageEnter": "Enter an address",
    "errorMessageSelect": "Select an address",
    "errorMessageAPI": "Sorry, there is a problem. We are working to fix it. Please try again later or",
    "errorMessageAPILinkText": "contact us for more help",
    "errorMessageAPILink": "#0",
    "options": {
        "regionCode": "gb-eng",
        "addressType": "residential"
    }
}) }}
Name Type Required Description
id string true ID for the fieldset. This is used to automatically generate IDs and names for each field if one isn’t specified
classes string false Classes to add to the fieldset
label Label (ref) false Settings for the input label. for will automatically be set to match the input id
legend string true Legend text for the address input
legendClasses string false Classes to apply to the legend
dontWrap boolean false Set to true to prevent the address fields from being wrapped in a fieldset
isEditable boolean true Used with the address macro to invoke population of manual fields upon selection of suggestion
manualEntry boolean false Only display manual fields and do not invoke autosuggest/api functionality
mandatory boolean false Set the autosuggest input to be mandatory and use client side validation for empty form submission
APIDomain string false Set an api domain when using an external API to suggest results
APIDomainBearerToken string false Set a bearer token for api authorization on the AIMS address api.
instructions string true Instructions on how to use the autosuggest that will be read out by screen readers
ariaYouHaveSelected string true Aria message to tell the user that they have selected an answer
ariaMinChars string true Aria message to tell the user how many characters they need to enter before autosuggest will start
ariaResultsLabel string true Aria message to tell the user that suggestions are available
ariaOneResult string true Aria message to tell the user there is only one suggestion left
ariaNResults string true Aria message to tell the user how many suggestions are left
ariaLimitedResults string true Aria message to tell the user if the results have been limited and what they are limited to
ariaGroupedResults string true Aria message to tell the user about a grouped result, for example, There are {n} for {x}
groupCount string true Aria message to tell the user the number of addresses in a group, for example, {n} addresses
moreResults string true Aria message to tell the user to continue to type to refine suggestions
noResults string true message to tell the user there are no results
tooManyResults string true message to tell the user there are too many results to display and the user should refine the search
typeMore string true message to encourage the user to enter more characters to get suggestions
resultsTitle string true Title of results to be displayed on screen at the top of the results
errorTitle string false Error message title displayed in the error panel
errorMessageEnter string false Error message description displayed in the error panel when the input is empty
errorMessageSelect string false Error message description displayed in the error panel when a suggestion has not been selected
errorMessageAPI string false Error message displayed when the API has failed during a search
errorMessageAPILinkText string false Link text used to toggle to a manual mode when using the address macro
manualLink string false url for the link displayed below the input
manualLinkText string false Link text shown for the manual link. If using the editable address, including this parameter will toggle the mode to manual entry
options Object<Options> false Option to provide key value pairs that will be added as data attributes to the component that will be added as parameters to the address index api
organisation Object<AddressField> false Configuration for the organisation field.
line1 Object<AddressField> false Configuration for the line1 field
line2 Object<AddressField> false Configuration for the line2 field
town Object<AddressField> false Configuration for the town field
county Object<AddressField> false Configuration for the county field
postcode Object<AddressField> false Configuration for the postcode field
uprn Object<AddressField> false Configuration for the uprn field
mutuallyExclusive MutuallyExclusive (ref) false Configuration object if this is a mutually exclusive input
legend string Only if mutuallyExclusive is set Text content for the legend
legendClasses string false Classes for the legend
error Error (ref) false Configuration for validation errors
name string false The name of the input
value string | number false The value to set the input to
attributes object false HTML attributes (for example, data attributes) to add to the input

Options

Name Type Required Description
regionCode string false Sets the provided region code, for example, en-gb
addressType string false Sets the provided address type, for example, residential
oneYearAgo string false If “true” will set a query parameter of epoch=75

AddressField

Name Type Required Description
id string false ID for the field
name string false Sets the name attribute on the field
label.text string true The label for the input
value string false The value for the input
error Error (ref) false Configuration for validation errors
{% from "components/fieldset/_macro.njk" import onsFieldset %}
{% from "components/autosuggest/_macro.njk" import onsAutosuggest %}
{% from "components/input/_macro.njk" import onsInput %}

{% macro onsAddressInput(params) %}
   {% set fields %}
        <div id="address" class="ons-field ons-address-input {% if not params.manualEntry %}ons-address-input--search ons-js-address-autosuggest{% endif %}">
            {% if params.isEditable == true or params.manualEntry %}
                {% if not params.manualEntry %}<div class="ons-js-address-input__manual ons-u-db-no-js_enabled">{% endif %}
                    {% if params.organisation is defined and params.organisation %}
                        {{
                            onsInput({
                                "id": params.id + "-organisation",
                                "label": {
                                    "text": params.organisation.label
                                },
                                "classes": "ons-js-address-organisation",
                                "width": "20@m",
                                "name": params.id + "-organisation",
                                "error": params.organisation.error
                            })
                        }}
                    {% endif %}
                    {% if params.line1 is defined and params.line1 %}
                        {{
                            onsInput({
                                "id": params.id + "-line1",
                                "value": params.line1.value,
                                "label": {
                                    "text": params.line1.label
                                },
                                "classes": "ons-js-address-line1",
                                "width": "20@m",
                                "name": params.id + "-line1",
                                "error": params.line1.error
                            })
                        }}
                    {% endif %}
                    {% if params.line2 is defined and params.line2 %}
                        {{
                            onsInput({
                                "id": params.id + "-line2",
                                "value": params.line2.value,
                                "label": {
                                    "text": params.line2.label
                                },
                                "classes": "ons-js-address-line2",
                                "width": "20@m",
                                "name": params.id + "-line2",
                                "error": params.line2.error
                            })
                        }}
                    {% endif %}
                    {% if params.town is defined and params.town %}
                        {{
                            onsInput({
                                "id": params.id + "-town",
                                "value": params.town.value,
                                "label": {
                                    "text": params.town.label
                                },
                                "classes": "ons-js-address-town",
                                "name": params.id + "-town",
                                "error": params.town.error
                            })
                        }}
                    {% endif %}
                    {% if params.postcode is defined and params.postcode %}
                        {{
                            onsInput({
                                "id": params.id + "-postcode",
                                "value": params.postcode.value,
                                "label": {
                                    "text": params.postcode.label
                                },
                                "classes": "ons-js-address-postcode",
                                "width": "7",
                                "name": params.id + "-postcode",
                                "error": params.postcode.error
                            })
                        }}
                    {% endif %}
                {% if not params.manualEntry %}
                        <div class="ons-u-mt-s">
                            <a href="#0" class="ons-js-address-search-btn ons-u-db-no-js_disabled">{{ params.searchButton }}</a>
                        </div>
                    </div>
                {% endif %}
            {% endif %}

            {% if params.uprn is defined and params.uprn and params.uprn.value is defined and params.uprn.value %}
                {% set uprnValue = params.uprn.value %}
            {% else %}
                {% set uprnValue = '' %}
            {% endif %}

            {{
                onsInput({
                    "id": params.id + "-uprn",
                    "classes": "ons-js-hidden-uprn ons-u-d-no",
                    "type": "hidden",
                    "name": params.id + "-uprn",
                    "value": uprnValue
                })
            }}
            {% if not params.manualEntry %}
                <div class="ons-js-address-input__search{% if params.isEditable == true %} ons-u-db-no-js_disabled{% endif %}">
                    {{
                        onsAutosuggest({
                            "id": params.id + "-autosuggest",
                            "classes": "ons-address-input__autosuggest ons-u-mb-no",
                            "width": "50",
                            "label": {
                                "text": params.label.text,
                                "id": params.label.id,
                                "classes": "ons-js-autosuggest-label"
                            },
                            "value": params.value,
                            "attributes": params.attributes,
                            "error": params.error,
                            "name": params.name,
                            "mutuallyExclusive": params.mutuallyExclusive,
                            "externalInitialiser": true,
                            "APIDomain": params.APIDomain,
                            "APIDomainBearerToken": params.APIDomainBearerToken,
                            "APIManualQueryParams": params.APIManualQueryParams,
                            "allowMultiple": params.allowMultiple,
                            "mandatory": params.mandatory,
                            "instructions": params.instructions,
                            "autocomplete": params.autocomplete,
                            "isEditable": params.isEditable,
                            "ariaYouHaveSelected": params.ariaYouHaveSelected,
                            "ariaMinChars": params.ariaMinChars,
                            "ariaResultsLabel": params.ariaResultsLabel,
                            "ariaOneResult": params.ariaOneResult,
                            "ariaNResults": params.ariaNResults,
                            "ariaLimitedResults": params.ariaLimitedResults,
                            "ariaGroupedResults": params.ariaGroupedResults,
                            "groupCount": params.groupCount,
                            "moreResults": params.moreResults,
                            "tooManyResults": params.tooManyResults,
                            "resultsTitle": params.resultsTitle,
                            "noResults": params.noResults,
                            "typeMore": params.typeMore,
                            "errorTitle": params.errorTitle,
                            "errorMessageEnter": params.errorMessageEnter,
                            "errorMessageSelect": params.errorMessageSelect,
                            "errorMessageAPI": params.errorMessageAPI,
                            "errorMessageAPILinkText": params.errorMessageAPILinkText,
                            "options": params.options,
                            "manualLink": params.manualLink,
                            "manualLinkText": params.manualLinkText
                        })
                    }}
                    {% if params.manualLinkText %}
                        <a href="{{ params.manualLink | default('#0') }}" class="ons-js-address-manual-btn ons-u-mt-s ons-u-dib">{{ params.manualLinkText }}</a>
                    {% endif %}
                </div>
            {% endif %}
        </div>
    {% endset %}

    {% if params.dontWrap is defined and params.dontWrap %}
        {{ fields | safe }}
    {% else %}
        {% call onsFieldset({
            "id": params.id,
            "classes": params.classes,
            "legend": params.legend,
            "legendClasses": params.legendClasses
        }) %}
            {{ fields | safe }}
        {% endcall %}
    {% endif %}
{% endmacro %}

Editable address finder

Include the parameter isEditable: true. You will also need to set other parameters as shown in the Nunjucks options in the example.

When a user selects an address, it will be displayed in a set of manual fields. This allows the user to check and edit the address.

If the address is changed, the UPRN (unique ID) is removed and not posted with the rest of the form data.

If there is an issue with the API, the manual fields will be shown instead of the address finder.

Important information:

If the address finder is not showing in the following example you will need to email the Design System working group at ons.design.system@ons.gov.uk to ask for access to the API.

<div id="address" class="ons-field ons-address-input ons-address-input--search ons-js-address-autosuggest">
  <div class="ons-js-address-input__manual ons-u-db-no-js_enabled">
    <div class="ons-field">
      <label class="ons-label  " for="address-line1">Address line 1
      </label>
      <input type="text" id="address-line1" class="ons-input ons-input--text ons-input-type__input ons-js-address-line1 ons-input--w-20@m" name="address-line1" />
    </div>
    <div class="ons-field">
      <label class="ons-label  " for="address-line2">Address line 2
      </label>
      <input type="text" id="address-line2" class="ons-input ons-input--text ons-input-type__input ons-js-address-line2 ons-input--w-20@m" name="address-line2" />
    </div>
    <div class="ons-field">
      <label class="ons-label  " for="address-town">Town or city
      </label>
      <input type="text" id="address-town" class="ons-input ons-input--text ons-input-type__input ons-js-address-town" name="address-town" />
    </div>
    <div class="ons-field">
      <label class="ons-label  " for="address-postcode">Postcode
      </label>
      <input type="text" id="address-postcode" class="ons-input ons-input--text ons-input-type__input ons-js-address-postcode ons-input--w-7" name="address-postcode" />
    </div>
    <div class="ons-u-mt-s">
      <a href="#0" class="ons-js-address-search-btn ons-u-db-no-js_disabled">Search for an address</a>
    </div>
  </div>
  <input type="hidden" id="address-uprn" class="ons-input ons-input--text ons-input-type__input ons-js-hidden-uprn ons-u-d-no" name="address-uprn" />
  <div class="ons-js-address-input__search ons-u-db-no-js_disabled">
    <div id="address-autosuggest-container" class=" ons-js-address-mandatory  ons-autosuggest-input" data-instructions="Use up and down keys to navigate suggestions once you&#39;ve typed more than two characters. Use the enter key to select a suggestion. Touch device users, explore by touch or with swipe gestures." data-aria-you-have-selected="You have selected" data-aria-min-chars="Enter 3 or more characters for suggestions." data-aria-one-result="There is one suggestion available." data-aria-n-results="There are {n} suggestions available." data-aria-limited-results="Results have been limited to 10 suggestions. Type more characters to improve your search" data-more-results="Enter more of the address to improve results" data-results-title="Select an address" data-no-results="No results found. Try entering a different part of the address" data-type-more="Enter more of the address to get results" data-api-domain="https://whitelodge-eq-ai-api.census-gcp.onsdigital.uk" data-authorization-token="some_token" data-error-title="There is a problem with your answer" data-error-enter="Enter an address" data-error-select="Select an address" data-aria-grouped-results="There are {n} for {x}" data-group-count="{n} addresses" data-too-many-results="{n} results found. Enter more of the address to improve results" data-error-api="Sorry, there is a problem loading addresses." data-error-api-link-text="Enter address manually" data-options-region-code="gb-eng" data-options-address-type="residential">
      <div class="ons-field">
        <label class="ons-label ons-js-autosuggest-label " for="address-autosuggest" id="address-label">Enter address or postcode and select from results
        </label>
        <input type="text" id="address-autosuggest" class="ons-input ons-input--text ons-input-type__input ons-js-autosuggest-input ons-address-input__autosuggest ons-u-mb-no ons-input--w-50" autocomplete="new-password" />
      </div>
      <div class="ons-autosuggest-input__results ons-js-autosuggest-results">
        <header class="ons-autosuggest-input__results-title ons-u-fs-s">Select an address</header>
        <ul class="ons-autosuggest-input__listbox ons-js-autosuggest-listbox" role="listbox" id="address-autosuggest-listbox" aria-labelledby="" tabindex="-1"></ul>
      </div>
      <div class="ons-autosuggest-input__instructions ons-u-vh ons-js-autosuggest-instructions" id="address-autosuggest-instructions" tabindex="-1">Use up and down keys to navigate suggestions once you&#39;ve typed more than two characters. Use the enter key to select a suggestion. Touch device users, explore by touch or with swipe gestures.</div>
      <div class="ons-autosuggest-input__status ons-u-vh ons-js-autosuggest-aria-status" aria-live="assertive" role="status" tabindex="-1"></div>
    </div>
    <a href="#0" class="ons-js-address-manual-btn ons-u-mt-s ons-u-dib">Manually enter address</a>
  </div>
</div>
{% from "components/address-input/_macro.njk" import onsAddressInput %}

{{ onsAddressInput({
    "id": "address",
    "dontWrap": true,
    "label": {
        "text": "Enter address or postcode and select from results",
        "id": "address-label"
    },
    "isEditable": true,
    "mandatory": true,
    "APIDomain": "https://whitelodge-eq-ai-api.census-gcp.onsdigital.uk",
    'APIDomainBearerToken': "some_token",
    "instructions": "Use up and down keys to navigate suggestions once you\'ve typed more than two characters. Use the enter key to select a suggestion. Touch device users, explore by touch or with swipe gestures.",
    "ariaYouHaveSelected": "You have selected",
    "ariaMinChars": "Enter 3 or more characters for suggestions.",
    "ariaResultsLabel": "Address suggestions",
    "ariaOneResult": "There is one suggestion available.",
    "ariaNResults": "There are {n} suggestions available.",
    "ariaLimitedResults": "Results have been limited to 10 suggestions. Type more characters to improve your search",
    "ariaGroupedResults": "There are {n} for {x}",
    "groupCount": "{n} addresses",
    "moreResults": "Enter more of the address to improve results",
    "resultsTitle": "Select an address",
    "noResults": "No results found. Try entering a different part of the address",
    "tooManyResults": "{n} results found. Enter more of the address to improve results",
    "typeMore": "Enter more of the address to get results",
    "autocomplete": "new-password",
    "errorTitle": "There is a problem with your answer",
    "errorMessageEnter": "Enter an address",
    "errorMessageSelect": "Select an address",
    "errorMessageAPI": "Sorry, there is a problem loading addresses.",
    "errorMessageAPILinkText": "Enter address manually",
    "options": {
        "regionCode": "gb-eng",
        "addressType": "residential"
    },
    "line1": {
        "label": "Address line 1"
    },
    "line2": {
        "label": "Address line 2"
    },
    "town": {
        "label": "Town or city"
    },
    "postcode": {
        "label": "Postcode"
    },
    "searchButton": "Search for an address",
    "manualLinkText": "Manually enter address"
}) }}
Name Type Required Description
id string true ID for the fieldset. This is used to automatically generate IDs and names for each field if one isn’t specified
classes string false Classes to add to the fieldset
label Label (ref) false Settings for the input label. for will automatically be set to match the input id
legend string true Legend text for the address input
legendClasses string false Classes to apply to the legend
dontWrap boolean false Set to true to prevent the address fields from being wrapped in a fieldset
isEditable boolean true Used with the address macro to invoke population of manual fields upon selection of suggestion
manualEntry boolean false Only display manual fields and do not invoke autosuggest/api functionality
mandatory boolean false Set the autosuggest input to be mandatory and use client side validation for empty form submission
APIDomain string false Set an api domain when using an external API to suggest results
APIDomainBearerToken string false Set a bearer token for api authorization on the AIMS address api.
instructions string true Instructions on how to use the autosuggest that will be read out by screen readers
ariaYouHaveSelected string true Aria message to tell the user that they have selected an answer
ariaMinChars string true Aria message to tell the user how many characters they need to enter before autosuggest will start
ariaResultsLabel string true Aria message to tell the user that suggestions are available
ariaOneResult string true Aria message to tell the user there is only one suggestion left
ariaNResults string true Aria message to tell the user how many suggestions are left
ariaLimitedResults string true Aria message to tell the user if the results have been limited and what they are limited to
ariaGroupedResults string true Aria message to tell the user about a grouped result, for example, There are {n} for {x}
groupCount string true Aria message to tell the user the number of addresses in a group, for example, {n} addresses
moreResults string true Aria message to tell the user to continue to type to refine suggestions
noResults string true message to tell the user there are no results
tooManyResults string true message to tell the user there are too many results to display and the user should refine the search
typeMore string true message to encourage the user to enter more characters to get suggestions
resultsTitle string true Title of results to be displayed on screen at the top of the results
errorTitle string false Error message title displayed in the error panel
errorMessageEnter string false Error message description displayed in the error panel when the input is empty
errorMessageSelect string false Error message description displayed in the error panel when a suggestion has not been selected
errorMessageAPI string false Error message displayed when the API has failed during a search
errorMessageAPILinkText string false Link text used to toggle to a manual mode when using the address macro
manualLink string false url for the link displayed below the input
manualLinkText string false Link text shown for the manual link. If using the editable address, including this parameter will toggle the mode to manual entry
options Object<Options> false Option to provide key value pairs that will be added as data attributes to the component that will be added as parameters to the address index api
organisation Object<AddressField> false Configuration for the organisation field.
line1 Object<AddressField> false Configuration for the line1 field
line2 Object<AddressField> false Configuration for the line2 field
town Object<AddressField> false Configuration for the town field
county Object<AddressField> false Configuration for the county field
postcode Object<AddressField> false Configuration for the postcode field
uprn Object<AddressField> false Configuration for the uprn field
mutuallyExclusive MutuallyExclusive (ref) false Configuration object if this is a mutually exclusive input
legend string Only if mutuallyExclusive is set Text content for the legend
legendClasses string false Classes for the legend
error Error (ref) false Configuration for validation errors
name string false The name of the input
value string | number false The value to set the input to
attributes object false HTML attributes (for example, data attributes) to add to the input

Options

Name Type Required Description
regionCode string false Sets the provided region code, for example, en-gb
addressType string false Sets the provided address type, for example, residential
oneYearAgo string false If “true” will set a query parameter of epoch=75

AddressField

Name Type Required Description
id string false ID for the field
name string false Sets the name attribute on the field
label.text string true The label for the input
value string false The value for the input
error Error (ref) false Configuration for validation errors
{% from "components/fieldset/_macro.njk" import onsFieldset %}
{% from "components/autosuggest/_macro.njk" import onsAutosuggest %}
{% from "components/input/_macro.njk" import onsInput %}

{% macro onsAddressInput(params) %}
   {% set fields %}
        <div id="address" class="ons-field ons-address-input {% if not params.manualEntry %}ons-address-input--search ons-js-address-autosuggest{% endif %}">
            {% if params.isEditable == true or params.manualEntry %}
                {% if not params.manualEntry %}<div class="ons-js-address-input__manual ons-u-db-no-js_enabled">{% endif %}
                    {% if params.organisation is defined and params.organisation %}
                        {{
                            onsInput({
                                "id": params.id + "-organisation",
                                "label": {
                                    "text": params.organisation.label
                                },
                                "classes": "ons-js-address-organisation",
                                "width": "20@m",
                                "name": params.id + "-organisation",
                                "error": params.organisation.error
                            })
                        }}
                    {% endif %}
                    {% if params.line1 is defined and params.line1 %}
                        {{
                            onsInput({
                                "id": params.id + "-line1",
                                "value": params.line1.value,
                                "label": {
                                    "text": params.line1.label
                                },
                                "classes": "ons-js-address-line1",
                                "width": "20@m",
                                "name": params.id + "-line1",
                                "error": params.line1.error
                            })
                        }}
                    {% endif %}
                    {% if params.line2 is defined and params.line2 %}
                        {{
                            onsInput({
                                "id": params.id + "-line2",
                                "value": params.line2.value,
                                "label": {
                                    "text": params.line2.label
                                },
                                "classes": "ons-js-address-line2",
                                "width": "20@m",
                                "name": params.id + "-line2",
                                "error": params.line2.error
                            })
                        }}
                    {% endif %}
                    {% if params.town is defined and params.town %}
                        {{
                            onsInput({
                                "id": params.id + "-town",
                                "value": params.town.value,
                                "label": {
                                    "text": params.town.label
                                },
                                "classes": "ons-js-address-town",
                                "name": params.id + "-town",
                                "error": params.town.error
                            })
                        }}
                    {% endif %}
                    {% if params.postcode is defined and params.postcode %}
                        {{
                            onsInput({
                                "id": params.id + "-postcode",
                                "value": params.postcode.value,
                                "label": {
                                    "text": params.postcode.label
                                },
                                "classes": "ons-js-address-postcode",
                                "width": "7",
                                "name": params.id + "-postcode",
                                "error": params.postcode.error
                            })
                        }}
                    {% endif %}
                {% if not params.manualEntry %}
                        <div class="ons-u-mt-s">
                            <a href="#0" class="ons-js-address-search-btn ons-u-db-no-js_disabled">{{ params.searchButton }}</a>
                        </div>
                    </div>
                {% endif %}
            {% endif %}

            {% if params.uprn is defined and params.uprn and params.uprn.value is defined and params.uprn.value %}
                {% set uprnValue = params.uprn.value %}
            {% else %}
                {% set uprnValue = '' %}
            {% endif %}

            {{
                onsInput({
                    "id": params.id + "-uprn",
                    "classes": "ons-js-hidden-uprn ons-u-d-no",
                    "type": "hidden",
                    "name": params.id + "-uprn",
                    "value": uprnValue
                })
            }}
            {% if not params.manualEntry %}
                <div class="ons-js-address-input__search{% if params.isEditable == true %} ons-u-db-no-js_disabled{% endif %}">
                    {{
                        onsAutosuggest({
                            "id": params.id + "-autosuggest",
                            "classes": "ons-address-input__autosuggest ons-u-mb-no",
                            "width": "50",
                            "label": {
                                "text": params.label.text,
                                "id": params.label.id,
                                "classes": "ons-js-autosuggest-label"
                            },
                            "value": params.value,
                            "attributes": params.attributes,
                            "error": params.error,
                            "name": params.name,
                            "mutuallyExclusive": params.mutuallyExclusive,
                            "externalInitialiser": true,
                            "APIDomain": params.APIDomain,
                            "APIDomainBearerToken": params.APIDomainBearerToken,
                            "APIManualQueryParams": params.APIManualQueryParams,
                            "allowMultiple": params.allowMultiple,
                            "mandatory": params.mandatory,
                            "instructions": params.instructions,
                            "autocomplete": params.autocomplete,
                            "isEditable": params.isEditable,
                            "ariaYouHaveSelected": params.ariaYouHaveSelected,
                            "ariaMinChars": params.ariaMinChars,
                            "ariaResultsLabel": params.ariaResultsLabel,
                            "ariaOneResult": params.ariaOneResult,
                            "ariaNResults": params.ariaNResults,
                            "ariaLimitedResults": params.ariaLimitedResults,
                            "ariaGroupedResults": params.ariaGroupedResults,
                            "groupCount": params.groupCount,
                            "moreResults": params.moreResults,
                            "tooManyResults": params.tooManyResults,
                            "resultsTitle": params.resultsTitle,
                            "noResults": params.noResults,
                            "typeMore": params.typeMore,
                            "errorTitle": params.errorTitle,
                            "errorMessageEnter": params.errorMessageEnter,
                            "errorMessageSelect": params.errorMessageSelect,
                            "errorMessageAPI": params.errorMessageAPI,
                            "errorMessageAPILinkText": params.errorMessageAPILinkText,
                            "options": params.options,
                            "manualLink": params.manualLink,
                            "manualLinkText": params.manualLinkText
                        })
                    }}
                    {% if params.manualLinkText %}
                        <a href="{{ params.manualLink | default('#0') }}" class="ons-js-address-manual-btn ons-u-mt-s ons-u-dib">{{ params.manualLinkText }}</a>
                    {% endif %}
                </div>
            {% endif %}
        </div>
    {% endset %}

    {% if params.dontWrap is defined and params.dontWrap %}
        {{ fields | safe }}
    {% else %}
        {% call onsFieldset({
            "id": params.id,
            "classes": params.classes,
            "legend": params.legend,
            "legendClasses": params.legendClasses
        }) %}
            {{ fields | safe }}
        {% endcall %}
    {% endif %}
{% endmacro %}

Using the API

The ONS Address Index API uses a JSON Web Token (JWT) to allow for the transfer of data. Email the Design System working group at ons.design.system@ons.gov.uk to let them know your requirements and to set up trusted domains for the API.

Set the values for the parameters APIDomain and APIDomainBearerToken to allow queries to be passed to the API. Also include the parameter "externalInitialiser": true to bypass the default autosuggest methods.

A query is sent to the relevant API endpoint after three characters have been entered into the address finder input. The API will return addresses in groups when the user searches by postcode. If the user searches by another part of the address, the API will return the best matches for that search term.

Validation

The address autosuggest provides client-side validation when the parameter mandatory: true is used. The validation checks if the user has:

  • entered something in the address finder input
  • selected an address from the results
  • selected an address from the results and then edited it in the address finder input (non-editable variant only)

You will need to include parameters for these error messages:

If the address finder input is empty

Use “Enter an address” for the parameter: errorMessageEnter

If no address is selected from the results

​​Use “Select an address” for the parameter: errorMessageSelect

If a selected address has been edited in the address finder input

​​Use “Select an address” for the parameter: errorMessageSelect

Important information:
If you are using the editable address finder or manual address entry variants, you will need to check the address using server-side validation.

Other API messages

Use the following error messages to improve the address finder results and deal with any loading issues:

If no results are found

Use “No results found. Try entering a different part of the address” for the parameter: noResults.

If the postcode returns too many results

Use “[number of addresses] results found. Enter more of the address to improve results” for the parameter: tooManyResults.

If more of the address or postcode are needed to get results

Use “Enter more of the address to get results” for the parameter: typeMore.

If there is an error with the API during use of the editable address finder

Use “Sorry, there is a problem loading addresses. Enter address manually” for the parameters: errorMessageAPI and errorMessageAPILinkText.

If the API is down before use of the editable address finder

There is a status check when the page loads and initialises the component. If the API is down, a set of fields will allow the user to enter an address manually. This also happens if JavaScript is turned off.

If the API is down before or during use of the non-editable address finder

The input will be disabled and an error message shown.

Use “Sorry, there is a problem. We are working to fix it. Please try again later or contact us for more help.” for the parameters: errorMessageAPI and errorMessageAPILinkText.

How to use this component for manual address entry

Include the parameter manualEntry: true. You will also need to set other parameters as shown in the Nunjucks options in the following example.

<div id="address" class="ons-field ons-address-input ">
  <div class="ons-field">
    <label class="ons-label  " for="address-line1">Address line 1
    </label>
    <input type="text" id="address-line1" class="ons-input ons-input--text ons-input-type__input ons-js-address-line1 ons-input--w-20@m" name="address-line1" />
  </div>
  <div class="ons-field">
    <label class="ons-label  " for="address-line2">Address line 2
    </label>
    <input type="text" id="address-line2" class="ons-input ons-input--text ons-input-type__input ons-js-address-line2 ons-input--w-20@m" name="address-line2" />
  </div>
  <div class="ons-field">
    <label class="ons-label  " for="address-town">Town or city
    </label>
    <input type="text" id="address-town" class="ons-input ons-input--text ons-input-type__input ons-js-address-town" name="address-town" />
  </div>
  <div class="ons-field">
    <label class="ons-label  " for="address-postcode">Postcode
    </label>
    <input type="text" id="address-postcode" class="ons-input ons-input--text ons-input-type__input ons-js-address-postcode ons-input--w-7" name="address-postcode" />
  </div>
  <input type="hidden" id="address-uprn" class="ons-input ons-input--text ons-input-type__input ons-js-hidden-uprn ons-u-d-no" name="address-uprn" />
</div>
{% from "components/address-input/_macro.njk" import onsAddressInput %}

{{ onsAddressInput({
    "id": "address",
    "dontWrap": true,
    "manualEntry": true,
    "label": {
        "text": "Enter address or postcode and select from results",
        "id": "address-label"
    },
    "line1": {
        "label": "Address line 1"
    },
    "line2": {
        "label": "Address line 2"
    },
    "town": {
        "label": "Town or city"
    },
    "postcode": {
        "label": "Postcode"
    }
}) }}
Name Type Required Description
id string true ID for the fieldset. This is used to automatically generate IDs and names for each field if one isn’t specified
classes string false Classes to add to the fieldset
label Label (ref) false Settings for the input label. for will automatically be set to match the input id
legend string true Legend text for the address input
legendClasses string false Classes to apply to the legend
dontWrap boolean false Set to true to prevent the address fields from being wrapped in a fieldset
isEditable boolean true Used with the address macro to invoke population of manual fields upon selection of suggestion
manualEntry boolean false Only display manual fields and do not invoke autosuggest/api functionality
mandatory boolean false Set the autosuggest input to be mandatory and use client side validation for empty form submission
APIDomain string false Set an api domain when using an external API to suggest results
APIDomainBearerToken string false Set a bearer token for api authorization on the AIMS address api.
instructions string true Instructions on how to use the autosuggest that will be read out by screen readers
ariaYouHaveSelected string true Aria message to tell the user that they have selected an answer
ariaMinChars string true Aria message to tell the user how many characters they need to enter before autosuggest will start
ariaResultsLabel string true Aria message to tell the user that suggestions are available
ariaOneResult string true Aria message to tell the user there is only one suggestion left
ariaNResults string true Aria message to tell the user how many suggestions are left
ariaLimitedResults string true Aria message to tell the user if the results have been limited and what they are limited to
ariaGroupedResults string true Aria message to tell the user about a grouped result, for example, There are {n} for {x}
groupCount string true Aria message to tell the user the number of addresses in a group, for example, {n} addresses
moreResults string true Aria message to tell the user to continue to type to refine suggestions
noResults string true message to tell the user there are no results
tooManyResults string true message to tell the user there are too many results to display and the user should refine the search
typeMore string true message to encourage the user to enter more characters to get suggestions
resultsTitle string true Title of results to be displayed on screen at the top of the results
errorTitle string false Error message title displayed in the error panel
errorMessageEnter string false Error message description displayed in the error panel when the input is empty
errorMessageSelect string false Error message description displayed in the error panel when a suggestion has not been selected
errorMessageAPI string false Error message displayed when the API has failed during a search
errorMessageAPILinkText string false Link text used to toggle to a manual mode when using the address macro
manualLink string false url for the link displayed below the input
manualLinkText string false Link text shown for the manual link. If using the editable address, including this parameter will toggle the mode to manual entry
options Object<Options> false Option to provide key value pairs that will be added as data attributes to the component that will be added as parameters to the address index api
organisation Object<AddressField> false Configuration for the organisation field.
line1 Object<AddressField> false Configuration for the line1 field
line2 Object<AddressField> false Configuration for the line2 field
town Object<AddressField> false Configuration for the town field
county Object<AddressField> false Configuration for the county field
postcode Object<AddressField> false Configuration for the postcode field
uprn Object<AddressField> false Configuration for the uprn field
mutuallyExclusive MutuallyExclusive (ref) false Configuration object if this is a mutually exclusive input
legend string Only if mutuallyExclusive is set Text content for the legend
legendClasses string false Classes for the legend
error Error (ref) false Configuration for validation errors
name string false The name of the input
value string | number false The value to set the input to
attributes object false HTML attributes (for example, data attributes) to add to the input

Options

Name Type Required Description
regionCode string false Sets the provided region code, for example, en-gb
addressType string false Sets the provided address type, for example, residential
oneYearAgo string false If “true” will set a query parameter of epoch=75

AddressField

Name Type Required Description
id string false ID for the field
name string false Sets the name attribute on the field
label.text string true The label for the input
value string false The value for the input
error Error (ref) false Configuration for validation errors
{% from "components/fieldset/_macro.njk" import onsFieldset %}
{% from "components/autosuggest/_macro.njk" import onsAutosuggest %}
{% from "components/input/_macro.njk" import onsInput %}

{% macro onsAddressInput(params) %}
   {% set fields %}
        <div id="address" class="ons-field ons-address-input {% if not params.manualEntry %}ons-address-input--search ons-js-address-autosuggest{% endif %}">
            {% if params.isEditable == true or params.manualEntry %}
                {% if not params.manualEntry %}<div class="ons-js-address-input__manual ons-u-db-no-js_enabled">{% endif %}
                    {% if params.organisation is defined and params.organisation %}
                        {{
                            onsInput({
                                "id": params.id + "-organisation",
                                "label": {
                                    "text": params.organisation.label
                                },
                                "classes": "ons-js-address-organisation",
                                "width": "20@m",
                                "name": params.id + "-organisation",
                                "error": params.organisation.error
                            })
                        }}
                    {% endif %}
                    {% if params.line1 is defined and params.line1 %}
                        {{
                            onsInput({
                                "id": params.id + "-line1",
                                "value": params.line1.value,
                                "label": {
                                    "text": params.line1.label
                                },
                                "classes": "ons-js-address-line1",
                                "width": "20@m",
                                "name": params.id + "-line1",
                                "error": params.line1.error
                            })
                        }}
                    {% endif %}
                    {% if params.line2 is defined and params.line2 %}
                        {{
                            onsInput({
                                "id": params.id + "-line2",
                                "value": params.line2.value,
                                "label": {
                                    "text": params.line2.label
                                },
                                "classes": "ons-js-address-line2",
                                "width": "20@m",
                                "name": params.id + "-line2",
                                "error": params.line2.error
                            })
                        }}
                    {% endif %}
                    {% if params.town is defined and params.town %}
                        {{
                            onsInput({
                                "id": params.id + "-town",
                                "value": params.town.value,
                                "label": {
                                    "text": params.town.label
                                },
                                "classes": "ons-js-address-town",
                                "name": params.id + "-town",
                                "error": params.town.error
                            })
                        }}
                    {% endif %}
                    {% if params.postcode is defined and params.postcode %}
                        {{
                            onsInput({
                                "id": params.id + "-postcode",
                                "value": params.postcode.value,
                                "label": {
                                    "text": params.postcode.label
                                },
                                "classes": "ons-js-address-postcode",
                                "width": "7",
                                "name": params.id + "-postcode",
                                "error": params.postcode.error
                            })
                        }}
                    {% endif %}
                {% if not params.manualEntry %}
                        <div class="ons-u-mt-s">
                            <a href="#0" class="ons-js-address-search-btn ons-u-db-no-js_disabled">{{ params.searchButton }}</a>
                        </div>
                    </div>
                {% endif %}
            {% endif %}

            {% if params.uprn is defined and params.uprn and params.uprn.value is defined and params.uprn.value %}
                {% set uprnValue = params.uprn.value %}
            {% else %}
                {% set uprnValue = '' %}
            {% endif %}

            {{
                onsInput({
                    "id": params.id + "-uprn",
                    "classes": "ons-js-hidden-uprn ons-u-d-no",
                    "type": "hidden",
                    "name": params.id + "-uprn",
                    "value": uprnValue
                })
            }}
            {% if not params.manualEntry %}
                <div class="ons-js-address-input__search{% if params.isEditable == true %} ons-u-db-no-js_disabled{% endif %}">
                    {{
                        onsAutosuggest({
                            "id": params.id + "-autosuggest",
                            "classes": "ons-address-input__autosuggest ons-u-mb-no",
                            "width": "50",
                            "label": {
                                "text": params.label.text,
                                "id": params.label.id,
                                "classes": "ons-js-autosuggest-label"
                            },
                            "value": params.value,
                            "attributes": params.attributes,
                            "error": params.error,
                            "name": params.name,
                            "mutuallyExclusive": params.mutuallyExclusive,
                            "externalInitialiser": true,
                            "APIDomain": params.APIDomain,
                            "APIDomainBearerToken": params.APIDomainBearerToken,
                            "APIManualQueryParams": params.APIManualQueryParams,
                            "allowMultiple": params.allowMultiple,
                            "mandatory": params.mandatory,
                            "instructions": params.instructions,
                            "autocomplete": params.autocomplete,
                            "isEditable": params.isEditable,
                            "ariaYouHaveSelected": params.ariaYouHaveSelected,
                            "ariaMinChars": params.ariaMinChars,
                            "ariaResultsLabel": params.ariaResultsLabel,
                            "ariaOneResult": params.ariaOneResult,
                            "ariaNResults": params.ariaNResults,
                            "ariaLimitedResults": params.ariaLimitedResults,
                            "ariaGroupedResults": params.ariaGroupedResults,
                            "groupCount": params.groupCount,
                            "moreResults": params.moreResults,
                            "tooManyResults": params.tooManyResults,
                            "resultsTitle": params.resultsTitle,
                            "noResults": params.noResults,
                            "typeMore": params.typeMore,
                            "errorTitle": params.errorTitle,
                            "errorMessageEnter": params.errorMessageEnter,
                            "errorMessageSelect": params.errorMessageSelect,
                            "errorMessageAPI": params.errorMessageAPI,
                            "errorMessageAPILinkText": params.errorMessageAPILinkText,
                            "options": params.options,
                            "manualLink": params.manualLink,
                            "manualLinkText": params.manualLinkText
                        })
                    }}
                    {% if params.manualLinkText %}
                        <a href="{{ params.manualLink | default('#0') }}" class="ons-js-address-manual-btn ons-u-mt-s ons-u-dib">{{ params.manualLinkText }}</a>
                    {% endif %}
                </div>
            {% endif %}
        </div>
    {% endset %}

    {% if params.dontWrap is defined and params.dontWrap %}
        {{ fields | safe }}
    {% else %}
        {% call onsFieldset({
            "id": params.id,
            "classes": params.classes,
            "legend": params.legend,
            "legendClasses": params.legendClasses
        }) %}
            {{ fields | safe }}
        {% endcall %}
    {% endif %}
{% endmacro %}

Help improve this component

Let us know how we could improve this component or share your user research findings. Discuss the ‘address input’ component on GitHub