The search filters panel shows a standard layout for a UoL search page. The pattern consists of a heading section, a filter panel (left hand side on large screens / behind a toggle button on smaller devices), a search form, results count, a chips container, search results and pagination.
This documentation details the sections of the page relating to filters (filters panel and search form).
The heading area houses the uol-page-heading component. Here the page is introduced with a title, subheading and further content where required.
The filter panel is viewable at all times on the left hand side for large width devices, but hidden on smaller devices. This is triggered by a filter results button.
The title for the filter panel is dynamically added depending on what type of filters are included within. With no Javascript enabled this title is set to be “Filter by”, When Javascript is enabled, a “scan” through the type of filters included with the panel sets this title to be one of the following:
Filters only - “Filter by” Sort only - “Sort by” Combination - “Filter and sort by”
This text is also applied to the filter button which triggers panel opening as detailed above.
Filters can be radio button groups, checkbox groups or select lists (single or multiselect). These input types are all derived from the @uol-form-input component. Each of these is introduced here via an example. Each filter is nested within a form block denoted by the config example for radio button group below.
The default variant has a radio button selected to select either full time or part time mode of study option (only one can be selected at any point). This is set up with the following config:
'form': {
'action': '/forms/some-action',
'filter_inputs': [{
"id": "filter-study-mode",
"name": "filter-study-mode",
"label": "Mode of study",
"type": "radio",
'input_width': 'small',
"legend": "Mode of study",
"hint": "Select one option",
"heading_level": "h3",
"group_label_id": "filter-study-mode-group",
"options": [{
"id": "filter-study-mode-1",
"name": "filter-study-mode-group",
"value": "full-time",
"label": "Full time"
},
{
"id": "filter-study-mode-2",
"name": "filter-study-mode-group",
"value": "part-time",
"label": "Part time",
"checked": true
}
Of note in the above:
The second filter type on the default variant has a checkbox group - the difference here being that more than one option can be selected. This is set up with the following config:
"type": "checkbox",
"input_width": "small",
"legend": "Delivery type",
"hint": "Select all that apply",
"heading_level": "h3",
"group_label_id": "filter-delivery-type-group",
"options": [{
"id": "filter-delivery-type-campus",
"name": "filter-delivery-type-campus",
"value": "campus",
"label": "On campus"
},
{
"id": "filter-delivery-type-blended",
"name": "filter-delivery-type-blended",
"value": "blended",
"label": "Blended learning",
"checked": true
},
Of note in the above:
The second filter type on the default variant has a checkbox group - the difference here being that more than one option can be selected. This is set up with the following config:
"type": "select",
"label": "Subject",
"hint": "Select one option",
"name": "filter-subject",
"id": "filter-subject",
"invalid": false,
"options": [{
"value": "art_design_media_and_communication",
"label": "Art, Design, Media and Communication"
},
{
"value": "biological_biomedical_and_sports_sciences",
"label": "Biological, Biomedical and Sports Sciences"
},
{
"value": "business_management_finance_and_economics",
"label": "Business, Management, Finance and Economics",
"selected": true
},
Of note in the above:
To incorporate a multiple select typeahead component requires the following parameters setting (all other config as per single typeahead above)
"type": "select",
"multiple": true,
"chips_hide": true,
The multiselect component when used in other page areas shows ‘chips’ for each selection within the component. For search results pages, chips should appear elsewhere on the page (see below), and their incorporation is done server side and beyond the scope of this pattern.
All filters panel include a “Clear all filters” button. When activated this button loops through all filters in the filter panel and clears their default values.
The search form uses the @uol-form-block component. This config is nested within the form element used above for filter inputs (although in different sections of the page layout, both the filters and form above results act as form elements). The default config below results in a form with keyword and search button. Please note this is not a second form but an addition to the above form object.
'form': {
'form_block': {
'lead': null,
'additional_info_before': null,
'button': {
'style': 'primary',
'type': 'submit',
'content': 'Search'
},
'fields': [
{
'type': 'search',
'id': 'inputId2',
'name': 'searchCourses2',
'label': 'Search by keyword',
'invalid': 'false',
'autocomplete': 'off',
'has_icon': true
}
],
'button_inline': true
}
For all current live Design System pages utilising chips, these are generated at run time via Funnelback integration. This design pattern includes a container which can be used to house these chips (further information to follow).
This variant of the search results will display the usual search results page pattern but without the Search Form. This will enable editors to create a filterable (but not searchable) list of results.
This can be implemented through the following configuration:
{
'no_form_variant': true,
'form': {
'form_block': false,
}
}
Please note the property ‘no_form_variant’: true, is required for this variant to add the correct styling.
This variant of the search results pattern shows an example with the addition of the content area at the top of the results. The content area uses the @uol-typography-rich-text component to allow editors to add and edit content within this section (typically through a text editor found within a CMS).
This can be implemented through the following configuration (for example):
{
'content': `
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.</p>
<div class="uol-in-text-cta">
<h2 class="uol-in-text-cta__heading">
<a class="uol-in-text-cta__link" href="/">Find out more about cheese</a>
</h2>
<p class="uol-in-text-cta__text">Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.</p>
</div>
`
}
<form {% if form.action %}action="{{ form.action }}"{% endif %} class="uol-col-container uol-search-results {{ 'uol-search--has-filters' if form.filter_inputs }} {{ 'uol-search--publications' if publications_items }} {{ 'uol-search--has-map-content' if with_map_and_content_variant }} {{ 'uol-search--no-form' if no_form_variant }}">
<div class="uol-search-results__page-heading">
{% render '@uol-page-heading', { page_heading: page_heading } %}
</div>
{% if content %}
<div class="uol-search-results__content-area">
<div class="uol-rich-text">
{{ content | safe }}
</div>
</div>
{% endif %}
{% if iframe %}
{% render '@uol-iframe', { iframe: iframe } %}
{% endif %}
{% if form.filter_inputs %}
<div class="uol-search-result__filters">
{% render '@uol-filters-panel', { filter_inputs: form.filter_inputs,
results_button: form.results_button } %}
</div>
{% endif %}
<div id="main" tabindex="-1" class="uol-search-results__main">
{% render '@uol-form-block', { form_block: form.form_block } %}
<div class="uol-search-results__results">
{% render '@uol-results-count' %}
<div class="uol-search-results__button-chips-container">
{% render '@uol-chips', { items: chips } %}
</div>
{% render '@uol-results-items', { items: results_items } %}
{% render '@uol-publications-items', { publications: publications_items } %}
{% render '@uol-pagination', { pagination: pagination } %}
</div>
</div>
</form>
<form action="/forms/some-action" class="uol-col-container uol-search-results uol-search--has-filters ">
<div class="uol-search-results__page-heading">
<header class="page-heading">
<h1 class="page-heading__title">
<span class="page-heading__title__main">Search page title</span>
</h1>
</header>
</div>
<div class="uol-search-result__filters">
<div class="uol-filters-panel " id="search-filters" aria-labelledby="filters-panel-title" role="group">
<div class="dialog-overlay" tabindex="-1" data-a11y-dialog-hide></div>
<h2 id="filters-panel-title" class="uol-filters-panel__title">Filters</h2>
<div class="uol-form__input-container
">
<label class="uol-form__input-label" for="filter-subject" id="filter-subject-label">
<span class="uol-form__input-label__text">Sort by</span>
<span class="uol-form__input-label__hint" id="filter-subject-hint">Select one option </span>
</label>
<div class="uol-form__input-wrapper " data-field-invalid=false>
<select class="uol-form__input uol-form__input--select uol-form__input-container__sort-by" name="filter-subject" id="filter-subject" aria-label="Select Sort by">
<option value="">Select an option</option>
<option value="newest_to_oldest" selected>Newest to oldest</option>
<option value="oldest_to_newest">Oldest to newest</option>
</select>
<svg class="uol-form__input__chevron" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" focusable="false" aria-hidden="true">
<path fill="none" d="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z" />
</svg>
</div>
</div>
<div class="uol-form__input-container
">
<label class="uol-form__input-label" for="selectID2" id="selectID2-label">
<span class="uol-form__input-label__text">Cheeses list</span>
<span class="uol-form__input-label__hint" id="selectID2-hint">Select a cheese </span>
</label>
<div class="uol-form__input-wrapper " data-field-invalid=false>
<select class="uol-form__input uol-form__input--select " name="selectName2" id="selectID2" aria-label="Select Cheeses list" multiple data-chips-hide>
<option value="">Select an option</option>
<option value="BRI">Brie</option>
<option value="CBL">Cashel Blue</option>
<option value="CHE">Cheddar</option>
<option value="CYA">Cornish Yarg</option>
<option value="EDA">Edam</option>
<option value="MAN">Manchego</option>
<option value="PRE">Parmigiano-Reggiano</option>
<option value="SBL">Shropshire Blue</option>
<option value="STI">Stilton</option>
<option value="SBI">Stinking Bishop</option>
<option value="WEN">Wensleydale</option>
</select>
<svg class="uol-form__input__chevron" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" focusable="false" aria-hidden="true">
<path fill="none" d="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z" />
</svg>
</div>
</div>
<div class="uol-filters-panel__footer">
<button id="clear_filter_panel" class="uol-button uol-button--secondary
uol-icon uol-icon--mdiDeleteForeverOutline
uol-icon--icon-only--large
" type="button">Clear all filters</button>
<button id="show_search_results" class="uol-button uol-button--primary
" type="button">Show 15 search results</button>
</div>
</div>
<div class="uol-filters-panel__overlay"></div>
</div>
<div id="main" tabindex="-1" class="uol-search-results__main">
<div class="uol-form__container">
<div class="uol-form__inner-wrapper">
<div class="uol-form uol-form--button-inline">
<div class="uol-form__inputs-wrapper">
<div class="uol-form__input-container
">
<label class="uol-form__input-label" for="inputId2">
<span class="uol-form__input-label__text">Search by keyword</span>
</label>
<div class="uol-form__input-wrapper
uol-form__input-wrapper--search
uol-form__input-wrapper--with-icon " data-field-invalid=false>
<!-- -->
<input class="uol-form__input uol-form__input--search" type="search" id="inputId2" name="searchCourses2" aria-invalid="false" value="" autocomplete="off">
<!-- -->
</div>
</div>
</div>
<div class="uol-form__button-wrapper">
<button class="uol-button uol-button--primary
" type="submit">Search</button>
</div>
</div>
</div>
</div>
<div class="uol-search-results__results">
<div class="uol-results-count">
<h2 class="uol-results-count__title">5 results for <strong>'ipsum'</strong></h2>
</div>
<div class="uol-search-results__button-chips-container">
</div>
<div class="uol-results-items">
<article class="uol-results-items__item">
<div class="uol-results-items__item__content-wrapper">
<div class="uol-results-items__item__image-container">
<img class="uol-results-items__item__img" src="/placeholders/banner/banner-05.jpg" alt="A super informative description">
</div>
<div class="uol-results-items__item__text-container">
<div class="uol-results-items__item__text-container__inner">
<h2 class="uol-results-items__item__title">
<a href="/cheese/brie" class="uol-results-items__item__link">Brie</a>
</h2>
<p class="uol-results-items__item__summary">Brie is a soft cow's-milk cheese named after Brie, the French region from which it originated. It is pale in color with a slight grayish tinge under a rind of white mould. The rind is typically eaten, with its flavor depending largely upon the ingredients used and its manufacturing environment</p>
</div>
</div>
</div>
</article>
<article class="uol-results-items__item">
<div class="uol-results-items__item__content-wrapper">
<div class="uol-results-items__item__text-container">
<div class="uol-results-items__item__text-container__inner">
<h2 class="uol-results-items__item__title">
<a href="/cheese/cashel-blue" class="uol-results-items__item__link">Cashel Blue</a>
</h2>
<p class="uol-results-items__item__summary">Cashel Blue is a hand-made, semi-soft, blue veined, medium-strength blue cheese with a creamy texture. Cashel Blue was the first Irish blue cheese, named after the Rock of Cashel overlooking the pastures close to the cheese farm of the family Grubb.</p>
</div>
</div>
</div>
</article>
<article class="uol-results-items__item">
<div class="uol-results-items__item__content-wrapper">
<div class="uol-results-items__item__text-container">
<div class="uol-results-items__item__text-container__inner">
<h2 class="uol-results-items__item__title">
<a href="/cheese/cheddar" class="uol-results-items__item__link">Cheddar</a>
</h2>
<p class="uol-results-items__item__summary">Cheddar cheese is a relatively hard, off-white, sometimes sharp-tasting, natural cheese. Originating in the English village of Cheddar in Somerset, cheeses of this style are now produced beyond the region and in several countries around the world</p>
</div>
</div>
</div>
</article>
<article class="uol-results-items__item">
<div class="uol-results-items__item__content-wrapper">
<div class="uol-results-items__item__image-container">
<img class="uol-results-items__item__img" src="/placeholders/banner/banner-05.jpg" alt="A super informative description">
</div>
<div class="uol-results-items__item__text-container">
<div class="uol-results-items__item__text-container__inner">
<h2 class="uol-results-items__item__title">
<a href="/cheese/edam" class="uol-results-items__item__link">Edam</a>
</h2>
<p class="uol-results-items__item__summary">Edam is a semi-hard cheese that originated in the Netherlands, and is named after the town of Edam in the province of North Holland. Edam is traditionally sold in rounded cylinders with a pale yellow interior and a coat, or rind, of red paraffin wax. Edam ages and travels well, and does not spoil; it only hardens</p>
</div>
</div>
</div>
</article>
<article class="uol-results-items__item">
<div class="uol-results-items__item__content-wrapper">
<div class="uol-results-items__item__image-container">
<img class="uol-results-items__item__img" src="/placeholders/banner/banner-05.jpg" alt="A super informative description">
</div>
<div class="uol-results-items__item__text-container">
<div class="uol-results-items__item__text-container__inner">
<h2 class="uol-results-items__item__title">
<a href="/cheese/manchego" class="uol-results-items__item__link">Manchego</a>
</h2>
<p class="uol-results-items__item__summary">Manchego is a cheese made in the La Mancha region of Spain from the milk of sheep of the Manchega breed. It is aged between 60 days and 2 years. Manchego has a firm and compact consistency and a buttery texture, and often contains small, unevenly distributed air pockets</p>
</div>
</div>
</div>
</article>
<article class="uol-results-items__item">
<div class="uol-results-items__item__content-wrapper">
<div class="uol-results-items__item__image-container">
<img class="uol-results-items__item__img" src="/placeholders/banner/banner-05.jpg" alt="A super informative description">
</div>
<div class="uol-results-items__item__text-container">
<div class="uol-results-items__item__text-container__inner">
<h2 class="uol-results-items__item__title">
<a href="/cheese/parmigiano-reggiano" class="uol-results-items__item__link">Parmigiano-Reggiano</a>
</h2>
<p class="uol-results-items__item__summary">Parmigiano-Reggiano or Parmesan is an Italian hard, granular cheese that is produced from cow's milk and has aged 12-36 months.</p>
</div>
</div>
</div>
</article>
</div>
<div class="uol-results-items">
</div>
<nav class="uol-pagination" aria-label="pagination">
<ol class="uol-pagination__list">
<li class="uol-pagination__item">
<button class="uol-button uol-button--primary uol-icon uol-icon--icon-only uol-icon--mdiPageFirst" type="button" disabled>First page</button>
</li>
<li class="uol-pagination__item">
<button class="uol-button uol-button--primary uol-icon uol-icon--icon-only uol-icon--mdiArrowLeft" type="button" disabled>Previous page</button>
</li>
<li class="uol-pagination__item uol-pagination__item--numeric uol-pagination__item--current">
<a class="uol-button uol-button--secondary uol-icon uol-icon--icon-only uol-pagination__link" href="/page-1" data-number="1" aria-current=page>
<span class="uol-icon__label">
<span class="hide-accessible">Page </span>1
</span>
</a>
</li>
<li class="uol-pagination__item uol-pagination__item--numeric ">
<a class="uol-button uol-button--secondary uol-icon uol-icon--icon-only uol-pagination__link" href="/page-2" data-number="2">
<span class="uol-icon__label">
<span class="hide-accessible">Page </span>2
</span>
</a>
</li>
<li class="uol-pagination__item uol-pagination__item--numeric ">
<a class="uol-button uol-button--secondary uol-icon uol-icon--icon-only uol-pagination__link" href="/page-3" data-number="3">
<span class="uol-icon__label">
<span class="hide-accessible">Page </span>3
</span>
</a>
</li>
<li class="uol-pagination__item">
<a href="/page-2" class="uol-button uol-button--primary uol-icon uol-icon--icon-only uol-icon--mdiArrowRight">Next page</a>
</li>
<li class="uol-pagination__item">
<a href="/page-4" class="uol-button uol-button--primary uol-icon uol-icon--icon-only uol-icon--mdiPageLast">Last page</a>
</li>
</ol>
<span class="uol-pagination__status">
Page 1 of 4
</span>
</nav>
</div>
</div>
</form>
.uol-search-results__page-heading {
@extend .uol-col;
@extend .uol-col-12;
padding-bottom: 0;
.page-heading {
@include media("<uol-media-xs") {
padding-left: $spacing-2;
padding-top: $spacing-2;
}
margin-bottom: $spacing-4;
@include media(">=uol-media-m") {
margin-bottom: $spacing-6;
}
}
}
.uol-search--no-form {
.page-heading {
margin-bottom: 0.625rem; // 10px
@include media(">=uol-media-xs") {
margin-bottom: 0.125rem; // 2px
}
@include media(">=uol-media-m") {
margin-bottom: 0.938rem; // 15px
}
@include media(">=uol-media-l") {
margin-bottom: 1.688rem; // 27px
}
@include media(">=uol-media-xl") {
margin-bottom: 1.188rem; // 19px
}
}
}
.uol-search-results__content-area {
@extend .uol-col;
@extend .uol-col-12;
padding: 0 $spacing-2;
.site-outer & {
padding-top: 0;
margin-top: -0.438rem; // -7px
@include media(">=uol-media-xs") {
padding-bottom: 0;
margin-top: -0.938rem // -15px
}
@include media(">=uol-media-m") {
padding-bottom: $spacing-4;
margin-top: -$spacing-5;
}
@include media(">=uol-media-l") {
padding-bottom: 1.75rem; // 28px
margin-top: -1.563rem; // -25px
}
@include media(">=uol-media-xl") {
padding-bottom: $spacing-4;
margin-top: -1.813rem; // -29px
}
}
.site-outer .uol-search--has-map-content & {
@include media(">=uol-media-l") {
padding-bottom: 1.25rem // 20px
}
@include media(">=uol-media-xl") {
padding-bottom: 0.75rem // 12px
}
}
.site-outer .uol-search--no-form & {
margin-bottom: -0.938rem; // -15px
padding-top: 0.375rem; // 6px
@include media(">=uol-media-xs") {
padding-top: 0.875rem; // 14px
}
@include media(">=uol-media-m") {
margin-bottom: -1.063rem; // -17px
padding-top: 1rem; // 16px
}
@include media(">=uol-media-l") {
margin-bottom: 0;
padding-top: 0.313rem; // 5px
}
@include media(">=uol-media-xl") {
padding-top: 0.813rem; // 13px
}
}
}
.uol-search-results__main {
@include page-width("full");
}
.uol-search-result__filters {
@extend .uol-col;
@extend .uol-col-12;
@extend .uol-col-l-3;
.js & {
@include media("<uol-media-l") {
padding: 0;
}
}
}
// Components margin/padding changes if in search results pattern
.uol-search-results {
margin-bottom: $spacing-7;
.uol-form__container,
.uol-results-count {
margin-bottom: $spacing-6;
@include media(">=uol-media-m") {
margin-bottom: $spacing-7;
}
}
.uol-chips {
padding: 0;
}
.uol-search-results__button-chips-container {
.uol-button {
margin-bottom: $spacing-5;
@include media(">=uol-media-m") {
margin-bottom: $spacing-6;
}
}
}
.uol-results-items {
margin: 1.25rem 0 $spacing-6;
padding: 0;
@include media(">=uol-media-m") {
margin: 2.25rem 0 $spacing-7;
}
}
.uol-form__inner-wrapper .uol-form__input-wrapper {
&::before {
@include media("<uol-media-m") {
bottom: 0; // add comment to force update
}
}
}
.uol-publications-list {
@include media(">=uol-media-s") {
margin-right: calc(100% / 12 * 2 + 0.25rem);
}
@include media(">=uol-media-l") {
margin-right: calc(100% / 9 * 2 + 0.25rem);
}
}
}
.uol-search--publications .page-heading__title__main::after {
content: " - Publications";
}
const focusTrap = require('focus-trap');
let courseFinderFilterPage = false;
export const uolSearchResults = () => {
const filterPanel = document.querySelector('.uol-search-result__filters');
const searchResultsPage = document.querySelector('.uol-search--has-filters');
let filterPanelTitle = "Filter By";
if (filterPanel) {
const numOfSortByOptions = filterPanel.getElementsByClassName("uol-form__input-container__sort-by").length;
const numOfFilterOptions = filterPanel.getElementsByClassName("uol-form__input-container").length;
console.log('numOfSortByOptions ' + numOfSortByOptions);
console.log('numOfFilterOptions ' + numOfFilterOptions);
if (numOfSortByOptions > 0 && numOfFilterOptions == numOfSortByOptions) {
filterPanelTitle = "Sort by";
}
if (numOfSortByOptions == 0 && numOfFilterOptions > 0) {
filterPanelTitle = "Filter by";
}
if (numOfSortByOptions > 0 && numOfFilterOptions > numOfSortByOptions) {
filterPanelTitle = "Filter and sort by";
}
document.getElementById("filters-panel-title").innerHTML = filterPanelTitle;
}
if (searchResultsPage) {
let filtersOffscreen = false;
// Create ResizeObserver to toggle offscreen filters
const searchScreenResize = new ResizeObserver((entries) => {
const viewportWidth = entries[0].contentRect.width;
// TODO: investigate docwidth issue further
// var docWidth = document.documentElement.clientWidth || document.body.clientWidth;
// console.log('viewportWidth ' + viewportWidth);
if (viewportWidth < 1008) {
if (filtersOffscreen === false) {
offScreenFiltersCreate();
filtersOffscreen = true;
}
} else {
if (filtersOffscreen === true) {
offScreenFiltersDestroy();
filtersOffscreen = false;
}
}
});
searchScreenResize.observe(document.body);
// Select button container
const btnContainer = searchResultsPage.querySelector('.uol-search-results__button-chips-container');
// Close filters panel button
const btnCloseFilters = document.getElementById('filters-close-button');
// Show results button
const btnShowResults = document.getElementById('show_search_results');
// Create toggle button
const btnFilterToggle = document.createElement('button');
btnFilterToggle.id = 'filters-toggle';
btnFilterToggle.type = 'button';
btnFilterToggle.classList.add('uol-button');
btnFilterToggle.classList.add('uol-button--secondary');
btnFilterToggle.classList.add('uol-icon');
btnFilterToggle.classList.add('uol-icon--icon-only--large');
// Sort by icon if only sorting, otherwise, filter by icon
if (filterPanel) {
if (filterPanelTitle) {
let svgCode = (filterPanelTitle == "Sort by") ?
`<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M120-240v-60h240v60H120Zm0-210v-60h480v60H120Zm0-210v-60h720v60H120Z"/></svg>`:
`<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M400-240v-60h160v60H400ZM240-450v-60h480v60H240ZM120-660v-60h720v60H120Z"/></svg>`;
btnFilterToggle.innerHTML = svgCode +
`<span id="open-filter-button-text" class="uol-icon__label">` +
filterPanelTitle +
`</span>
`;
}
}
// Select filters panel
const filtersPanel = document.querySelector('.uol-filters-panel');
const filterPanelFocusTrap = focusTrap.createFocusTrap(filtersPanel, {
clickOutsideDeactivates: true,
returnFocusOnDeactivate: true,
onActivate: () => {
filtersPanel.classList.add('uol-filters-panel--open');
document.body.style.overflow = 'hidden';
},
onDeactivate: () => {
filtersPanel.classList.remove('uol-filters-panel--open');
document.body.style.removeProperty('overflow');
// Slight delay before attempting to move focus to allow reactivation of non-modal elements
const interval = setInterval(() => {
btnFilterToggle.focus();
clearInterval(interval);
}, 5);
}
});
btnFilterToggle.addEventListener('click', () => {
filtersOpen();
})
const filtersOpen = () => {
filtersPanel.setAttribute('tabindex', '-1')
filtersPanel.removeAttribute('hidden');
filtersPanel.focus();
filterPanelFocusTrap.activate();
}
const filtersClose = () => {
filterPanelFocusTrap.deactivate();
filtersPanel.addEventListener('transitionend', hidePanel)
const hidePanel = () => filtersPanel.setAttribute('hidden', true);
filtersPanel.removeEventListener('transitionend', hidePanel)
}
const offScreenFiltersCreate = () => {
// Hide the filters
filtersPanel.setAttribute('hidden', true);
// Add btnFilterToggle to DOM
btnContainer.insertAdjacentElement('afterbegin', btnFilterToggle);
btnCloseFilters.addEventListener('click', () => {
filtersClose();
})
btnShowResults.addEventListener('click', () => {
filtersClose();
})
}
const offScreenFiltersDestroy = () => {
// Unhide the filters
filtersPanel.removeAttribute('hidden');
// Remove btnFilterToggle from DOM
btnFilterToggle.remove();
// In case the filters are open we need to close
filtersClose();
// Remove 'hidden' attribute that was added by filtersClose()
filtersPanel.removeAttribute('hidden');
}
}
}
{
"page_heading": {
"title": "Search page title"
},
"form": {
"action": "/forms/some-action",
"filter_inputs": [
{
"type": "select",
"label": "Sort by",
"hint": "Select one option",
"name": "filter-subject",
"id": "filter-subject",
"invalid": false,
"sort_by": true,
"options": [
{
"value": "newest_to_oldest",
"label": "Newest to oldest",
"selected": true
},
{
"value": "oldest_to_newest",
"label": "Oldest to newest"
}
]
},
{
"type": "select",
"label": "Cheeses list",
"id": "selectID2",
"name": "selectName2",
"hint": "Select a cheese",
"multiple": true,
"chips_hide": true,
"options": [
{
"label": "Brie",
"value": "BRI"
},
{
"label": "Cashel Blue",
"value": "CBL"
},
{
"label": "Cheddar",
"value": "CHE"
},
{
"label": "Cornish Yarg",
"value": "CYA"
},
{
"label": "Edam",
"value": "EDA"
},
{
"label": "Manchego",
"value": "MAN"
},
{
"label": "Parmigiano-Reggiano",
"value": "PRE"
},
{
"label": "Shropshire Blue",
"value": "SBL"
},
{
"label": "Stilton",
"value": "STI"
},
{
"label": "Stinking Bishop",
"value": "SBI"
},
{
"label": "Wensleydale",
"value": "WEN"
}
]
}
],
"results_button": {
"type": "button",
"content": "Show 15 search results",
"style": "primary",
"id": "show_search_results"
},
"form_block": {
"lead": null,
"additional_info_before": null,
"button": {
"style": "primary",
"type": "submit",
"content": "Search"
},
"fields": [
{
"type": "search",
"id": "inputId2",
"name": "searchCourses2",
"label": "Search by keyword",
"invalid": "false",
"autocomplete": "off",
"has_icon": true
}
],
"button_inline": true
}
},
"results_items": [
{
"url": "/cheese/brie",
"title": "Brie",
"text": "Brie is a soft cow's-milk cheese named after Brie, the French region from which it originated. It is pale in color with a slight grayish tinge under a rind of white mould. The rind is typically eaten, with its flavor depending largely upon the ingredients used and its manufacturing environment",
"image": {
"src": "/placeholders/banner/banner-05.jpg",
"alt": "A super informative description"
}
},
{
"url": "/cheese/cashel-blue",
"title": "Cashel Blue",
"text": "Cashel Blue is a hand-made, semi-soft, blue veined, medium-strength blue cheese with a creamy texture. Cashel Blue was the first Irish blue cheese, named after the Rock of Cashel overlooking the pastures close to the cheese farm of the family Grubb."
},
{
"url": "/cheese/cheddar",
"title": "Cheddar",
"text": "Cheddar cheese is a relatively hard, off-white, sometimes sharp-tasting, natural cheese. Originating in the English village of Cheddar in Somerset, cheeses of this style are now produced beyond the region and in several countries around the world"
},
{
"url": "/cheese/edam",
"title": "Edam",
"text": "Edam is a semi-hard cheese that originated in the Netherlands, and is named after the town of Edam in the province of North Holland. Edam is traditionally sold in rounded cylinders with a pale yellow interior and a coat, or rind, of red paraffin wax. Edam ages and travels well, and does not spoil; it only hardens",
"image": {
"src": "/placeholders/banner/banner-05.jpg",
"alt": "A super informative description"
}
},
{
"url": "/cheese/manchego",
"title": "Manchego",
"text": "Manchego is a cheese made in the La Mancha region of Spain from the milk of sheep of the Manchega breed. It is aged between 60 days and 2 years. Manchego has a firm and compact consistency and a buttery texture, and often contains small, unevenly distributed air pockets",
"image": {
"src": "/placeholders/banner/banner-05.jpg",
"alt": "A super informative description"
}
},
{
"url": "/cheese/parmigiano-reggiano",
"title": "Parmigiano-Reggiano",
"text": "Parmigiano-Reggiano or Parmesan is an Italian hard, granular cheese that is produced from cow's milk and has aged 12-36 months.",
"image": {
"src": "/placeholders/banner/banner-05.jpg",
"alt": "A super informative description"
}
}
],
"pagination": {
"current": 1,
"pages": [
{
"number": 1,
"url": "/page-1"
},
{
"number": 2,
"url": "/page-2"
},
{
"number": 3,
"url": "/page-3"
},
{
"number": 4,
"url": "/page-4"
}
]
}
}