Jump to an anchor after “Sort By” is changed on category page in Magento 2
-
02-10-2020 - |
Question
I'm developing a custom theme where the category page starts with some content and the list of products is below such content.
I would like to keep the view anchored to the product list when the user change the "Sort By" option. But it is executed some javascript and the page reload with an url like this:
http://example.com/plants?product_list_order=position
bringing the user back to the page top.
Would be enough for me to add an anchor in the url, like this:
http://example.com/plants?product_list_order=position#my-page-anchor
But I have no control on the url that is generated when the "Sort By" option change.
Is there a way to do this?
La solution
I ended up overriding the toolbar.js
file. I don't like to override Magento's javascript files, but it is the only solution I found. Maybe there is a simpler solution.
Below the parts I added to my theme.
File <theme_dir>/requirejs-config.js
:
var config = {
"map": {
"*": {
// ...
"productListToolbarForm": "js/toolbar",
}
},
// ...
}
File <theme_dir>/web/js/toolbar.js
, copied from
module-catalog/view/frontend/web/js/product/list/toolbar.js
options: {
// ...
anchor: '[data-role="anchor"]',
// ...
},
// ...
_processLink: function (event) {
event.preventDefault();
this.changeUrl(
event.data.paramName,
$(event.currentTarget).data('value'),
event.data.default,
$(event.currentTarget).data('anchor')
);
},
_processSelect: function (event) {
this.changeUrl(
event.data.paramName,
event.currentTarget.options[event.currentTarget.selectedIndex].value,
event.data.default,
$(event.currentTarget).data('anchor')
);
},
changeUrl: function (paramName, paramValue, defaultValue, anchor) {
// ...
if (anchor === undefined) {
anchor = '';
}
location.href =
baseUrl +
(paramData.length ? '?' + paramData : '') +
(anchor.length ? '#' + anchor : '');
}
File
<theme_dir>/base/Magento_Catalog/templates/product/list/toolbar/sorter.phtml
copied from
module-catalog/view/frontend/templates/product/list/toolbar/sorter.phtml
<div class="toolbar-sorter sorter">
<label class="sorter-label" for="sorter"><?php /* @escapeNotVerified */ echo __('Sort By') ?></label>
<select id="sorter" class="sorter-options"
data-role="sorter" data-anchor="my-page-anchor" >
...
</select>
<?php if ($block->getCurrentDirection() == 'desc'): ?>
<a title="<?php /* @escapeNotVerified */ echo __('Set Ascending Direction') ?>"
href="#" class="action sorter-action sort-desc"
data-role="direction-switcher" data-value="asc"
data-anchor="my-page-anchor">
<span><?php /* @escapeNotVerified */ echo __('Set Ascending Direction') ?></span>
</a>
<?php else: ?>
<a title="<?php /* @escapeNotVerified */ echo __('Set Descending Direction') ?>"
href="#" class="action sorter-action sort-asc"
data-role="direction-switcher" data-value="desc"
data-anchor="my-page-anchor">
<span><?php /* @escapeNotVerified */ echo __('Set Descending Direction') ?></span>
</a>
<?php endif; ?>
</div>
The idea is just to add a data-anchor
attribute on select and link tags. From the toolbar.js
we read the anchor and set it in the url.
You can see the above solution in action on this online store: http://latterialacollina.com/en/accessories?p=1#page-content