Skip to content

Commit a29ff3a

Browse files
committed
Improve accessibility of the AJAX search (aria-live, focus, loader)
After every AJAX filter/sort/page change the whole #search-form node is swapped, which was a triple problem for assistive-technology users. - Wrap the hits count in a role=status aria-live=polite region so the updated "N results" is announced after each update. - Give the loader overlay role=status and a translated aria-label ("Loading results…", added to all 12 locales) so "loading" is conveyed. - In search.js #replaceContent(): record the active element's id/name before the swap and restore focus to the equivalent element afterwards, falling back to focusing the results region (tabindex=-1) so focus is never dumped back on <body>. Closes #133
1 parent f33f2e3 commit a29ff3a

16 files changed

Lines changed: 75 additions & 2 deletions

src/Resources/public/js/search.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,12 +322,54 @@ class SearchManager {
322322
return null;
323323
}
324324

325+
// Remember what was focused: replaceWith() removes the element the user just operated
326+
// (a checkbox, the sort select), so focus would reset to <body> and keyboard users would
327+
// have to tab from the top again after every interaction.
328+
const active = document.activeElement;
329+
const focusId = active instanceof Element ? active.id : '';
330+
const focusName = (active instanceof HTMLInputElement || active instanceof HTMLSelectElement || active instanceof HTMLTextAreaElement) ? active.name : '';
331+
325332
existingContent.replaceWith(newContent);
326333
this.#initializeForm();
327334

335+
this.#restoreFocus(newContent, focusId, focusName);
336+
328337
return newContent;
329338
}
330339

340+
/**
341+
* Restores focus to the equivalent element in the freshly swapped-in content: the same id, or
342+
* the same field name, or — as a fallback — the results region itself (so focus is never left
343+
* on <body>).
344+
*
345+
* @param {Element} container
346+
* @param {string} focusId
347+
* @param {string} focusName
348+
*/
349+
#restoreFocus(container, focusId, focusName) {
350+
let target = null;
351+
352+
if (focusId !== '') {
353+
target = container.querySelector(`#${CSS.escape(focusId)}`) ?? document.getElementById(focusId);
354+
}
355+
356+
if (target === null && focusName !== '') {
357+
target = container.querySelector(`[name="${CSS.escape(focusName)}"]`);
358+
}
359+
360+
if (target === null) {
361+
// Fallback: move focus into the results region so it isn't dumped back at <body>.
362+
target = container;
363+
if (!container.hasAttribute('tabindex')) {
364+
container.setAttribute('tabindex', '-1');
365+
}
366+
}
367+
368+
if (typeof target.focus === 'function') {
369+
target.focus({ preventScroll: true });
370+
}
371+
}
372+
331373
/**
332374
* Emits a bubbling `search:content-updated` event so other scripts can re-initialise
333375
* widgets after the results markup is swapped.

src/Resources/translations/messages.da.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ setono_sylius_meilisearch:
88
price: Price
99
size: Size
1010
taxons: Category
11+
loading: 'Indlæser resultater…'
1112
no_results:
1213
body: 'Prøv at søge efter noget andet'
1314
header: 'Ingen resultater fundet'

src/Resources/translations/messages.de.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ setono_sylius_meilisearch:
88
price: Price
99
size: Size
1010
taxons: Category
11+
loading: 'Ergebnisse werden geladen…'
1112
no_results:
1213
body: 'Versuchen Sie, nach etwas anderem zu suchen'
1314
header: 'Keine Ergebnisse gefunden'

src/Resources/translations/messages.en.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ setono_sylius_meilisearch:
88
price: Price
99
size: Size
1010
taxons: Category
11+
loading: 'Loading results…'
1112
no_results:
1213
body: 'Try to search for something else'
1314
header: 'No results found'

src/Resources/translations/messages.es.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ setono_sylius_meilisearch:
88
price: Price
99
size: Size
1010
taxons: Category
11+
loading: 'Cargando resultados…'
1112
no_results:
1213
body: 'Intenta buscar otra cosa'
1314
header: 'No se encontraron resultados'

src/Resources/translations/messages.fr.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ setono_sylius_meilisearch:
88
price: Price
99
size: Size
1010
taxons: Category
11+
loading: 'Chargement des résultats…'
1112
no_results:
1213
body: 'Essayez de rechercher autre chose'
1314
header: 'Aucun résultat trouvé'

src/Resources/translations/messages.it.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ setono_sylius_meilisearch:
88
price: Price
99
size: Size
1010
taxons: Category
11+
loading: 'Caricamento dei risultati…'
1112
no_results:
1213
body: 'Prova a cercare qualcos''altro'
1314
header: 'Nessun risultato trovato'

src/Resources/translations/messages.lt.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ setono_sylius_meilisearch:
88
price: Price
99
size: Size
1010
taxons: Category
11+
loading: 'Kraunami rezultatai…'
1112
no_results:
1213
body: 'Pabandykite ieškoti ko nors kito'
1314
header: 'Rezultatų nerasta'

src/Resources/translations/messages.nl.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ setono_sylius_meilisearch:
88
price: Price
99
size: Size
1010
taxons: Category
11+
loading: 'Resultaten laden…'
1112
no_results:
1213
body: 'Probeer iets anders te zoeken'
1314
header: 'Geen resultaten gevonden'

src/Resources/translations/messages.no.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ setono_sylius_meilisearch:
88
price: Price
99
size: Size
1010
taxons: Category
11+
loading: 'Laster resultater…'
1112
no_results:
1213
body: 'Prøv å søke etter noe annet'
1314
header: 'Ingen resultater funnet'

0 commit comments

Comments
 (0)