commit
d2d9b56200
5 changed files with 143 additions and 0 deletions
@ -0,0 +1,46 @@ |
|||||||
|
# Preserve Advanced Search |
||||||
|
|
||||||
|
Keeps the advanced search `a[]` query parameters attached to the facet slider |
||||||
|
URLs that Facets builds server-side, so clicking a slider doesn't drop the |
||||||
|
user's advanced search criteria. |
||||||
|
|
||||||
|
Replaces the equivalent code that previously lived in individual themes |
||||||
|
(`THEME.libraries.yml` + `THEME_preprocess_page()`). |
||||||
|
|
||||||
|
## Install |
||||||
|
|
||||||
|
Copy this directory to `web/modules/custom/preserve_advanced_search` on each |
||||||
|
site, then: |
||||||
|
|
||||||
|
drush en preserve_advanced_search |
||||||
|
drush cr |
||||||
|
|
||||||
|
## Scope |
||||||
|
|
||||||
|
`hook_library_info_alter()` appends this module's library to the dependencies of |
||||||
|
`facets_range_nouislider/facets_range_nouislider`. It therefore loads only on |
||||||
|
pages that actually render a noUiSlider facet — not site-wide, and with no route |
||||||
|
list to maintain per site. |
||||||
|
|
||||||
|
Library info is cached, so run `drush cr` after deploying or the alter won't |
||||||
|
take effect. |
||||||
|
|
||||||
|
If a site configures its facets with the **Facets core** slider widget |
||||||
|
(`facets_range_widget`) instead of `facets_range_nouislider`, add that |
||||||
|
extension's library to the alter as well. Both submodules write to |
||||||
|
`drupalSettings.facets.sliders`, so the JavaScript itself needs no change — only |
||||||
|
the attachment point does. |
||||||
|
|
||||||
|
## Notes |
||||||
|
|
||||||
|
- Load order is guaranteed by the dependency: our script is loaded ahead of |
||||||
|
`slider.js`, so `Drupal.behaviors.preserveAdvancedSearchParams` is registered |
||||||
|
first and runs first. `facets_range_nouislider`'s `slider.js` is additionally |
||||||
|
marked `defer: true` while ours is not, and non-deferred scripts always |
||||||
|
execute before deferred ones — so the ordering holds twice over. |
||||||
|
- `rebuildUrl()` is idempotent (it strips all `a[]` params before re-adding the |
||||||
|
current ones), so re-running on AJAX rebuilds is safe. |
||||||
|
- The JS handles both `sliderSettings.url` and `sliderSettings.urls`. Range |
||||||
|
widgets collapse the parent's `urls` map into a single `url` |
||||||
|
(`RangeNoUiSliderWidget::build()`); single-handle widgets keep `urls`. Both |
||||||
|
branches are live — don't remove either. |
||||||
@ -0,0 +1,59 @@ |
|||||||
|
(function (Drupal, drupalSettings) { |
||||||
|
'use strict'; |
||||||
|
|
||||||
|
Drupal.behaviors.preserveAdvancedSearchParams = { |
||||||
|
attach: function (context, settings) { |
||||||
|
|
||||||
|
// Capture the a[] advanced search params from the current URL
|
||||||
|
const rawSearch = window.location.search; |
||||||
|
const aParams = rawSearch |
||||||
|
.substring(1) |
||||||
|
.split('&') |
||||||
|
.filter(part => part.startsWith('a%5B') || part.startsWith('a[')) |
||||||
|
.join('&'); |
||||||
|
|
||||||
|
if (!aParams) return; |
||||||
|
|
||||||
|
const sliders = settings.facets && settings.facets.sliders; |
||||||
|
if (!sliders) return; |
||||||
|
|
||||||
|
// Replace any a[] params in a URL with the current page's a[] params.
|
||||||
|
// The current URL is always the source of truth — the server-built
|
||||||
|
// slider URL may contain stale or partial a[] params.
|
||||||
|
function rebuildUrl(url) { |
||||||
|
if (!url) return url; |
||||||
|
const parts = url.split('?'); |
||||||
|
const basePath = parts[0]; |
||||||
|
const query = parts[1] || ''; |
||||||
|
|
||||||
|
// Keep everything that is NOT an a[] param (i.e. the f[] facet params)
|
||||||
|
const keptParams = query |
||||||
|
.split('&') |
||||||
|
.filter(p => p.length > 0) |
||||||
|
.filter(p => !p.startsWith('a%5B') && !p.startsWith('a[')) |
||||||
|
.join('&'); |
||||||
|
|
||||||
|
const finalQuery = [keptParams, aParams].filter(Boolean).join('&'); |
||||||
|
return basePath + '?' + finalQuery; |
||||||
|
} |
||||||
|
|
||||||
|
// Range sliders expose a single `url`; single-handle sliders expose a
|
||||||
|
// `urls` map keyed by value. Handle both — which one is present depends
|
||||||
|
// on the widget the facet is configured with.
|
||||||
|
Object.keys(sliders).forEach(function (key) { |
||||||
|
const sliderSettings = sliders[key]; |
||||||
|
|
||||||
|
if (sliderSettings.url) { |
||||||
|
sliderSettings.url = rebuildUrl(sliderSettings.url); |
||||||
|
} |
||||||
|
|
||||||
|
if (sliderSettings.urls) { |
||||||
|
Object.keys(sliderSettings.urls).forEach(function (urlKey) { |
||||||
|
sliderSettings.urls[urlKey] = rebuildUrl(sliderSettings.urls[urlKey]); |
||||||
|
}); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
})(Drupal, drupalSettings); |
||||||
@ -0,0 +1,5 @@ |
|||||||
|
name: 'Preserve Advanced Search' |
||||||
|
type: module |
||||||
|
description: 'Keeps advanced search a[] query parameters attached to facet slider URLs built by the server.' |
||||||
|
package: 'Custom' |
||||||
|
core_version_requirement: ^10 || ^11 |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
preserve-advanced-search: |
||||||
|
version: VERSION |
||||||
|
js: |
||||||
|
js/preserve-advanced-search.js: {} |
||||||
|
dependencies: |
||||||
|
- core/drupal |
||||||
|
- core/drupalSettings |
||||||
@ -0,0 +1,26 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/** |
||||||
|
* @file |
||||||
|
* Preserves advanced search a[] parameters on facet slider URLs. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* Implements hook_library_info_alter(). |
||||||
|
* |
||||||
|
* Attaches the fix-up library as a dependency of the slider widget library |
||||||
|
* rather than to every page. This scopes it to the pages that actually render |
||||||
|
* a slider, and guarantees our script loads first so the behavior is |
||||||
|
* registered — and therefore runs — before the slider reads |
||||||
|
* drupalSettings.facets.sliders. |
||||||
|
*/ |
||||||
|
function preserve_advanced_search_library_info_alter(array &$libraries, $extension) |
||||||
|
{ |
||||||
|
if ($extension !== 'facets_range_nouislider') { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (isset($libraries['facets_range_nouislider'])) { |
||||||
|
$libraries['facets_range_nouislider']['dependencies'][] = 'preserve_advanced_search/preserve-advanced-search'; |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue