• Organism
  • CORE COMPONENT
  • Taxonomic name: O-RESULTS
  • Extension: FORMS-EXTENDED-A
  • Added on: v4.14.0 (11/10/19)
  • Updated on: v5.8.0 (15/06/21)

Filter tags

The results organism acts as a container for data reply of results returned fom targeted searches. It consists of filter tags and a results display toggle, as well as the results themselves. The former can be configured by teams dependent on their needs and works through sets of multiselect dropdowns which are styled according to the view breakpoint and number of controls required. The results filter is a pair of radio button sets styled to restrict the number of options being shown and whether theose results should be displayed as a grid or a list.


Design and usage

Filter tags

Structure

  • On desktop the filter has a group of multiselect dropdowns, allowing the user to select multiple filters. This organism has a Filter Results CTA to the right of the dropdowns which will update the screen with the filters applied.
  • If the multiselect dropdowns do not fit on one line within the permitted width, and for tablet and mobile, the Filters CTA opens a full screen model with a filter navigation which allows users to select multiple options.
  • This organism has two CTAs at the base of the modal, one to 'apply' filters and one to reset all filter criteria.
  • Filter tags include a H2 describing the functionality of the filter eg. 'Document search'.
  • This also has a link to download all documents.
  • multiselect dropdown:

    • Minimum number of checkbox multiselects is one dropdown.
    • Maximum number of checkbox multiselects depends on when the screen width is maxed; if width is maxed, the dropdowns change to the modal pattern similarly to tablet and mobile.
  • Filter tags:

    • Once the user has applied filters with the multiselect dropdowns or Modal window, individual filter tags will appear underneath the Filter organism showing the filters the user has selected.
    • The filter tags have a close button to the right of the label, this will remove the filter tag and the content associated to it.
    • To the right of the filter tags is a 'clear all filters' CTA; this is left aligned to the tags and pushes to the right each time another filter is applied; once pushed all the way to the right the clear all CTA will remain on the right and the tags will wrap underneath.
    • On mobile, the tags are masked behind the width of the device (similar to our pattern in wallet); this is to save screen space when multiple tags have been selected.
    • The cancel clear all filters CTA sits underneath the filter tags on mobile.
  • Feedback regarding the number of documents displayed following search and filtering must be replayed above the search results, near the results display component.

Labels

  • Labels appear as per our usual pattern for form UI and in buttons.
  • Checkbox multiselect dropdown labels mirror existing styling.

Accessibility and screen readers

  • Follows existing rules.
  • Uses aria-live regions to announce content updates eg. number of results found, any errors etc.
  • 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

Non-JS requirements and considerations

  • multiselect dropdowns work as standard dropdowns across all breakpoints.

Placement

  • Sits below the hero or at the top of a page.

Use case and exception scnenarios

  • User policy documents journeys.

Results display

Structure

  • Results displayed: Up to four options plus 'Show All' recommended due to potential character lengths for different languages; labels can be configured by project teams.
  • Display as: grid and list views available (desktop, tablet and mobile) as toggles.
  • Both 'Results displayed' and 'Display as' sit in-line with each other where they will fit (desktop).

Labels

  • Font weights and styling in relationship with filter tags (see above).

Accessibility and screen readers

  • Follows existing rules.

Non-JS requirements and considerations

  • N/A

Placement

  • Anchored to right desktop margin.
  • Alternatively, right edge of page grid column in use.
  • 40px horizontal spacing between results displayed lockup and display as lockup.

Use case and exception scnenarios

  • Can be used individually or as a pair (combined recommended where applicable).
  • Can be used in association with filtering.

Examples

Interactive example

Code example

Outer wrapper

<div class="o-results">
	<h2 class="a-heading a-heading--2 u-margin--bottom-none">...</h2>
	<button class="a-button a-button--tertiary a-button--download"><span class="a-button__inner">Download all</span></button>	<hr class="a-divider-line a-divider-line--horizontal-solid a-divider-line--horizontal-solid-light a-divider-line--30-all" />	<div class="m-filter-tags" id="..." data-module="m-filter-tags">
	...
	</div>	<hr class="a-divider-line a-divider-line--horizontal-solid a-divider-line--horizontal-solid-light a-divider-line--30-all" />	<div class="m-form-row m-form-row--full-width">
		<div class="m-form-row__content">
			<div class="m-results-display-wrapper">
				<div class="m-results-display">
					...
				</div>
				<div class="m-results-display m-results-display--total" aria-live="polite"></div>
			</div>
		</div>
	</div>
</div>

Filter tags

In-page content

<div class="m-filter-tags" id="..." data-module="m-filter-tags">
	<div class="m-filter-tags-filters">
		<h3 class="m-filter-tags-filters__heading a-heading a-heading--3">Select categories to filter documents</h3>
		<div class="m-filter-tags-filters__multiselect">
			<fieldset class="m-form-row m-form-row--full-width">
				<legend class="a-label">.../legend>
				<div class="m-form-row__content">
					<ul class="m-form-row-group m-form-row-group--option-group m-form-row-group--stacked">
						<li class="m-form-row-group-item m-form-row-group-item--full-width">
							<label class="a-checkbox" for="...">
								<input class="a-checkbox__input" type="checkbox" name="..." id="..." value="..." />
								<span class="a-checkbox__label"><span class="a-checkbox__label-inner">...</span></span>
								<span class="a-checkbox__ui"></span>
							</label>
						</li>
						...
					</ul>
				</div>
			</fieldset>
		</div>
		...
		<div class="m-filter-tags-filters__cta">
			<button id="modal-trigger" class="a-button a-button--form">Filter results</button>
		</div>
		<div class="m-filter-tags-filters__buttons">
			<ul class="m-button-group">
				<li class="m-button-group__item"><button class="a-button a-button--filters-apply">Apply</button></li>
				<li class="m-button-group__item"><button class="a-button a-button--tertiary a-button--filters-clear"><span class="a-button__inner">Clear all filters</span></button></li>
			</ul>
		</div>
	</div>
	<div class="m-filter-tags-tags">
		<p class="m-filter-tags-tags__label">Filters:</p>
		<ul class="m-filter-tags-tags__list m-button-group">
			<li class="m-button-group__item"><button class="a-button a-button--tag">...</button></li>
			...
			<li class="m-button-group__item"><button class="a-button a-button--tertiary a-button--cancel a-button--filters-cancel"><span class="a-button__inner">Clear all filters</span></button></li>
		</ul>
	</div>
</div>

At bottom of page

<div class="o-modal-target"></div>

Results display

<div class="m-form-row m-form-row--full-width">
	<div class="m-form-row__content">
		<div class="m-results-display-wrapper">
			<div class="m-results-display">
				<fieldset class="m-results-display-block">
					<legend class="a-label m-results-display-block__label">Results displayed:</legend>
					<ul class="m-results-display-block-list">
						<li class="m-results-display-block-list__item">
							<label class="a-radio" for="...">
								<input class="a-radio__input" type="radio" name="..." id="..." value="..." />
								<span class="a-radio__label"><span class="a-radio__label-inner">...</span></span>
							</label>
						</li>
						...
						<li class="m-results-display-block-list__item">
							<label class="a-radio" for="all">
								<input class="a-radio__input" type="radio" name="..." id="..." value="..." />
								<span class="a-radio__label a-radio__label--lozenge"><span class="a-radio__label-inner">Show all</span></span>
							</label>
						</li>
					</ul>
				</fieldset>
				<fieldset class="m-results-display-block">
					<legend class="a-label m-results-display-block__label">Display as:</legend>
					<ul class="m-results-display-block-list">
						<li class="m-results-display-block-list__item">
							<label class="a-radio" for="grid">
								<input class="a-radio__input" type="radio" name="view1" id="grid" value="grid" />
								<span class="a-radio__label a-radio__label--grid"><span class="a-radio__label-inner">Grid</span></span>
							</label>
						</li>
						<li class="m-results-display-block-list__item">
							<label class="a-radio" for="list">
								<input class="a-radio__input" type="radio" name="view1" id="list" value="list" />
								<span class="a-radio__label a-radio__label--list"><span class="a-radio__label-inner">List</span></span>
							</label>
						</li>
					</ul>
				</fieldset>
			</div>
			<div class="m-results-display m-results-display--total" aria-live="polite"></div>
		</div>
	</div>
</div>

Development and test

Notes for developers

Basic setup

For the fiter tags, the majority of the code here operates at the front end. Teams will need to configure the backend response for when filters are applied and then display the filter tags accordingly. The clear all filters tag is required, but the JavaScript will add and remove the other filter tags as a user interacts with the component. These will only need to be manually added if not use the JavaScript. With the results display, the number of results each radio button will show and how this affects the list should be determined by consuming teams.

How to process filter updates

A callback function has been provided in this component which can be called when a user adjusts their filter options; this allows you to process which options a user has selected and to update the results display accordingly.

The following is an example of how this could be acheived:

document.addEventListener( 'frameworkready', function () {
	FRAMEWORK.require([ 'blocks/m-filter-tags' ], function ( mFilterTagsModule ) {
		var filterEl = document.querySelector( '.m-filter-tags' ),
			applyFilters = function() {
				// Callback function which should then process which checkboxes have been selected
			},
			filterInstance = mFilterTagsModule.initInstance( filterEl );		filterInstance.setCallback( applyFilters );
	});
});

For more information on this, see our page on how to interact with JavaScript Framework components.

Ensure that all results updates, number of results and any errors (if they occur while searching/filtering) are announced to the user; this can be achieved via the use of aria-live regions.

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.

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

  • Ensure that checkbox multiselects perform as expexted when present, and that checkboxes retain their checked/unchecked states when switching breakpoints/views.

Classes overview

The following table gives you a quick overview of the CSS classes that can be applied.

Class Outcome Required Applied to Comments
.o-results Base style for results playback area including filter tags and results display Yes div Required if filters tags and results display are being used together
.m-filter-tags Base style for filter tags Yes .o-results > div Does not need to be child of .o-results if being used stand-alone
.m-filter-tags-filters Style for filter tags filters wrapper Yes .m-filter-tags > div Does not need to be child of .o-results if being used stand-alone
.m-filter-tags-filters__heading Style for filter tags filters heading Yes m-filter-tags-filters > h3  
.m-filter-tags-filters__multiselect Style for filter tags filters multiselect wrapper Yes m-filter-tags-filters > div  
m-filter-tags-filters__cta Style for filter tags filters main CTA Yes m-filter-tags-filters > div  
m-filter-tags-filters__buttons Style for filter tags filters modal buttons Yes m-filter-tags-filters > div  
.a-button--filters-apply Style for 'Apply' button within modal Yes .m-filter-tags-filters__buttons > ul > li > .a-button  
.a-button--filters-clear Style for 'Clear all filters' button within modal Yes .m-filter-tags-filters__buttons > ul > li > .a-button  
.m-filter-tags-tags Style for filter tags tags wrapper Yes .m-filter-tags > div  
.m-filter-tags-tags__label Style for filter tags tags label Yes .m-filter-tags-tags > p  
.m-filter-tags-tags__list Style for filter tags tags label Yes .m-filter-tags-tags > ul  
.a-button--tag Style for button within tags group Yes .m-filter-tags-tags__list > li > .a-button  
.m-results-display-wrapper Style for results display wrapper Yes .m-form-row > .m-form-row__content > div  
.m-results-display Base style for results display Yes .m-results-display-wrapper > div  
.m-results-display--total Modifier for results total display Yes .m-results-display + div  
.m-results-display-block Style for radio group results/display option wrappers Yes .m-results-display > div  
.m-results-display-block__label Style for radio group results/display option wrappers Yes .m-results-display-block > .a-label  
.m-results-display-block-list Style for radio group results/display option lists Yes .m-results-display-block > ul  
.m-results-display-block-list__item Style for radio group results/display option list items Yes .m-results-display-block-list > li  
.a-radio__label--grid Style to add correct icon to display as grid option Yes .m-results-display-block-list__item > label > .a-radio__label  
.a-radio__label--list Style to add correct icon to display as list option Yes .m-results-display-block-list__item > label > .a-radio__label  

Keyboard operations

TAB

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

Component releases

  • Added on: v4.14.0 (11/10/19)
  • Updated on: v5.8.0 (15/06/21)

Latest update:

  • fixed: Fix for issue where select all checkboxes would not always be cleared on smaller screens when tags were removed from the filter. Some adjustments have been made in order to improve support for IE11, where it was struggling to reliably draw the modal view correctly.

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