Skip to content

Commit

Permalink
[FINNA-2652] Fix sort in collectionlist tab (#3121)
Browse files Browse the repository at this point in the history
  • Loading branch information
LuomaJuha authored Jan 28, 2025
1 parent 40a86e3 commit e3f164d
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 50 deletions.
108 changes: 62 additions & 46 deletions themes/finna2/js/finna-common.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,54 +81,70 @@ finna.common = (function finnaCommon() {
VuFind.listen('results-loaded', () => {
initResultScripts(document.querySelector('.js-result-list'), false);
});

// Set up Finna's dropdown-based sort and limit controls:
document.querySelectorAll('.search-controls .sort-option-container .dropdown-menu a, .search-controls .limit-option-container .dropdown-menu a').forEach(link => {
if (link.dataset.ajaxPagination) {
return;
/**
* Set up Finna's dropdown-based sort and limit controls:
* Objects contain following data:
* - dropdownWrapperSelector targets root element for the dropdowns
* - type declares the dropdowns type
* - hiddenSelectSelector targets the hidden select which is required to do a search after
* selecting new value from the dropdown
* - ariaLabelTemplate updates the toggle buttons aria label after selecting new value
* - sessionSaveSelector Save the last clicked menu item into session storage to retain
* focus after loading new results
*/
const dropdownMappings = [
{
dropdownWrapperSelector: '.search-controls .sort-option-container .dropdown',
type: 'sort',
hiddenSelectSelector: '.search-controls form.search-sort select',
ariaLabelTemplate: `${VuFind.translate('Sort')}: %%linkText%% ${VuFind.translate('selected')}`,
sessionSaveSelector: 'sort-dropdown a.dropdown-toggle',
},
{
dropdownWrapperSelector: '.search-controls .limit-option-container .dropdown',
type: 'limit',
hiddenSelectSelector: '.search-controls form.search-result-limit select',
ariaLabelTemplate: `${VuFind.translate('Results per page')}: %%linkText%% ${VuFind.translate('selected')}`,
sessionSaveSelector: 'limit-dropdown a.dropdown-toggle',
}
link.dataset.ajaxPagination = true;
const type = link.closest('.sort-option-container') ? 'sort' : 'limit';
const selectors = {
sort: '.search-controls form.search-sort select',
limit: '.search-controls form.search-result-limit select'
};
link.addEventListener('click', function handleClick(event) {
event.preventDefault();
window.sessionStorage.setItem('clickedMenu', `${type}-dropdown a.dropdown-toggle`);
// Update button text:
const dropdownEl = link.closest('.dropdown');
const dropdownLabel = type === 'sort' ? 'Sort' : 'Results per page';
if (dropdownEl) {
const toggleEl = dropdownEl.querySelector('.dropdown-toggle');
if (toggleEl) {
toggleEl.ariaLabel = VuFind.translate(dropdownLabel) + ': ' + VuFind.translate(link.innerText) + ' ' + VuFind.translate('selected');
const spanEl = toggleEl.querySelector('span');
if (spanEl) {
spanEl.innerText = link.innerText;
}
}
const menuEl = dropdownEl.querySelector('.dropdown-menu');
if (menuEl) {
menuEl.querySelectorAll("li > a").forEach(element => {
if (element.ariaDescription) {
element.removeAttribute("aria-description");
}
if (element.innerText.trim() === toggleEl.innerText.trim()) {
element.ariaDescription = VuFind.translate('selected');
}
});
}
}
// Get relevant data from the link and change the hidden field accordingly:
const urlParts = link.getAttribute('href').split('?', 2);
const query = new URLSearchParams(urlParts.length > 1 ? urlParts[1] : '');
const newValue = query.get(type);
const field = document.querySelector(selectors[type]);
if (field) {
field.value = newValue;
field.dispatchEvent(new Event('change'));
];
dropdownMappings.forEach(mapping => {
document.querySelectorAll(mapping.dropdownWrapperSelector).forEach(dropdown => {
const dropdownMenu = dropdown.querySelector('.dropdown-menu');
if (!dropdownMenu) {
return;
}
const toggleDropdown = dropdown.querySelector('.dropdown-toggle');
const toggleSpan = toggleDropdown ? toggleDropdown.querySelector(':scope > span') : undefined;
const hiddenSelectElement = document.querySelector(mapping.hiddenSelectSelector);
dropdownMenu.querySelectorAll('a').forEach((link) => {
if (link.dataset.ajaxPagination) {
return;
}
link.dataset.ajaxPagination = true;
link.addEventListener('click', function handleClick(event) {
event.preventDefault();
window.sessionStorage.setItem('clickedMenu', mapping.sessionSaveSelector);
// Update button text:
if (toggleDropdown) {
toggleDropdown.ariaLabel
= mapping.ariaLabelTemplate.slice(0).replace('%%linkText%%', VuFind.translate(link.innerText));
}
if (toggleSpan) {
toggleSpan.innerText = link.innerText;
}
dropdownMenu.querySelectorAll('li > a').forEach(el => el.removeAttribute('aria-description'));
link.setAttribute('aria-description', 'selected');
// Get relevant data from the link and change the hidden field accordingly:
const urlParts = link.getAttribute('href').split('?', 2);
const query = new URLSearchParams(urlParts.length > 1 ? urlParts[1] : '');
const newValue = query.get(mapping.type);
if (hiddenSelectElement) {
hiddenSelectElement.value = newValue;
hiddenSelectElement.dispatchEvent(new Event('change'));
}
});
});
});
});
}
Expand Down
2 changes: 1 addition & 1 deletion themes/finna2/templates/RecordTab/collectionlist.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Get search results
$results = $this->tab->getResults();
$params = $this->tab->getParams();
$searchDetails = ['results' => $results, 'params' => $params, 'indexStart' => 1, 'isCollection' => true];
$searchDetails = ['results' => $results, 'params' => $params, 'indexStart' => 1, 'isCollection' => true, 'context' => 'CollectionList'];
?>
<div class="collection-list-controls">
<div class="filter-input">
Expand Down
9 changes: 6 additions & 3 deletions themes/finna2/templates/search/controls/sort.phtml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<!-- START of: finna - search/controls/sort.phtml -->
<?php $list = $this->sortList ? $this->sortList : $this->params->getSortList();
if (!empty($list)): ?>
<?php
$list = $this->sortList ? $this->sortList : $this->params->getSortList();
$context = $this->context ?: 'Results';
if (!empty($list)):
?>
<div class="sort-option-container">
<span class="hidden-sm hidden-xs hidden-md button-label" id="sort-label"><?=$this->transEsc('Sort')?></span>
<span class="sr-only hidden-lg hidden-md"><?=$this->transEsc('Sort')?></span>
Expand All @@ -23,7 +26,7 @@ if (!empty($list)): ?>
<ul class="dropdown-menu" role="menu" aria-labelledby="sort-label">
<?php foreach ($list as $sortType => $sortData): ?>
<li>
<a href="Results<?=isset($sortData['url']) ? $this->escapeHtmlAttr($sortData['url']) : $this->results->getUrlQuery()->setSort($sortType)?>" role="menuitem" <?php if ($sortData['selected']):?>aria-description="<?=$this->transEsc('selected')?>"<?php endif;?>><?=$this->transEsc($sortData['desc'])?></a>
<a href="<?=$this->escapeHtmlAttr($context) ?><?=isset($sortData['url']) ? $this->escapeHtmlAttr($sortData['url']) : $this->results->getUrlQuery()->setSort($sortType)?>" role="menuitem" <?php if ($sortData['selected']):?>aria-description="<?=$this->transEsc('selected')?>"<?php endif;?>><?=$this->transEsc($sortData['desc'])?></a>
<?php endforeach; ?>
</li>
</ul>
Expand Down

0 comments on commit e3f164d

Please sign in to comment.