When form is validated, how to SCROLL to the first error instead of jumping?

Here's what you can do:

  • By default the validate plugin focuses the first erroneous element (in case there's any). Turn off the option focusInvalid by setting it to false.

  • The callback invalidHandler handler is executed when the form is invalid. You get access through the second parameter validator to the validator object and thus to the errorList array. You can then animate the scroll relatively to the first erroneous element.

Here's the code:

$("#commentForm").validate({
    focusInvalid: false,
    invalidHandler: function(form, validator) {

        if (!validator.numberOfInvalids())
            return;

        $('html, body').animate({
            scrollTop: $(validator.errorList[0].element).offset().top
        }, 2000);

    }
});

DEMO


For Anyone Using HTML5 Validation + Vanilla JavaScript:

Not a direct answer to this question, but as this is the main post that comes up when searching for this question, I figured I'd post my solution here for anyone who's looking as well!

I'm using this in my ReactJS project, but it should work in just about any vanilla ES6 JavaScript setting using modern browsers, as well.

function scrollToInvalid(form) {
  const invalidInputs = Array.from(form.querySelectorAll(':invalid, .is-invalid [, .custom-invalid-selector]'));    // set up so you can use any custom invalid classes you're adding to your elements, as well
  invalidInputs.sort((a, b) => a.getBoundingClientRect().top - b.getBoundingClientRect().top);                      // sort inputs by offset from top of viewport (handles issues with multi-column layouts, where the first element in the markup isn't necessarily the highest on the page)
  invalidInputs[0].scrollIntoView({ block: 'center', behavior: 'smooth' });                                         // scroll first (top) input into center of view, using smooth animation
}

function handleSubmit(e) {
  const form = e.currentTarget;

  if (form.checkValidity() === false ) {
    // form is invalid, don't submit
    e.preventDefault();
    e.stopPropagation();
    // scroll first invalid input into view
    scrollToInvalid(form);
  }
  else {
    // form is valid, handle submit...
  }
}
<form onSubmit="handleSubmit">
  ...
</form>

just add this code to your themes javascript:

(function($) {
$(document).ready(function(){
    //bmo scroll to not valid
    $(".wpcf7").on('invalid.wpcf7',function(e){
        $('html, body').animate({
                scrollTop: $(".wpcf7-not-valid").first().offset().top-30
            }, 2000);
    });

});
})(jQuery);

I dont like all the jQuery extentions so here is my solution to this problem:

if ($('#MYID').valid()) {
      //dosomething();
} else {
    $('html, body').animate({
         scrollTop: ($('.error').offset().top - 300)
    }, 2000);
}