Prevent submission of form until validation is complete using Bootstrap 4

Within this particular issue I am facing, there are 2 fields that require validation.
The submit button should remain disabled until both fields (in this case, 2) have been validated.
Once both fields have been successfully validated, the submit button should then become enabled.

The Issue: The problem arises when the first field is validated - the button becomes enabled prematurely.
This seems to be happening due to the placement of

$("#submitBtn").attr("disabled",false);
.

If anyone has any insight on how to resolve this issue, it would be greatly appreciated.

UPDATE: For a complete example of a registration form where the submit button is only enabled when all form elements have been validated, you can refer to this link.

<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 characters 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 characters 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>

Answer №1

Make sure to verify if all the input fields have the is-valid class inside your input event listener function. If indeed every input contains the is-valid class, then you can enable the disabled button.

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);
  });
});

Answer №2

It's uncertain if this is the best approach, as it depends on your specific requirements. If it meets your needs, then it should be fine.

I have made some modifications by removing certain lines and adding new ones.

  1. I moved the disable button code from the first condition to the last one.

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>

Answer №3

Before enabling, it is crucial to validate all inputs to ensure their validity.

let formElement = document.getElementById('myForm1');
      // Validate each input:
      formElement.querySelectorAll('.form-control').forEach(input => {
        input.addEventListener(('input'), () => {
          if (input.checkValidity()) {
            /* Once validated, check other inputs */

            /* Store valid inputs */
            let validInputs = formElement.querySelectorAll('.form-control').filter(input => 
              { return input.checkValidity() })

            /* Update submit button based on number of valid inputs */
            $("#submitBtn").attr("disabled", validInputs.length === formElement.querySelectorAll('.form-control').length); 

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

            /* If validation fails, set validator as false */
            $("#submitBtn").attr("disabled", true); 
            input.classList.remove('is-valid')
            input.classList.add('is-invalid');
          }
        });
      });

      /* Update submit button based on validator variable */
      $("#submitBtn").attr("disabled", validatorForSubmit ); 

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error: The API call response could not be shown on the webpage

Upon exploring the React App.js page, I discovered that I am making calls to a Django Rest API and receiving an array as a response. Within this array, there are nested components that should be listed in my code. However, when attempting to display multi ...

Having trouble getting basic HTML to function with Vue.js

I am new to vue.js and decided to follow the steps in this tutorial: https://www.sitepoint.com/getting-started-with-vue-js/ After copying the code into my HTML, I encountered some issues. Could someone please assist me in identifying what might be going w ...

Display text on the screen with a customized design using JavaScript's CSS styles

I need help with printing a specific page that contains some information designed in print.css. I want to print this page, including an image, with the same style. function printContent() { var divContents = document.getElementById("terms").innerH ...

Using ESLint to enforce snake_case naming conventions within TypeScript Type properties

When working with TypeScript, I prefer to use snake_case for properties within my Interfaces or Types. To enforce this rule, I have configured the ESLint rule camelcase as follows: 'camelcase': ["error", {properties: "never"}], Even though the E ...

Is it possible to prevent an iFrame from loading its src until a certain function is triggered?

Currently, my webpage has multiple iFrames that are being populated with sources dynamically. However, the page's performance is suffering due to all iframes loading simultaneously. To improve this, I want to delay the loading of these iframes until a ...

What impact does the //g flag in Regex JavaScript have on the program's state?

I recently had a question that was answered, but I'm still trying to grasp why the regex behaves in a certain way. According to w3schools, it explains: g: Perform a global match (find all matches rather than stopping after the first match) Okay, ...

Changing badge colors dynamically in Bootstrap

I'm currently working on a simple web application using Django and Bootstrap 4.5. Within one of my models, there is a color attribute that I would like to visually represent using Bootstrap's badge. My goal is to dynamically set the badge's ...

Just delving into React for the first time and encountering undefined values in PropTypes

I am completely new to React and attempting to create a basic weather application in order to understand how components interact with each other. I have a forecast.json file that contains information such as temperature, date, humidity, wind speed, wind di ...

I am encountering a challenge retrieving the ID via AJAX from the view to the controller. However, the ID is successfully displaying in the alert

In the view page code below, I am trying to send an ID through Ajax but it is not posting in the controller. The goal is to replace one question at a time fetching from the database. $(document).ready(function() { $("#next").click(function() { ...

Unable to trigger onClick event in React class-based component

I came across the following code for a class-based component: class PostLike extends Component { constructor(props) { super(props); this.state = { likes: null, like_id: null } this.likeSubmit = t ...

Troubles with Promise.all and json() in JavaScript causing errors being logged as "invalid function"

I'm experiencing some difficulties with the "Promise.all" method. Essentially, I have an array of URLs (here is a simple one if you want to test it: const urlArray = [ "https://coverartarchive.org/release/985adeec-a1fd-4e79-899d-10c54b6af299&qu ...

Create a JavaScript variable that is initialized with a value from an AngularJS scope

What is the best way to assign a value from an AngularJS scope variable to a JavaScript variable? For example: xyz.controller({ $scope.country = "Canada"; }); Here's how you can do it in JavaScript: <script> var country = {{scope.countr ...

When hovering over a jQuery element, display another element and then move the mouse away

When hovering over the red box, the grey box will appear. If the mouse remains on the grey box, it will stay open. Moving the mouse from the grey box back to the red box should keep the grey box open. The grey box will only close when the mouse is not hov ...

Creating a form for adding and editing using React Hook Form

I'm currently working on creating a form that can handle both the creation and editing of a product by passing values through an object. The form functions perfectly for creating a product, but I'm facing challenges in making it work for editing ...

An error was caught: Cursor blinking not functioning properly in textbox when using JavaScript

Currently, I am in the process of creating an HTML form that involves selecting items from a list box. Once an item is selected, an input text box is generated automatically for entering the quantity of the selected item. I have implemented a feature where ...

Difficulty in rendering all facets of a 3D object with Three.js and Fresnel Shader

I am delving into the world of Three.js and JavaScript coding for the first time. Lately, I have been experimenting with Shaders and Shader Materials. The issue I encountered was when I loaded a mesh with a Fresnel material. While the surface material app ...

Routing with nested modules in Angular 2 can be achieved by using the same

Encountering a common issue within a backend application. Various resources can be accessed through the following routes: reports/view/:id campains/view/:id suts/view/:id certifications/view/:id Note that all routes end with the same part: /view/:id. ...

Display a specific section of a local JSON Array file using the Html5 FileReader

I have a background in VBA Excel programming and find it much easier to read and manipulate Excel files using VBA compared to web tools like FileReader and JSON arrays. Below is the content of my JSON array file: [ ["TWE",6000,4545.5], ["RW",1000,256 ...

What could be the reason for the Express function Router() returning a value of undefined?

Currently, I am working with TypeScript and Express to develop an API that adheres to the principles of Clean Architecture. To organize my application, I have structured each route in separate folders and then imported them all into an index.ts file where ...

Extracting Data from Input Box Using Query

In my HTML setup, I have five <textarea> tags with IDs text1,text2,text3,text4, and one additional <textarea> tag with ID output. I want to query based on the values of text1,text2,text3,text4 (referred to as field1, field2, field3, field4). F ...