最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Bootstrap 4: add a "scroll to first invalid field" to a don't "Submit"

programmeradmin2浏览0评论

I am using Bootstrap 4 and i am stopping form submission if any of the fields are invalid with the below script. I am trying to figure out (with no success so far) what code do i need to add after the "event.stopPropagation();" in order to make the form scroll to the first invalid field that was found. Appreciate your help, thanks.

Form:

<form class="needs-validation" novalidate action="search.php" id="firstform" method="post" >

Prevent submission if invalid:

  <script>
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function() {
  'use strict';
  window.addEventListener('load', function() {
    // Fetch all the forms we want to apply custom Bootstrap validation styles to
    var forms = document.getElementsByClassName('needs-validation');
    // Loop over them and prevent submission
    var validation = Array.prototype.filter.call(forms, function(form) {
      form.addEventListener('submit', function(event) {
        if (form.checkValidity() === false) {
          event.preventDefault();
          event.stopPropagation();
        }
        form.classList.add('was-validated');
      }, false);
    });
  }, false);
})();
</script>

Found the below code but couldn't find a way to embed it into the "disabling form submissions" script or use it as a standalone script:

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

        if (!validator.numberOfInvalids())
            return;

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

    }
});

I am using Bootstrap 4 and i am stopping form submission if any of the fields are invalid with the below script. I am trying to figure out (with no success so far) what code do i need to add after the "event.stopPropagation();" in order to make the form scroll to the first invalid field that was found. Appreciate your help, thanks.

Form:

<form class="needs-validation" novalidate action="search.php" id="firstform" method="post" >

Prevent submission if invalid:

  <script>
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function() {
  'use strict';
  window.addEventListener('load', function() {
    // Fetch all the forms we want to apply custom Bootstrap validation styles to
    var forms = document.getElementsByClassName('needs-validation');
    // Loop over them and prevent submission
    var validation = Array.prototype.filter.call(forms, function(form) {
      form.addEventListener('submit', function(event) {
        if (form.checkValidity() === false) {
          event.preventDefault();
          event.stopPropagation();
        }
        form.classList.add('was-validated');
      }, false);
    });
  }, false);
})();
</script>

Found the below code but couldn't find a way to embed it into the "disabling form submissions" script or use it as a standalone script:

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

        if (!validator.numberOfInvalids())
            return;

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

    }
});
Share Improve this question edited Aug 1, 2018 at 0:50 Muhammad Omer Aslam 23.7k9 gold badges46 silver badges69 bronze badges asked May 13, 2018 at 18:49 Mark.DMark.D 511 gold badge1 silver badge6 bronze badges
Add a comment  | 

5 Answers 5

Reset to default 13

You should use the input.form-control:invalid pseudo selector that is added to the elements you’ll see the :invalid and :valid styles applied to your form controls.

Although using custom validation you have to look for a lot of things that this article can cover up for you.

We will use the above selector document.querySelectorAll("input.form-control:invalid"); to get all the error fields list and scroll to the first error element in the form in case there are multiple errors.

See a demo below.

// Example starter JavaScript for disabling form submissions if there are invalid fields
(function() {
  'use strict';
  window.addEventListener('load', function() {
    // Fetch all the forms we want to apply custom Bootstrap validation styles to
    var forms = document.getElementsByClassName('needs-validation');
    // Loop over them and prevent submission
    var validation = Array.prototype.filter.call(forms, function(form) {
      form.addEventListener('submit', function(event) {

        if (form.checkValidity() === false) {
          event.preventDefault();
          event.stopPropagation();

          var errorElements = document.querySelectorAll(
            "input.form-control:invalid");
          errorElements.forEach(function(element) {
            element.parentNode.childNodes.forEach(function(node) {
              if (node.className == 'valid-feedback') {
                node.className = 'invalid-feedback';
                node.innerText =
                  'Please choose a Gender';
              }
            });
          });
          $('html, body').animate({
            scrollTop: $(errorElements[0]).offset().top
          }, 2000);
        }
        form.classList.add('was-validated');
      }, false);
    });
  }, false);
})();
input[type=text],
input[type=email],
input[type=number],
textarea,
fieldset {
  /* required to properly style form 
   elements on WebKit based browsers */
  -webkit-appearance: none;
  width: 100%;
  border: 1px solid #333;
  margin: 0;
  font-family: inherit;
  font-size: 90%;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

<form class="needs-validation" novalidate>
  <div class="form-row">
    <div class="col-md-4 mb-3">
      <label for="gender">Male</label>
      <input id="gender_male" type="radio" name="gender" class="form-control col-sm-2" required>
      <label for="gender">Female</label>
      <input id="gender_female" type="radio" name="gender" class="form-control col-sm-2">
      <label for="gender">Other</label>
      <input id="gender_other" type="radio" name="gender" class="form-control col-sm-2">

      <div class="valid-feedback">
        Looks good!
      </div>
    </div>
  </div>
  <div class="form-row">
    <div class="col-md-4 mb-3">
      <label for="validationCustom01">First name</label>
      <input type="text" class="form-control" id="validationCustom01" placeholder="First name" value="Mark" required>
      <div class="valid-feedback">
        Looks good!
      </div>
    </div>
    <div class="col-md-4 mb-3">
      <label for="validationCustom02">Last name</label>
      <input type="text" class="form-control" id="validationCustom02" placeholder="Last name" value="Otto" required>
      <div class="valid-feedback">
        Looks good!
      </div>
    </div>

  </div>
  <div class="form-row">
    <div class="col-md-4 mb-3">
      <label for="validationCustomUsername">Username</label>
      <div class="input-group">
        <div class="input-group-prepend">
          <span class="input-group-text" id="inputGroupPrepend">@</span>
        </div>
        <input type="text" class="form-control" id="validationCustomUsername" placeholder="Username" aria-describedby="inputGroupPrepend" required>
        <div class="invalid-feedback">
          Please choose a username.
        </div>
      </div>
    </div>
  </div>
  <div class="form-row">
    <div class="col-md-6 mb-3">
      <label for="validationCustom03">City</label>
      <input type="text" class="form-control" id="validationCustom03" placeholder="City" required>
      <div class="invalid-feedback">
        Please provide a valid city.
      </div>
    </div>

  </div>
  <div class="form-row">
    <div class="col-md-3 mb-3">
      <label for="validationCustom04">State</label>
      <input type="text" class="form-control" id="validationCustom04" placeholder="State" required>
      <div class="invalid-feedback">
        Please provide a valid state.
      </div>
    </div>
    <div class="col-md-3 mb-3">
      <label for="validationCustom05">Zip</label>
      <input type="text" class="form-control" id="validationCustom05" placeholder="Zip" required>
      <div class="invalid-feedback">
        Please provide a valid zip.
      </div>
    </div>
  </div>
  <div class="form-row">
    <div class="col-md-3 mb-3">
      <label for="validationCustom05">Zip</label>
      <input type="text" class="form-control" id="validationCustom05" placeholder="Zip" required>
      <div class="invalid-feedback">
        Please provide a valid zip.
      </div>
    </div>
  </div>
  <div class="form-group">
    <div class="form-check">
      <input class="form-check-input" type="checkbox" value="" id="invalidCheck" required>
      <label class="form-check-label" for="invalidCheck">
                Agree to terms and conditions
            </label>
      <div class="invalid-feedback">
        You must agree before submitting.
      </div>
    </div>
  </div>
  <button class="btn btn-primary" type="submit">Submit form</button>
</form>

If you are using jQuery and only supporting modern browsers (which is likely if you're using Bootstrap 4), you can use the following code to validate the form and scroll to the field with an error:

$('form#contact').submit(function(e) {
    var form = $(this);

    // HTML5 validility checker
    if (form[0].checkValidity() === false) {
        // not valid
        form.addClass('was-validated');
        $('html,body').animate({scrollTop: $('.was-validated .form-control:invalid').first().offset().top - 50},'slow');
        e.preventDefault();
        e.stopPropagation();
        return;
    }
    // valid, do something else ...
});

Just add these two lines

var errorElements = document.querySelectorAll(".form-control:invalid");
$(errorElements[0]).focus(); 

after

event.stopPropagation();

Putting focus to the first invalid field will automatically scroll the page to that position i in most of the browsers.

Sergej, this worked great!

I modified it as below so that checkboxes/radio buttons and drop-down menus are also detected.

var errorElements = document.querySelectorAll(".form-control:invalid, .form-check-input:invalid, .form-select:invalid");

Try this:

$( "input[type=submit]" ).click(function() {
    event.preventDefault();
    event.stopPropagation();
    //  console.log("test")
    var errorElements = document.querySelectorAll(".input-validation-error");
  for (let index = 0; index < errorElements.length; index++) {
      const element = errorElements[index];
    //  console.log(element);
      $('html, body').animate({
        scrollTop: $(errorElements[0]).focus().offset().top - 25
      }, 1000);      
      return false;
  }
});

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论