10

How to stop scrolling to top or first validation failure message

enter image description here

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

2 Answers 2

17

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
  • 3
    Overwriting the whole file just to remove 3 lines is not a good idea. See my answer for a solution with a JS mixin. Commented Aug 16, 2019 at 10:53
14

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;
    }
});
2
  • Works well... :D
    – Sumit
    Commented Nov 10, 2020 at 9:22
  • Yes yes yes, proper answer!
    – 00-BBB
    Commented Nov 17, 2020 at 15:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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