• Molecule
  • CORE COMPONENT
  • Taxonomic name: M-PREDICTIVE-SEARCH
  • Extension: FORMS-EXTENDED-A
  • Added on: v3.1.0 (08/12/17)
  • Updated on: v5.11.0 (07/09/21)

Predictive search

Provide contextual value suggestions as the user types, which the user can then select from


Design and usage

The default version of this component pushes down the content on the page when it is opened, but an additional variant is available which will allow the open component to overlay other content on the page instead - see 'overlay variant' example below.

  • Results can be grouped into categories which display with a title and optional icon.
  • Works with a static list of option and with AJAX requests.
  • When categorising search results limit results to for each category to a maximum of 5 items.
  • Aria-invalid must be used to indicate when an error has occurred with this element.
  • Aria-describedby must be used to link any help, instructional and/or error text with the element/form fields.

Examples

Predictive search options

Interactive example

Code example

<div class="m-form-row [ Modifier ]">
	<label class="a-label" for="test-text-a">Which country did you last visit?</label>
	<div class="m-form-row__content">
		<input type="text" id="..." name="..." class="a-textbox [ Modifier ]" data-module="m-predictive-search" />
	</div>
</div>

For further information on how to fully setup the predictive search component see the developer notes.

Valid predictive search

Interactive example

Code example

<div class="m-form-row [ Modifier ]">
	<label class="a-label" for="test-text-a">Which country did you last visit?</label>
	<p class="m-form-row__validation-message">...</p>
	<div class="m-form-row__content">
		<input type="text" id="..." name="..." class="a-textbox [ Modifier ]" data-module="m-predictive-search" />
	</div>
</div>

Errored predictive search

Interactive example

Code example

<div class="m-form-row [ Modifier ]">
	<label class="a-label" for="test-text-a">Which country did you last visit?</label>
	<p class="m-form-row__error-message" id="..."><span class="u-hidden--visually">Error: </span>...</p>
	<div class="m-form-row__content">
		<input type="text" id="..." name="..." class="a-textbox [ Modifier ]" data-module="m-predictive-search" aria-invalid="true" aria-describedby="..." />
	</div>
</div>

Disabled predictive search

Interactive example

Code example

<div class="m-form-row is-disabled [ Modifier ]">
	<label class="a-label" for="test-text-a">Which country did you last visit?</label>
	<div class="m-form-row__content">
		<input type="text" id="..." name="..." class="a-textbox [ Modifier ]" disabled data-module="m-predictive-search" />
	</div>
</div>

Required predictive search

<div class="m-form-row [ Modifier ]">
	<label class="a-label" for="test-text-a">Which country did you last visit?</label>
	<div class="m-form-row__content">
		<input type="text" id="..." name="..." class="a-textbox [ Modifier ]" data-module="m-predictive-search" aria-required="true" />
	</div>
</div>

Development and test

Notes for developers

When using the predictive search component a number of settings need to be set either on initial load or using the setSettings function for this component. The possible settings are covered below:

Attribute Type Default Description
display Integer 0

Value 0, 1 or 2.

  • 0 - No formatting applied to results
  • 1 - Highlights any matches to the search term within the results
  • 2 - Highlights any words prior to a ","
overlay Boolean false Set to true if the results display should overlay page content rather than push it down
cache Boolean true Set to false to disable result caching
minChars Integer 3 Set the minimum number of characters required before any search is performed
delay Integer 350 Number of miliseconds to wait between search requests/debounce keypresses. Minimum allowed if 350 to prevent errors.
categories Object null

Indexable object reference for category id, readable name and class ie.

categories : {
	areas : 'Cities/Areas',
	places : 'Places/Landmarks',
	garages : 'Garages'
}

To display an icon beside the category title include a class along with the category name eg.

categories : {
	areas : [ 'Cities/Areas', 'm-predictive-search-results__category--areas' ],
	places : [ 'Places/Landmarks', 'm-predictive-search-results__category--places' ],
	garages : [ 'Garages', 'm-predictive-search-results__category--garages' ]
}

See icon reference for further details on available icons and how to add additional icons.

choices Array null

If search is to be done on a local list populate an array with all the possible choices.

With no categories:

choices : [ 'Afghanistan', 'Albania', 'Algeria', .... ]

With categories:

choices : [ [ 'Maciejki, Warszawa, Mazovia', 'areas' ], [ 'Maciejki Town Hall, Waszawa, Mazovia', 'places' ], .... ]
source Function null

When an AJAX call is required set source to be the function that retrieves the data and passes it on as an array (same format as choices) to the response function eg.

source : function( term, response, xhr ) {
	xhr.open( 'GET', '//www.test.com/search?q=' + term, true );
	xhr.onload = function onload() {
		var jsonResponse,
			responseData = [],
			i;
		if ( xhr.status >= 200 && xhr.status < 400 ) {
			jsonResponse = JSON.parse( xhr.responseText );			// Format response from service			response( responseData );
		}
	};
	xhr.send();
}

The XMLHttpRequest object is passed into the source function as the last parameter so that it can be used to initiate the ajax request and will be automatically aborted if a new search is initialised to avoid race conditions.

For example:

document.addEventListener( 'frameworkready', function () {
	FRAMEWORK.require([ 'blocks/m-predictive-search' ], function ( mPredictiveSearchModule ) {
		var searchEl = document.querySelector( '#search-input' ),
			dateInstance = mPredictiveSearchModule.initInstance( searchEl, {
				overlay : true,
				display : 2,
				source : function( term, response, xhr ) {
					xhr.open( 'GET', '//www.test.com/search?q=' + term, true );
					xhr.onload = function onload() {
						var jsonResponse,
							responseData = [],
							i;
						if ( xhr.status >= 200 && xhr.status < 400 ) {
							jsonResponse = JSON.parse( xhr.responseText );							// Format response from service							response( responseData );
						}
					};
					xhr.send();
				},
			});
	});
});

or

document.addEventListener( 'frameworkready', function () {
	FRAMEWORK.require([ 'blocks/m-predictive-search' ], function ( mPredictiveSearchModule ) {
		var searchEl = document.querySelector( '#search-input' ),
			dateInstance = mPredictiveSearchModule.initInstance( searchEl );		dateInstance.setSettings({
			source : function( term, response, xhr ) {
				xhr.open( 'GET', '//www.test.com/search?q=' + term, true );
				xhr.onload = function onload() {
					var jsonResponse,
						responseData = [],
						i;
					if ( xhr.status >= 200 && xhr.status < 400 ) {
						jsonResponse = JSON.parse( xhr.responseText );						// Format response from service						response( responseData );
					}
				};
				xhr.send();
			},
		});
	});
});

Icon reference

Category Icon class name
Cities/Areas m-predictive-search-results__category--areas
Garages m-predictive-search-results__category--garages
Medical professional m-predictive-search-results__category--medical
Places/Landmarks m-predictive-search-results__category--places

If different icons are required the icons can be added via custom css:

.m-predictive-search-results__category--people {
	background-image: [ Image URL ];
}

Icons should be:

  • A maximum of 20px high and 20px wide
  • Colour set to #5C596D with a transparent background
  • Included in SVG format

Input types

Care should be taken when choosing input field types for various uses, particularly with regard to number entry, as making the wrong selection could prevent users from inputting the required details into a form. For further information, see the form introduction page.

Aria usage for errors and help text

To aid screen reader users in completing forms without error and also with understanding and fixing any errors that have occured, some additional aria attributes are now recommended to be applied across all form fields/rows.

All form row help, explanatory text, form row instructions and form row errors must have a unique id assigned to them and be appropriately linked to either the individual form input or the form row using aria-describedby. This ensures that the help text is read out immediately on focus of the form input/fieldset. When there is more that one item that requires referencing within the aria-describedby attribute the id values must be supplied in the form of a space separated list. For example if there is an error with id of 'err1' and help text with id of 'help1' the value for the aria-describedby attribute would be 'err1 help1'.

All inline form error messages should start with the hidden text 'Error: ' so that when read by out by a screen reader it is immediately clear that the text being read is an error message.

All erroring form fields (or fieldset if a group or radios/checkboxes) must have aria-invalid="true" set on them, ensuring that when a user focus' on an errored form field, the field will be announced as invalid, so the user is then aware that there in an issue that requires fixing.

When linking help or errors, or even adding aria-invalid to the markup careful consideration must be taken as to where it is most appropriate to apply the value. The following rules should be used to decide where the attribute(s) should be applied.

  • Single form field - All attributes should be applied directly to that form field
  • Group of form fields but only one in error or help text applies to only one - Apply the attribute(s) to the only field in error or where the help text applies
  • Group of form field where all in error or the help text applies to all - Apply the attribute(s) to the groups surrounding fieldset (form row)

There may situations where more than one of these rules applies to the overall form row for example a date range where the instruction text applies to both fields so should be linked to the fieldset for the date range but one of the two fields is in error so the error should be linked to just that field not to the fieldset.

Important messages

To help those using assistive technologies, make sure that success/error messages which need to be announced to users have their aria attributes updated to role="alert" and/or aria-live="assertive".

Using autocomplete

Users appreciate when websites save them time by automatically filling common fields like names, email addresses and other frequently used fields, plus it helps to reduce potential input errors, especially on virtual keyboards and small devices.

Browsers use many methods to determine which fields they can auto-populate based on previously specified data by the user, and you can give hints to the browser by providing both the name attribute and the autocomplete attribute on each input element.

Further details can be found in the developer notes on the form introduction page.

Changing locale settings

Default text for predictive search can be changed for a particular locale.

en: {
	mPredictiveSearch : {
		instruction : 'When auto-complete results are available use up and down arrows to review, and enter to select.  Touch device users, explore by touch or with swipe gestures.',
		resultsFound : 'results are available.',
		noResults : 'No search results.',
	},
},

For more information on this, see our page on how to change locale settings within JavaScript.

Extension component

This component forms part of the 'forms-extended-a' extension and so requires an additional stylesheet to be loaded in order to be used; include the following code in the header of your page to attach the relevant additional stylesheet:

<link media="all" href="./assets/[ theme type ]/[ release version ]/[ organisation ]/[ theme name ]/css/forms-extended-a.css" rel="stylesheet" />

Notes for testers

  • When geolocation is not available on the device or the page is HTTP then the "Use current location" will not be displayed at all. If any error occurs when retrieving the location the option will become disabled.
  • By default the results list height is limited to showing 5.5 results (if only 6 results, 6 are shown) and 3.5 (if only 4 results all 4 are shown) at mobile. This height restriction does not include the "Use current location" or any category titles.

Keyboard operations

TAB

Tabbing to an predictive search field should make the input clearly visually different so that the focus point on the page is obvious to the user.

CURSOR KEYS

With focus on the predictive search field and options being presented, pressing UP or DOWN will cycle through available options. Pressing LEFT or RIGHT will move the cursor left or right through the selected option

ENTER

With focus on the predictive search field and options being presented, pressing ENTER will select the current option and close the selections

ESCAPE

With focus on the predictive search field and options being presented, pressing ESCAPE will close the selections

Component releases

  • Added on: v3.1.0 (08/12/17)
  • Updated on: v5.11.0 (07/09/21)

Latest update:

  • fixed: Fix for JavaScript incompatability with IE11.

Full version history

A full history of changes and enhancements detailing all minor and major updates to the component.

View full version history

Want something new in Framework, or to chat about an issue you're having with it?

Contact the team