I have a form with a varying number of inputs, some visible and some hidden (they're conditional based on selected options and radio controls). I have jQuery script below that's pulling through all of the visible inputs on the form.
EDIT more of the script as requested.
var formInputs = jQuery('#Enquire :input:not(button):visible');
var enquiry = validateInputs(formInputs);
function validateInputs(inputs){
var nullCount = 0;
var errorCount = 0;
var reqdFields = {};
var formInputs = {};
var firstError = "";
var text = "";
inputs.each(function(){
if(jQuery(this).is(":visible")){ // will remove once I've got the answer
var name = jQuery(this).attr("name");
var value = jQuery(this).val();
if(jQuery(this).hasClass("error")){ errorCount++; }
var reqd = jQuery(this).attr('required');
var num = jQuery(this).attr('number');
var fieldType = jQuery(this).attr('type');
var errorLabel = "<label id=\"" + name + "-error\" class=\"error\" for=\"" + name + "\">This field is required.</label>";
var numerrorLabel = "<label id=\"" + name + "-error\" class=\"error\" for=\"" + name + "\">This field can only contain numeric characters.</label>";
//check if the field is required
if(typeof reqd !== typeof undefined && reqd !== false){
//check if the field's value is empty
if(value == null || value == ""){
nullCount++;
if(!(jQuery(this).hasClass("error"))){
debugLog("adding error class");
//perform the error report on the field
jQuery(this).addClass("error");
jQuery(this).after(errorLabel);
}
}
}
//check if the field is a number field
if(typeof num !== typeof undefined && num !== false){
//check if the field already has an error (null)
if(!(jQuery(this).hasClass("error"))){
if(!isNumeric(value)){
debugLog("adding error class");
//perform the error report on the field
jQuery(this).addClass("error");
jQuery(this).after(numerrorLabel);
}
}
}
//check if the field value is not empty
if(jQuery(this).val() != ""){
debugLog("Visible Field" + jQuery(this).attr("id"));
//check if the field is a checkbox / radio field which doesn't use IDs
if(fieldType == "radio" && jQuery(this).prop("checked")){
outputdata[name] = value;
}
else{
outputdata[name] = value;
}
}
else{
//here we flag the first required field's ID so we can scroll to it later
if(nullCount == 1){
firstError = jQuery(this).attr("id");
debugLog("First Error" + firstError);
}
debugLog("Null value for "+name);
}
}
});
debugLog(nullCount);
debugLog(reqdFields);
debugLog(errorCount);
debugLog(outputdata);
Errors = errorCount;
if(nullCount !== 0){
debugLog("throw Error on screen");
jQuery('html, body').animate({
scrollTop: (jQuery("#"+firstError).offset().top)-40
}, 1000);
}else{
return outputdata;
}
};
What I've found is that everything seems to work fine except for the radio buttons and checkboxes as it seems to default the last input with the same name. HTML below:
<form role="form" class="clearfix Form DonationForm" id="Enquire">
<fieldset>
<div class="form-group col-lg-12 no-padding">
<div class="form-group col-lg-2 no-left-padding no-margin">
<label for="Title" class="control-label col-sm-12 no-padding">Title</label>
<div class="col-sm-12 no-padding">
<select id="Title" name="Title" class="form-control" required type="select">
<option value="">Title:</option>
<option value="Mr">Mr</option>
<option value="Mrs">Mrs</option>
<option value="Miss">Miss</option>
<option value="Ms">Ms</option>
<option value="Dr">Dr</option>
<option value="Prof">Prof</option>
<option value="Hon">Hon</option>
<option value="Rev">Rev</option>
</select>
</div>
</div>
<div class="form-group col-lg-5 no-padding no-margin">
<label for="FirstName" class="control-label col-sm-12 no-padding">First Name</label>
<div class="col-sm-12 no-padding">
<input type="text" class="form-control" id="FirstName" name="FirstName" placeholder="First Name" required minlength="2">
</div>
</div>
<div class="form-group col-lg-5 no-right-padding no-margin">
<label for="Surname" class="control-label col-sm-12 no-padding">Surname</label>
<div class="col-sm-12 no-padding">
<input type="text" class="form-control" id="Surname" name="Surname" placeholder="Surname" required minlength="2">
</div>
</div>
</div>
<div class="form-group col-lg-6 no-padding">
<label class="control-label col-sm-12 no-padding" for="EnquiryType">Enquiry Type</label>
<div class="controls text-left col-sm-6 no-left-padding">
<label><input type="radio" class="EnquiryType" name="EnquiryType" id="Sales" value="Sales" required>Sales</label>
</div>
<div class="controls text-left col-sm-6 no-right-padding">
<label><input type="radio" class="EnquiryType" name="EnquiryType" id="Service" value="Service" required>Service</label>
</div>
</div>
<div class="form-group">
<div class="controls col-sm-12 no-padding">
<input type="hidden" id="ReferenceNo" name="ReferenceNo" value="<?php echo genTicketString(); ?>">
<a class="btn btn-success" href="javascript:;" id="EnquireBtn">Enquire Now</a>
<!--input class="btn btn-success" type="submit" value="Enquire Now"-->
</div>
</div>
</fieldset>
</form>
I'm currently logging everything to the console to watch what is happening and no matter what my selection is above, the output is always EnquiryType: Service
In an attempt to "catch" this particular issue, I had changed this:
if(jQuery(this).val() != ""){
debugLog("Visible Field" + jQuery(this).attr("id"));
formInputs[name] = value;
}
To this:
if(jQuery(this).val() != ""){
debugLog("Visible Field" + jQuery(this).attr("id"));
//check if the field is a checkbox / radio field which doesn't use IDs
if(fieldType == "radio" && jQuery(this).prop("checked")){
formInputs[name] = value;
}
else{
formInputs[name] = value;
}
}
Are there any suggestions? I'd prefer to keep the script as dynamic as possible and it works great for all other input types so I'd like to fix this please.