How to stop scrolling to top or first validation failure message
2 Answers
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();
}
-
3Overwriting the whole file just to remove 3 lines is not a good idea. See my answer for a solution with a JS mixin. Aug 16, 2019 at 10:53
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;
}
});