Options
All
  • Public
  • Public/Protected
  • All
Menu

@ideal-postcodes/postcode-lookup

Ideal Postcodes Postcode Lookup

Add UK Postcode Lookup and address search to a webpage in moments

npm version npm bundle size

@ideal-postcodes/postcode-lookup is a JavaScript library that delivers Postcode Lookup and address search functionality on a webpage.

This package should be consumed by a bundler or transpiler (e.g. webpack, parcel, rollup) for minification, module resolution and specific browser support.

For a pre-bundled version of postcode-lookup (minified, transpiled, polyfilled, etc) that can immediately be dropped on a webpage, use postcode-lookup-bundled.

Postcode Lookup Demo

Links

Example Setup

Webpack Status

Parcel Status

Rollup Status

Related Projects

How it Works

  1. Add the library to your project. Your page should have pre-existing address input fields as well as a parent container for Postcode Lookup
  2. Run initialisation code providing a reference to a parent container and any other configuration
  3. By default, Postcode Lookup will check if your key is usable. If not, setup will halt and Postcode Lookup will not bind. Set checkKey to false to disable this step. Use the onFailedCheck callback to update your page if the check fails.
  4. Postcode Lookup then creates an input field and button to perform postcode and address lookups in the parent container
  5. If a matching postcode or address is found, a dropdown <select> menu is created in the parent container and the selected address is piped into the form
  6. If no matching postcode/address is found or an error occurred, Postcode Lookup will append an appropriate message

Documentation

Configuration & Usage

Install

Add postcode-lookup to your project via npm

npm install @ideal-postcodes/postcode-lookup

Instantiate

Create postcode search tools using PostcodeLookup.setup.

import { PostcodeLookup } from "@ideal-postcodes/postcode-lookup";

PostcodeLookup.setup({
  // *Required* Insert your API Key
  apiKey: "iddqd",

  // *Required* Specify the target element with ID `postcode_lookup` to house the search tools
  context: "#postcode_lookup",

  // Configures how address results are sent to inputs with IDs `line_1`, `line_2`, `line_3`, `post_town` and `postcode`.
  outputFields: {
    line_1: "#line_1",
    line_2: "#line_2",
    line_3: "#line_3",
    post_town: "#post_town",
    postcode: "#postcode",
  }
});

Configuration options

Detach

Remove all search tools created via PostcodeLookup.controllers and #removeAll().

PostcodeLookup.controllers.forEach(c => c.removeAll());

Or store a reference to Postcode Lookup and removeAll().

PostcodeLookup.removeAll();

Populating your Address Fields

Postcode Lookup expects you to have your own address inputs on the page ready to be populated.

When an address is select, the addressing data will be piped to those address inputs designated in outputFields. For instance line_1: "#line_1" will write Address Line One data to a HTML element with ID line_1.

Assigning the 3 address line, post town and postcode fields, is all addressing information required to identify a UK premise. You may extract more data for an address by passing more properties into the outputFields configuration object.

The configuration attributes for outputFields matches the Address response object. E.g. street name can be populated can be populated using the thoroughfare attribute. A list of address attributes provided by the API can be found at @ideal-postcodes/api-typings.

More information on addressing data can be found on our data documentation.

For more sophistated behaviour when a user selects an address, you can hook into the onAddressSelected callback and implement customised behaviour there.

Setup Options

The Postcode Lookup configuration object is passed in as the first argument when calling setup().

Below is a list of the primary, mainly optional, parameters you can use to style or modify the postcode and address search elements generated by the library.

A complete list of configuration options can be found in the library documentation.

Default values are documented here.

Required Config

apiKey

API Key associated with your account. Typically begins ak_

context

DOM context in which to inject Postcode Lookup tools.

You will need to provide a HTMLElement, typically a <div> to house the postcode lookup tools. This can be referenced using a query selector (e.g. "#postcode_lookup") or a direct reference to the HTMLElement (e.g. document.getElementById("postcode_lookup")).

outputFields

Specify where to send address data given a selected address. A object which maps an address attribute to the CSS selector of an input field or HTMLElement like HTMLInputElement or HTMLTextAreaElement.

{
  line_1: "#line_1",
  line_2: "#line_2",
  line_3: "input[name='line_3']",
  post_town: document.getElementById("post_town"),
  postcode: document.getElementById("postcode")
}

The configuration attributes for outputFields matches the Address response object. E.g. street name can be populated can be populated using the thoroughfare attribute. A list of address attributes provided by the API can be found at @ideal-postcodes/api-typings.

More complex, dynamic assignment can be performed using the onAddressSelected callback.

Output fields assigned with a query selector are evaluated lazily (i.e. when an address attribute needs to be piped to a field).

Styling

Custom styling can be achieved by applying your own CSS classes to each HTML element created by Postcode Lookup:

You may also inject style attributes into the HTML elements themselves:

HTML elements created by Postcode Lookup can be configured with their own IDs:

WAI-ARIA

Postcode Lookup exposes some accessibility settings.

The following WAI-ARIA components of Postcode Lookups have WAI-ARIA attributes enabled

  • Message box has aria-role is set to alert to immediately notify the user
  • Postcode Lookup container has aria-live enabled to alert users to updates in the address dropdown
  • Search input accepts an Enter/Return key to trigger an address search without submitting the form

Configure Behaviour

checkKey

If enabled, the plugin will check if the key is in a usable state before initialising itself.

The check can fail if:

  • Your key has no remaining lookups
  • Your key has run into its lookup limit for the day
  • Your key is requested from a URL which is not on your whitelist
  • The user seeking to use the key has exceeded their limit for the day

If the check fails, the plugin will not initialise. You can use the onFailedCheck callback to customise your response to a failed check.

Defauts to true.

strictlyPostcodes

If enabled, any lookups which do not validate as a standard postcode will be passed to the address search API instead.

You can configure address search by passing in a a configuration object. Currently this configuration object only accepts one parameter: limit. Limit determines the maximum number of search results to return. (Default is 10, maximum is 100).

Defaults to true.

titleizePostTown

Title case the post town (true) or keep in all caps (false). All caps post town is recommended by Royal Mail's good addressing guidelines.

If enabled, any lookups which do not validate as a standard postcode will be passed to the address search API instead.

Defaults to true.

removeOrganisation

If set to true, organisation name will be removed from the address.

Note that addresses which are exclusively an organisation name will not result in the organisation name being removed as this will result in no premise identifier.

Defaults to false.

selectSinglePremise

If set to true, the premise will be immediately populated if the result set of an address or postcode search contains a single premise.

Note the address selection box will not appear.

Note that onAddressSelected callback is still invoked in this instance. To detect whether the last address search yielded a single premise, the controller instance data property will have a single element. i.e. this.data.length === 1.

Defaults to false.

hide

Accepts an array of HTMLElements or CSS selectors. E.g.

{
  hide: [
    "#line_1",
    document.getElementById("line_2"),
    document.querySelector("#line_3")],
  ],
}

When enabled, the HTMLElements supplied in hide are hidden with display: none; when Postcode Lookup successfully initialises. These elements will be subsequently unhidden if an address is selected or the user opts to manually input an address.

Enabling this feature will also create a clickable element in the Postcode Lookup container, which provides users the option to manually input an address. You may provide your own clickable element with unhide or customise the clickable element with msgUnhide and unhideClass.

Defaults to [].

autocomplete

Sets the autocomplete= attribute of the input element. Setting this attribute aims to prevent some browsers (particularly Chrome) from providing a clashing autofill overlay.

The best practice for this attribute breaks over time (see https://stackoverflow.com/questions/15738259/disabling-chrome-autofill) and is specific to different forms. If you are observing chrome's autofill clashing on your form, update this attribute to the best practice du jour.

Defaults to "none".

Message Customisation

placeholder

Sets the default placeholder label on input field.

Defaults to "Search your postcode".

buttonLabel

Sets the label on the button.

Defaults to "Find my Address".

msgSelect

Sets the topline message for the dropdown menu.

Defaults to "Please select your address".

msgUnhide

Sets the message on the clickable HTMLElement that unhides any fields defined in hide.

Defaults to "Enter address manually".

Custom Elements

If you wish to bring your own HTML elements to function as the postcode input, button, etc.

input

If you wish to use your own input field, you can specify the unique css selector for that field here. E.g. "#myCustomPostcodeLookupField". Please note that all input field parameters like inputClass and placeholder will be ignored. It will be up to you to implement styling and any desired behaviours in your input field.

button

If you wish to use your own lookup button, you can specify the unique css selector for that field here. E.g. "#customLookupTrigger". Any "clickable" DOM element will work as a valid "button" to trigger a lookup. Please note that all other parameters like button_disabled_message will be ignored. It will be up to you to implement styling and any desired behaviours for your lookup button.

selectContainer

Specify a query selector (string) or (HTMLElement) custom container for the HTMLSelectElement which will display address suggestions.

The default select container is hidden using display: none; and unhidden by setting display to "". A custom selectContainer will not have display: none; initially applied but it will be unhidden by setting display to "". To hide your selectContainer to also be initially hidden apply style.display = "none" or style="display: none;" to your container element.

message

Specify a query selector (string) or (HTMLParagraphElement) as a custom container for messages.

If a message or error prompt needs to be shown (e.g. postcode not found) a <p>, the message is inserted into the specified container.

This container is hidden and unhidden using display: none. However it is not initially hidden. To hide your message container, apply style.display = "none" or style="display: none;" to your container element.

unhide

Specify a query selector (string) or (HTMLElement) as a custom clickable element to unhide and form fields configured with hide.

Lifecycle Callbacks

Postcode Lookup also provides callbacks which let you hook into specific events in the Controller lifecyle.

onLoaded

A function invoked once the plugin has initialised.

onRemove

A function invoked when a plugin instance is detatched using removeAll.

onButtonTrigger

A function invoked when the search button is triggered (i.e. clicked, pressed).

onFailedCheck

A function invoked if checkKey is enabled and the API Key check fails.

onSearchCompleted

A function invoked as soon as an address search successfully completes.

Note, this is also invoked on all errors including:

  • 404-type errors such as "postcode not found" returning [] as the list of addresses.
  • Other 4XX and 5XX errors where the error argument will be available

onAddressesRetrieved

A function invoked when a successful API request is made and at least 1 address is returned. This property takes a function, which accepts an addresses argument representing the addresses returned by the API.

onAddressSelected

A function invoked when the user selects an address option on the plugin's dropdown menu. This property takes a function, which accepts a address argument representing the full details of the selected address.

onAddressPopulated

A function invoked after a selected address has been applied to output fields.

onSelectCreated

A function invoked when addresses have been retrieved and the dropdown has been inserted into the DOM.

onSelectRemoved

A function invoked when select element is removed from the DOM as user attempts to search another address or postcode.

onLookupTriggered

A function invoked when the user triggers a lookup (e.g. by clicking the button). This callback is invoked before any request is made to the API.

onSearchError

A function invoked when the API returns an error. This property takes a function, which accepts an error argument representing the error returned by the API.

Examples of errors includes "lookup balance exhausted" and "lookup limit reached" errors.

onUnhide

A function invoked when fields defined in hide are unhidden. Useful for further customisation when address fields are finally presented to the user.

This function must be idempotent as it can be invoked multiple times during both hidden and unhidden states.

shouldLookupTrigger

A function invoked just before the plugin triggers a lookup when the search button is clicked. If false is returned, the search API request is aborted.

Scoping

It is possible to narrow the scope in which the Postcode Lookup Controller can operate. For instance, if you wish for a Controller to just operate on a billing address form and another Controller to operate only on a shipping address form, you can use the scope or outputScope options to do this.

scope

Scopes the operable area of the DOM using a query selector or HTMLElement.

By assigning a scope, the Controller will only attempt to resolve for HTMLElements within that scope.

Defaults to window.document.

outputScope

Scopes the operable area of the DOM using a query selector or HTMLElement when resolving output fields.

Defaults to the scope of the Controller.