How to stop scrolling to first validation error message on magento2 on add to cart?
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();
}
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;
}
});