проверка bootstrap 4 отключить кнопку отправки до проверки формы

В следующем примере моей проблемы у меня есть 2 поля, которые необходимо проверить.
Пока все (в данном случае 2) поля не будут проверены, кнопка отправки должна быть отключена.
Если оба проверены, она должна быть включена.

Моя проблема: в ту минуту, когда проверяется первое поле, кнопка активируется, что слишком рано.
Я понимаю (но не думаю, что знаю), что это происходит из-за того, где я разместил $("#submitBtn").attr("disabled",false);

Любой намек на то, как заставить его работать, будет принят с благодарностью.

РЕДАКТИРОВАТЬ: Пример полной регистрационной формы с включенной кнопкой отправки, ТОЛЬКО когда все элементы формы проверены, см. это.

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<style>
  input[type="submit"]:disabled {
    background-color: red;      }
</style>
</head>
<body>
  <div class="container mt-2">
    <div class="row">
      <div class="col-md-4 offset-md-4">
        <form action="page2.php" id="myForm1" class="needs-validation" novalidate>
          <div class="form-group">
            <input type="text" class="form-control" pattern="^[a-z]{3,6}$" required autofocus>
            <div class="valid-feedback">Valid</div>
            <div class="invalid-feedback">a to z only (3 to 6 long)</div>
          </div>
          <div class="form-group">
            <input type="text" class="form-control" pattern="^[a-z]{3,6}$" required>
            <div class="valid-feedback">Valid</div>
            <div class="invalid-feedback">a to z only (3 to 6 long)</div>
          </div>
          <div class="form-group">
            <button id="submitBtn" type="submit" class="btn btn-primary submit-button" disabled>Submit</button>
          </div>
        </form>
      </div>
    </div>
  </div>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
  <script>
    window.addEventListener('load', function() {
      let currForm1 = document.getElementById('myForm1');
      // Validate on input:
      currForm1.querySelectorAll('.form-control').forEach(input => {
        input.addEventListener(('input'), () => {
          if (input.checkValidity()) {
            input.classList.remove('is-invalid')
            input.classList.add('is-valid');
            $("#submitBtn").attr("disabled",false);           <<<<======== ??????
          } else {
            input.classList.remove('is-valid')
            input.classList.add('is-invalid');
          }
        });
      });
      // Validate on submit:
      currForm1.addEventListener('submit', function(event) {
        if (currForm1.checkValidity() === false) {
          event.preventDefault();
          event.stopPropagation();
        }
        currForm1.classList.add('was-validated');
      }, false);
    });
  </script>

person gadi    schedule 07.11.2019    source источник
comment
Внутри input.addEventListener[...] добавьте еще одну проверку. Проверьте, все ли входные данные имеют класс is-valid. Если это так, используйте $("#submitBtn").attr("disabled",false); там.   -  person JM-AGMS    schedule 07.11.2019
comment
@ JM-AGMS Спасибо. Это имеет смысл. Поскольку я новичок в JS и BS, не могли бы вы сэкономить мне время и рассказать мне синтаксис для проверки того, все ли входные данные имеют класс is-valid? Я уже несколько часов гоняюсь за ним своим хвостом...   -  person gadi    schedule 07.11.2019
comment
@JM-AGMS Спасибо!!! Это сработало для меня. Если поставите как и ответите - приму. (Теперь я вижу, что уже есть 2 ответа, которые я сейчас проверю)   -  person gadi    schedule 07.11.2019


Ответы (3)


Внутри прослушивателя входных событий проверьте, все ли входные данные имеют класс is-valid. Если все ваши входы имеют класс is-valid, выключите отключенную кнопку.

currForm1.querySelectorAll('.form-control').forEach(input => {
  input.addEventListener(('input'), () => {
    if (input.checkValidity()) {
      input.classList.remove('is-invalid')
      input.classList.add('is-valid');
      // $("#submitBtn").attr("disabled",false);           <<<<======== ??????
    } else {
      input.classList.remove('is-valid')
      input.classList.add('is-invalid');
    }
    var is_valid = $('.form-control').length === $('.form-control.is-valid').length;
    $("#submitBtn").attr("disabled", !is_valid);
  });
});
person JM-AGMS    schedule 07.11.2019
comment
Я заметил, что ваше решение не на 100% идеально: только после ввода правильного ввода во все поля кнопка активируется. Это хорошо! Но если перед тем, как нажать кнопку, я вернусь к любому из полей и сделаю его недействительным (например, удалив символы, чтобы оно было ниже требуемого минимума), кнопка останется включенной. Я думаю, что это достаточно хорошо для моего проекта, но это было бы было бы намного элегантнее, если бы эта небольшая проблема тоже была решена.Есть идеи...? - person gadi; 07.11.2019
comment
Обновил мой ответ. - person JM-AGMS; 07.11.2019
comment
Ух ты! Когда я вырасту, я хочу стать JM-AGMS... Большое спасибо! Для меня это 100% решение. - person gadi; 07.11.2019

Я не знаю, хороший это подход или нет, и он также зависит от ваших требований, если он удовлетворяет ваши потребности, так что все в порядке.

здесь я удаляю одну строку и добавляю другую

  1. удалить код кнопки отключения из первого условия и добавить в последний

if(input.checkValidity() && index ===1) {
    $("#submitBtn").attr("disabled", false); 
}
<!DOCTYPE html>
<html lang="en">
<head>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
  <style>
    input[type="submit"]:disabled {
      background-color: red;      }
  </style>
  </head>
  <body>
    <div class="container mt-2">
      <div class="row">
        <div class="col-md-4 offset-md-4">
          <form action="page2.php" id="myForm1" class="needs-validation" novalidate>
            <div class="form-group">
              <input type="text" class="form-control" pattern="^[a-z]{3,6}$" required autofocus>
              <div class="valid-feedback">Valid</div>
              <div class="invalid-feedback">a to z only (3 to 6 long)</div>
            </div>
            <div class="form-group">
              <input type="text" class="form-control" pattern="^[a-z]{3,6}$" required>
              <div class="valid-feedback">Valid</div>
              <div class="invalid-feedback">a to z only (3 to 6 long)</div>
            </div>
            <div class="form-group">
              <button id="submitBtn" type="submit" class="btn btn-primary submit-button" disabled>Submit</button>
            </div>
          </form>
        </div>
      </div>
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
    <script>
      window.addEventListener('load', function() {
        let currForm1 = document.getElementById('myForm1');
        // Validate on input:
        currForm1.querySelectorAll('.form-control').forEach((input, index) => {
          input.addEventListener(('input'), () => {
            if (input.checkValidity()) {
              console.log(input.checkValidity());
              input.classList.remove('is-invalid')
              input.classList.add('is-valid');      
            } else {
              input.classList.remove('is-valid')
              input.classList.add('is-invalid');
            }
            if(input.checkValidity() && index ===1) {
              $("#submitBtn").attr("disabled", false); 
            }
          });
        });
        // Validate on submit:
        currForm1.addEventListener('submit', function(event) {
          if (currForm1.checkValidity() === false) {
            event.preventDefault();
            event.stopPropagation();
          }
          currForm1.classList.add('was-validated');
        }, false);
      });
    </script>
  </body>
</html>

person Atul Kumar    schedule 07.11.2019
comment
Спасибо. Я нашел решение @JM-AGMS идеальным для себя. Спасибо еще раз. - person gadi; 07.11.2019

Нам нужно проверить, верны ли все остальные входные данные, прежде чем предположить, что мы можем просто включить его.

let currForm1 = document.getElementById('myForm1');
      // Validate on input:
      currForm1.querySelectorAll('.form-control').forEach(input => {
        input.addEventListener(('input'), () => {
          if (input.checkValidity()) {
            /* IF IT PASSES WE NEED TO CHECK THE OTHER INPUTS */

            /* STORE ALL THE INPUTS THAT PASS THE CHECKVALIDITY */
            let allValid = currForm1.querySelectorAll('.form-control').filter(input => 
              { return input.checkValidity() })

            /* WE CAN NOW UPDATE THE SUBMIT BASED ON THE NUMBER OF VALID 
               INPUTS WE HAVE */
            $("#submitBtn").attr("disabled", allValid.length === currForm1.querySelectorAll('.form-control').length); 

            input.classList.remove('is-invalid')
            input.classList.add('is-valid');   
          } else {

            /* IF IT FAILS WE DONT NEED TO CHECK WE WANT THE VALIDATOR AS FALSE */
            $("#submitBtn").attr("disabled", true); 
            input.classList.remove('is-valid')
            input.classList.add('is-invalid');
          }
        });
      });

      /* FINALLY WE CAN UPDATE THE SUBMIT, BASED ON OUR VARIABLE */
      $("#submitBtn").attr("disabled", validatorForSubmit ); 
person rule    schedule 07.11.2019
comment
Спасибо. Я нашел решение @JM-AGMS идеальным для себя. Спасибо еще раз. - person gadi; 07.11.2019