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?

Was it helpful?

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

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top