cancel
Showing results for 
Search instead for 
Did you mean: 

Page Jumping on Tab & Layered Navigation

SOLVED

Page Jumping on Tab & Layered Navigation

I have a Magento 2.3.3 site and when a tab or accordion link is clicked the page scrolls to top of content. How can I prevent this?

The filter tabs on the left (desktop only) http://designacake.co.uk/bakeware

The accordion at the bottom of the product section: http://designacake.co.uk/katy-sue-designs-mould-creative-cake-system-easy-fabric-puff

Thank you.

2 ACCEPTED SOLUTIONS

Accepted Solutions

Re: Page Jumping on Tab & Layered Navigation

Try this code in the mixin instead:

define(["jquery"], function($) {
  return function(widget) {
    $.widget("mage.collapsible", widget, {
      _create: function() {
        this.storage = $.localStorage;
        this.icons = false;

        if (typeof this.options.icons === "string") {
          this.options.icons = $.parseJSON(this.options.icons);
        }

        this._processPanels();
        this._processState();
        this._refresh();

        if (this.options.icons.header && this.options.icons.activeHeader) {
          this._createIcons();
          this.icons = true;
        }

        this._bind("click");
        this._trigger("created");
      }
    });
    return $.mage.collapsible;
  };
});

View solution in original post

Re: Page Jumping on Tab & Layered Navigation

The solution to this was to overwrite view.phtml in a custom theme /Magento_LayeredNavigation/templates/layer/view.phtml

 

Collapsible elements need the following arguments:

{
                            "accordion":
                            {
                                "openedState": "active",
                                "collapsible": true,
                                "active": false,
                                "multipleCollapsible": false,
                                "animate":{"duration":"200"}
                            }
                        }

For reference, my view.phtml is: 

 

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
?>
<?php
/**
 * Category layered navigation
 *
 * @var $block \Magento\LayeredNavigation\Block\Navigation
 */
?>

<?php if ($block->canShowBlock()) : ?>
    <div class="block filter" id="layered-filter-block" data-mage-init='
    {
        "collapsible":
        {
            "openedState": "active",
            "collapsible": true,
            "active": false,
            "collateral":
            {
                "openedState": "filter-active",
                "element": "body"
            }
        }
    }'>
        <?php $filtered = count($block->getLayer()->getState()->getFilters()) ?>
        <div class="block-title filter-title" data-count="<?= /* @noEscape */ $filtered ?>">
            <strong data-role="title"><?= $block->escapeHtml(__('Shop By')); ?></strong>
        </div>
        <div class="block-content filter-content">
            <?= $block->getChildHtml('state') ?>

            <?php if ($block->getLayer()->getState()->getFilters()) : ?>
                <div class="block-actions filter-actions">
                    <a href="<?= $block->escapeUrl($block->getClearUrl()) ?>" class="action clear filter-clear">
                        <span><?= $block->escapeHtml(__('Clear All')) ?></span>
                    </a>
                </div>
            <?php endif; ?>
            <?php $wrapOptions = false; ?>
            <?php foreach ($block->getFilters() as $filter) : ?>

            <!-- Attribute the filter title as a class of the filter title -->
            <!-- Currently used to hide Brand filter on Ves Brand pages -->
            <?php $filtertitle = $filter->getName();
            $filtertitle = strtolower($filtertitle);
            $filtertitle = preg_replace("/[\s_]/", "-", $filtertitle);
            ?>

                <?php if ($filter->getItemsCount()) : ?>
                    <?php if (!$wrapOptions) : ?>
                        <strong role="heading" aria-level="2" class="block-subtitle filter-subtitle"><?= $block->escapeHtml(__('Shopping Options')) ?></strong>
                        <div class="filter-options" id="narrow-by-list" data-role="content" data-mage-init='
                        {
                            "accordion":
                            {
                                "openedState": "active",
                                "collapsible": true,
                                "active": false,
                                "multipleCollapsible": false,
                                "animate":{"duration":"200"}
                            }
                        }'>
                        <?php $wrapOptions = true;
                        endif; ?>
                    <div data-role="collapsible" class="filter-options-item <?php echo $filtertitle; ?>">
                        <div data-role="title" class="filter-options-title"><?= $block->escapeHtml(__($filter->getName())) ?></div>
                        <div data-role="content" class="filter-options-content"><?= /* @noEscape */ $block->getChildBlock('renderer')->render($filter) ?></div>
                    </div>
                <?php endif; ?>
            <?php endforeach; ?>
            <?php if ($wrapOptions) : ?>
                </div>
            <?php else : ?>
                <script>
                    require([
                        'jquery'
                    ], function ($) {
                        $('#layered-filter-block').addClass('filter-no-options');
                    });
                </script>
            <?php endif; ?>
        </div>
    </div>
<?php endif; ?>

 

View solution in original post

6 REPLIES 6

Re: Page Jumping on Tab & Layered Navigation

Having the same issue.  (using tabs, accordions,  or drop down selectors it seems) Anyone?  M2.3.3

Re: Page Jumping on Tab & Layered Navigation

To do this we have to create requirejs-config.js under app/design/frontend/<VendorName>/<ThemeName>/requirejs-config.js

and add below content 

 

var config = {    config: {        mixins: {
            'mage/collapsible': {
                'js/mage/collapsible-mixin': true
            }
        }
    }
};

 

add file app/design/frontend/<VendorName>/<ThemeName>/web/js/mage/collapsible-mixin.js and add below content 

 

define([
    'jquery',
], function ($) {

    var hideProps = {},        showProps = {};    hideProps.height =  'hide';    showProps.height =  'show';

    return function (widget) {        $.widget('mage.collapsible', widget, {            options: {                scrollTo: false
            },            _create: function () {
                this.storage = $.localStorage;
                this.icons = false;

                if (typeof this.options.icons === 'string') {
                    this.options.icons = $.parseJSON(this.options.icons);
                }

                this._processPanels();
                this._processState();
                this._refresh();

                if (this.options.icons.header && this.options.icons.activeHeader) {
                    this._createIcons();
                    this.icons = true;
                }

                if (this.options.scrollTo) {
                    this.element.on('dimensionsChanged', function (e) {
                        if (e.target && e.target.classList.contains('active')) {
                            this._scrollToTopIfVisible(e.target);
                        }
                    }.bind(this));
                }

                this._bind('click');
                this._trigger('created');
            },
        });

        return $.mage.collapsible;
    };
});

 

Later,

Deploy: php bin/magento s:up && php bin/magento s:s:d -f

 

That's it.

 

Enjoy !!

Re: Page Jumping on Tab & Layered Navigation

By implementing the above code it stopped clicking on all other collapsible/toggle widgets. For example, it is stopped expanding for the discount code section and the summary section on the cart page. Also, it is stopped expanding on checkout page right sidebar.

Re: Page Jumping on Tab & Layered Navigation

Try this code in the mixin instead:

define(["jquery"], function($) {
  return function(widget) {
    $.widget("mage.collapsible", widget, {
      _create: function() {
        this.storage = $.localStorage;
        this.icons = false;

        if (typeof this.options.icons === "string") {
          this.options.icons = $.parseJSON(this.options.icons);
        }

        this._processPanels();
        this._processState();
        this._refresh();

        if (this.options.icons.header && this.options.icons.activeHeader) {
          this._createIcons();
          this.icons = true;
        }

        this._bind("click");
        this._trigger("created");
      }
    });
    return $.mage.collapsible;
  };
});

Re: Page Jumping on Tab & Layered Navigation

This works for me along with the requirejs-config.js under app/design/frontend/<VendorName>/<ThemeName>/requirejs-config.js

Thank you very much!

Re: Page Jumping on Tab & Layered Navigation

The solution to this was to overwrite view.phtml in a custom theme /Magento_LayeredNavigation/templates/layer/view.phtml

 

Collapsible elements need the following arguments:

{
                            "accordion":
                            {
                                "openedState": "active",
                                "collapsible": true,
                                "active": false,
                                "multipleCollapsible": false,
                                "animate":{"duration":"200"}
                            }
                        }

For reference, my view.phtml is: 

 

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
?>
<?php
/**
 * Category layered navigation
 *
 * @var $block \Magento\LayeredNavigation\Block\Navigation
 */
?>

<?php if ($block->canShowBlock()) : ?>
    <div class="block filter" id="layered-filter-block" data-mage-init='
    {
        "collapsible":
        {
            "openedState": "active",
            "collapsible": true,
            "active": false,
            "collateral":
            {
                "openedState": "filter-active",
                "element": "body"
            }
        }
    }'>
        <?php $filtered = count($block->getLayer()->getState()->getFilters()) ?>
        <div class="block-title filter-title" data-count="<?= /* @noEscape */ $filtered ?>">
            <strong data-role="title"><?= $block->escapeHtml(__('Shop By')); ?></strong>
        </div>
        <div class="block-content filter-content">
            <?= $block->getChildHtml('state') ?>

            <?php if ($block->getLayer()->getState()->getFilters()) : ?>
                <div class="block-actions filter-actions">
                    <a href="<?= $block->escapeUrl($block->getClearUrl()) ?>" class="action clear filter-clear">
                        <span><?= $block->escapeHtml(__('Clear All')) ?></span>
                    </a>
                </div>
            <?php endif; ?>
            <?php $wrapOptions = false; ?>
            <?php foreach ($block->getFilters() as $filter) : ?>

            <!-- Attribute the filter title as a class of the filter title -->
            <!-- Currently used to hide Brand filter on Ves Brand pages -->
            <?php $filtertitle = $filter->getName();
            $filtertitle = strtolower($filtertitle);
            $filtertitle = preg_replace("/[\s_]/", "-", $filtertitle);
            ?>

                <?php if ($filter->getItemsCount()) : ?>
                    <?php if (!$wrapOptions) : ?>
                        <strong role="heading" aria-level="2" class="block-subtitle filter-subtitle"><?= $block->escapeHtml(__('Shopping Options')) ?></strong>
                        <div class="filter-options" id="narrow-by-list" data-role="content" data-mage-init='
                        {
                            "accordion":
                            {
                                "openedState": "active",
                                "collapsible": true,
                                "active": false,
                                "multipleCollapsible": false,
                                "animate":{"duration":"200"}
                            }
                        }'>
                        <?php $wrapOptions = true;
                        endif; ?>
                    <div data-role="collapsible" class="filter-options-item <?php echo $filtertitle; ?>">
                        <div data-role="title" class="filter-options-title"><?= $block->escapeHtml(__($filter->getName())) ?></div>
                        <div data-role="content" class="filter-options-content"><?= /* @noEscape */ $block->getChildBlock('renderer')->render($filter) ?></div>
                    </div>
                <?php endif; ?>
            <?php endforeach; ?>
            <?php if ($wrapOptions) : ?>
                </div>
            <?php else : ?>
                <script>
                    require([
                        'jquery'
                    ], function ($) {
                        $('#layered-filter-block').addClass('filter-no-options');
                    });
                </script>
            <?php endif; ?>
        </div>
    </div>
<?php endif; ?>