N P
N P

Reputation: 2619

Check if all form fields have inputs jQuery

I have a form on my page, I want to disable the submit button via jQuery until all the form fields have a value. I also have server-side validation, but I would rather use some client-side validation to ease the strain on my server. I currently hold all the elements of my form in an array, I then loop over each element and check if any are empty. I also need to recall this function everytime a user enters data into the form, to check if all the inputs have been filled. This seems to put a huge strain on my browser and crashes the page, below is code.

let inputArray = [
            $('.registration-form #inputEmail'),
            $('.registration-form #inputForename'),
            $('.registration-form #inputSurname'),
            $('.registration-form #inputJobTitle'),
            $('.registration-form #inputJobFunction'),
            $('.registration-form #inputCompanyName'),
            $('.registration-form #inputCompanySize')
        ];

        let $registerButton = $('.create-account-button');

        function checkFields() {
            inputArray.forEach(function (input) {
                if (!$(input).val()) {
                    $registerButton.prop('disabled', true);
                } else {
                    $registerButton.prop('disabled', false);
                }
                input.on('input', checkFields);
            });
        }

Upvotes: 2

Views: 4075

Answers (5)

Derek Nolan
Derek Nolan

Reputation: 744

I agree with Nick using jQuery plugin

Here's a working example using the plugin:

<html>
    <head>
        <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
        <script src="https://cdn.jsdelivr.net/jquery.validation/1.16.0/jquery.validate.min.js"></script>
        <script src="https://cdn.jsdelivr.net/jquery.validation/1.16.0/additional-methods.min.js"></script>
        <style>
        input{
        width:100px;
        margin-bottom: 3px;
        clear:both;
        }
        form#form-to-validate {
            float: left;
            display: block;
            width: 100px;
        }
        </style>
    </head>
    <body>
        <form id="form-to-validate">
        <input class="registration-form" id='inputEmail' name="inputEmail"/>
        <input class="registration-form" id='inputForename' name='inputForename'/>
        <input class="registration-form" id='inputSurname' name='inputSurname'/>
        <input class="registration-form" id='inputJobTitle' name='inputJobTitle'/>
        <input class="registration-form" id='inputCompanyName' name='inputCompanyName'/>
        <input class="registration-form" id='inputCompanySize' name='inputCompanySize'/>
        <input type="submit"/>
        </form>
        <script>
        jQuery.validator.setDefaults({
                    debug: true,
                    success: "valid"
                });
                $( "#form-to-validate" ).validate({
                    rules: {
                        inputEmail: {
                        required: true,
                        email: true
                        },
                        inputForename: {
                        required: true
                        },
                        inputSurname: {
                        required: true
                        },
                        inputJobTitle: {
                        required: true
                        },
                        inputCompanyName: {
                        required: true
                        },
                        inputCompanySize: {
                        required: true
                        }
                    }
                });
        </script>
    </body>
</html>

Upvotes: 1

Nick Cordova
Nick Cordova

Reputation: 754

Don't reinvent the wheel jquery validation plug-in

But if you really want to

$(document).ready(function(){
       var form = $('form'),
           submitButton = $("#btnSubmit"),
           isValid = true;

       submitButton.click(function(event){
       		event.preventDefault();
          isValid = true;
          form.children("input").each(function(index,element)               
          {
                 if(!element.value.trim())
                    isValid = false;    
          });

					console.log(isValid);
          
          if(isValid)
          	 form.submit();
      });      
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="/action_page.php">
  First name:<br>
  <input type="text" name="firstname" value="Mickey">
  <br>
  Last name:<br>
  <input type="text" name="lastname" value="Mouse">
  <br><br>
  <input id="btnSubmit" type="submit" value="Submit">
</form>

Upvotes: 1

Sergey Sklyar
Sergey Sklyar

Reputation: 1970

Pure Javascript version. Lets take a Bootstrap form.

Add validate class to the inputs you need to check:

<form class="registration-form">
  <div class="form-group">
    <label for="exampleFormControlInput1">Email address</label>
    <input type="email" class="form-control validate" id="exampleFormControlInput1" placeholder="[email protected]">
  </div>
  <div class="form-group">
    <label for="exampleFormControlSelect1">Example select</label>
    <select class="form-control validate" id="exampleFormControlSelect1">
      <option>1</option>
      <option>2</option>
      <option>3</option>
      <option>4</option>
      <option>5</option>
    </select>
  </div>
  <div class="form-group">
    <label for="exampleFormControlSelect2">Example multiple select</label>
    <select multiple class="form-control validate" id="exampleFormControlSelect2">
      <option>1</option>
      <option>2</option>
      <option>3</option>
      <option>4</option>
      <option>5</option>
    </select>
  </div>
  <div class="form-group">
    <label for="exampleFormControlTextarea1">Example textarea</label>
    <textarea class="form-control validate" id="exampleFormControlTextarea1" rows="3"></textarea>
  </div>
  <button type="submit" class="btn btn-primary create-account-button">Submit</button>
</form>


var form = document.querySelector('.registration-form'),
    form_elements = form.querySelectorAll('.validate'),
    btn = document.querySelector('.create-account-button');

function checkFields() {
    var error = 0;
    Array.prototype.slice.call( form_elements ).forEach(function( input ) {
        if ( input.value.length == 0 ) {
            error++;
        }
    });
    if ( error > 0 ){
        btn.setAttribute( 'disabled', 'disabled' );
    } else {
        btn.removeAttribute( 'disabled' );
    }
}

document.addEventListener( 'DOMContentLoaded', checkFields, false );
Array.prototype.slice.call( form_elements ).forEach(function( input ) {
    input.addEventListener( 'input', checkFields, false );
});

DEMO

Upvotes: 0

Terry
Terry

Reputation: 66228

As per my comment: you are over-complicating your question—the reason why your browser crashes is because you are calling checkFields in an infinite loop. What you want to do is really simple:

  1. Give a class to all the input fields you want to validate, say give them a class of validate
  2. Bind the onInput event to call these input fields. jQuery will automatically iteratively bind the same event handler when provided with a collection of elements
  3. In the callback of the onInput event, you simply have the logic that checks if any of the fields are empty. This is done by using .map() and then .filter() to return an array of empty fields. Conditionally disable/enable the submit button by checking the length of this array.

Point #3 can be a bit complicated to understand, so here's the breakdown of it:

  • .map() is used to return an array-like object. Using return this.value in the callback function means you want to push the values of each input into this arrya.
  • .get() is chained after this because .map() does not return a true array
  • .filter() is used to remove items from the array that are not empty, using the callback function that returns true when the length of the array item (in this case, the input element's value) is 0

This will return an array of empty fields. You can then use .prop('disabled', <boolean>) to conditionally enable or disable the submit button. !!emptyFields.length expression is used to ensure that a boolean is returned:

  • When there are no empty fields (length of 0), !!0 returns false.
  • When there are empty fields (length >= 1), !!<n> returns true.

See proof-of-concept below:

$(function() {
  // Cache fields that you want to validate
  var $fieldsToCheck = $('.registration-form .validate');
  
  // Function to ensure fields are not empty
  var checkFields = function() {
    // Get array of empty fields
    var emptyFields = $fieldsToCheck.map(function() {
      return this.value;
    }).get().filter(function(val) {
      return val.length === 0;
    });
    
    // Disabled prop to be toggled based on length of empty fields
    $('.create-account-button').prop('disabled', !!emptyFields.length);
  };

  // Bind onInput event to all inputs you want to check
  $fieldsToCheck.on('input', checkFields);

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="registration-form">

  <input name="email" class="validate" type="text" />
  <input name="forename" class="validate" type="text" />
  <input name="surname" class="validate" type="text" />

  <button class="create-account-button" disabled>Create account</button>

</form>

Upvotes: 4

Fan Cheung
Fan Cheung

Reputation: 11380

try this

let inputArray = [
        $('.registration-form #inputEmail'),
        $('.registration-form #inputForename'),
        $('.registration-form #inputSurname'),
        $('.registration-form #inputJobTitle'),
        $('.registration-form #inputJobFunction'),
        $('.registration-form #inputCompanyName'),
        $('.registration-form #inputCompanySize')
    ];

    let $registerButton = $('.create-account-button');

    function checkFields() {
        inputArray.forEach(function (input) {
            if (!$(input).val()) {
                $registerButton.prop('disabled', true);
            } else {
                $registerButton.prop('disabled', false);
            }
        });
    }

    inputArray.forEach(function (input) {
            input.on('input', checkFields);
    })

Upvotes: 0

Related Questions