Reputation: 2619
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
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
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
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 );
});
Upvotes: 0
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:
validate
onInput
event to call these input fields. jQuery will automatically iteratively bind the same event handler when provided with a collection of elementsonInput
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 0This 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:
!!0
returns false.!!<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
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