9

How to stop scrolling to top or first validation failure message

enter image description here

  • Did u find an answer? I am looking for the same. – Sejal Shah May 8 at 12:30
11

Copy

MAGENTO_ROOT/vendor/magento/magento2-base/lib/web/mage/validation.js

into app/design/frontend/THEME_ROOT/web/mage/

then delete (start in line 1956)

if (firstActive.length) {
                $('html, body').animate({
                    scrollTop: firstActive.offset().top
                });
                firstActive.focus();
            }

become

if (firstActive.length) {

                firstActive.focus();
            }
  • 1
    Overwriting the whole file just to remove 3 lines is not a good idea. See my answer for a solution with a JS mixin. – Daniel Kratohvil Aug 16 at 10:53
5

Here is a solution with a mixin to avoid overwriting the whole file:

1) app/design/frontend/[THEME_VENDOR]/[THEME_NAME]/Magento_Theme/requirejs-config.js

var config = {
    config: {
        mixins: {
            'mage/validation': {
                'Magento_Theme/js/lib/mage/validation-mixin': true
            }
        }
    }
};

2) app/design/frontend/[THEME_VENDOR]/[THEME_NAME]/Magento_Theme/web/js/lib/mage/validation-mixin.js

define([
    'jquery'
], function ($) {
    'use strict';

    return function (widget) {

        $.widget('mage.validation', widget, {
            /**
             * Handle form validation. Focus on first invalid form field.
             *
             * @param {jQuery.Event} event
             * @param {Object} validation
             */
            listenFormValidateHandler: function (event, validation) {
                let firstActive = $(validation.errorList[0].element || []),
                    lastActive = $(validation.findLastActive() ||
                        validation.errorList.length && validation.errorList[0].element || []),
                    parent, windowHeight, successList;

                if (lastActive.is(':hidden')) {
                    parent = lastActive.parent();
                    windowHeight = $(window).height();
                    $('html, body').animate({
                        scrollTop: parent.offset().top - windowHeight / 2
                    });
                }

                // ARIA (removing aria attributes if success)
                successList = validation.successList;

                if (successList.length) {
                    $.each(successList, function () {
                        $(this)
                            .removeAttr('aria-describedby')
                            .removeAttr('aria-invalid');
                    });
                }

                if (firstActive.length) {
                    /* vertically center the first field on the screen. This is best for UX but if you prefer to avoid the scrolling completelly, just remove the next line and the function "scrollToCenterFormFieldOnError" below. */
                    scrollToCenterFormFieldOnError(firstActive);
                    firstActive.focus();
                }
            }
        });

        function scrollToCenterFormFieldOnError(firstActive) {
            let fieldTop = firstActive.offset().top,
                fieldHeight = firstActive.height(),
                windowHeight = $(window).height(),
                offset;

            offset = fieldTop - ((windowHeight / 2) - (fieldHeight / 2));

            $('html, body').stop().animate({
                scrollTop: offset
            });
        }

        return $.mage.validation;
    }
});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.