I am attempting to add validation for a non-input, custom selection. I have a series of images that the user clicks, which act as a checkbox, but do not actually have an input. I am using jQuery validate for the rest of my form and wanted to see if there was anyway that I can add validation, whether it is adding a method (I read jQuery validate only works on inputs) or something else that will work with one click of submit.
I am wanting something similar to this, but to work like jQuery validate.
if(checkValue.length < 1) {
alert("You need at least one interested selected.");
}
I tried putting the above if-statement above the rules section in the validation code, but it throws an error.
Does anyone have any alternative ideas that I could try?
//Getting Value of the interest boxes
var interest = $('.interest');
var checkVal = '';
var checkValue = '';
interest.click(function() {
checkVal = [];
$(this).toggleClass('active');
$('.interestBox', this).toggleClass('active');
interest.each(function() {
if($(this).is('.active')) {
checkVal.push($(this).data('title'));
}
});
checkValue = checkVal.join(', ');
console.log(checkValue);
});
//Jquery Validate
$('#salesforce_submit').validate({
rules: {
first_name: {
required: true,
minlength: 2
}
},
messages: {
first_name: {
required: "Please enter your first name",
minlength: "Your first name seems a bit short, doesn't it?"
}
},
submitHandler: function(form) {
event.preventDefault();
var datastring = $('#salesforce_submit').serialize();
$.ajax({
url: '/php/quoteSend.php',
type: 'POST',
data: datastring
,
success: function(data) {
if (data == 'Error!') {
alert(data);
} else {
}
},
error: function(xhr, textStatus, errorThrown) {
alert(textStatus + '|' + errorThrown);
console.log('error');
}
});
}
});
.interest img {
height: 50px;
width: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js"></script>
<form id="salesforce_submit" type="Post">
<div><input id="first_name" placeholder="First Name*" class="input block" maxlength="40" name="first_name" type="text"></div>
<h3 class="interestTitle">A</h3>
<div class="interest" data-title="A">
<img src="https://www.mountaineers.org/images/placeholder-images/placeholder-400-x-400/image_preview" alt="A">
</div>
<h3 class="interestTitle">B</h3>
<div class="interest" data-title="B">
<img src="https://www.mountaineers.org/images/placeholder-images/placeholder-400-x-400/image_preview" alt="B">
</div>
<h3 class="interestTitle">C</h3>
<div class="interest" data-title="C">
<img src="https://www.mountaineers.org/images/placeholder-images/placeholder-400-x-400/image_preview" alt="C">
</div>
<input type="Submit" value="Submit">
Full code:
<section class="sec90">
<h3 class="subTC">Enter your information below.</h3>
<form action="" id="salesforce_submit" method="POST" enctype="multipart/form-data">
<input name="oid" type="hidden" value=""><input type="hidden" id="" id="interestValue" multiple="multiple" name="" value=""><input name="retURL" type="hidden"> <input name="lead_source" required="" type="hidden" value="Quote Form"> <input id="txt_medium" name="txt_medium" type="hidden" value=""> <input id="txt_source" name="txt_source" type="hidden" value=""> <input id="txt_campaign_name" name="txt_campaign_name" type="hidden" value=""> <input id="txt_term" name="txt_term" type="hidden" value=""> <input id="txt_content" name="txt_content" type="hidden" value="">
<div><input id="first_name" placeholder="First Name*" class="input block" maxlength="40" name="first_name" type="text"></div>
<div><input id="last_name" placeholder="Last Name*" class="input block" maxlength="80" name="last_name" type="text"></div>
<div><input id="email" placeholder="Email*" class="input block" maxlength="80" name="email" type="email"></div>
<div><input id="phone" placeholder="Phone* no dashes" class="input block" maxlength="12" name="phone" type="tel"></div>
<div><input id="zip" placeholder="Zip/Postal Code*" class="input block" maxlength="5" name="zip" type="text" pattern= "[0-9]{5}"></div>
<div><input id="company" placeholder="Company*" class="input block" maxlength="40" name="company" type="text"></div>
</section>
<section class="sec90">
<h3 class="subTC">What are you interested in?*</h3>
<div><input type="hidden" name="interestHidden" value=""></div>
<section class="sec90" id="up">
<h3 class="subTC">Describe your project*</h3>
<div><textarea id="description" name="description" placeholder="Provide as much detail as possible"></textarea></div>
<h3 class="subTC block">Have a .stp file or drawing example? Send it for quicker quote times.</h3>
<input type="file" name="uploadedFile" class="inputfile" id="uploadedFile" data-multiple-caption="{count} files selected" multiple>
<label for="uploadedFile" class="button"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" viewBox="0 0 20 17"><path d="M10 0l-5.2 4.9h3.3v5.1h3.8v-5.1h3.3l-5.2-4.9zm9.3 11.5l-3.2-2.1h-2l3.4 2.6h-3.5c-.1 0-.2.1-.2.1l-.8 2.3h-6l-.8-2.2c-.1-.1-.1-.2-.2-.2h-3.6l3.4-2.6h-2l-3.2 2.1c-.4.3-.7 1-.6 1.5l.6 3.1c.1.5.7.9 1.2.9h16.3c.6 0 1.1-.4 1.3-.9l.6-3.1c.1-.5-.2-1.2-.7-1.5z"/></svg><span class="marL5">Upload file</span></label>
<input type="hidden" name="MAX_FILE_SIZE" value="10000000">
<div class="margBot40"></div>
</section>
<input name="submit" class="block testB" type="submit" value="SUBMIT QUOTE">
</form>
JS:
var interest = $('.interest');
var checkVal = '';
var checkValue = '';
var showMe = '';
interest.click(function() {
checkVal = [];
$(this).toggleClass('active');
$('.interestBox', this).toggleClass('active');
interest.each(function() {
if($(this).is('.active')) {
checkVal.push($(this).data('title'));
}
});
checkValue = checkVal.join(', ');
console.log(checkValue);
//Hidden interest input value
var checkLength = checkVal.length;
console.log(checkLength);
$('[name="interestHidden"]').val(checkLength);
var interestVal = $('interestValue').val()
interestVal = checkValue;
showMe = interestVal;
console.log('Hidden val is ' + showMe);
});
/*$('#phone').keyup(function() {
$(this).val($(this).val().replace(/(\d{3})\-?(\d{3})\-?(\d{4})/,'$1-$2-$3'));
});*/
$('#phone').keydown(function (e) {
var key = e.charCode || e.keyCode || 0;
$text = $(this);
if (key !== 8 && key !== 9) {
if ($text.val().length === 3) {
$text.val($text.val() + '-');
}
if ($text.val().length === 7) {
$text.val($text.val() + '-');
}
}
return (key == 8 || key == 9 || key == 46 || (key >= 48 && key <= 57) || (key >= 96 && key <= 105));
});
var inputs = document.querySelectorAll( '.inputfile' );
Array.prototype.forEach.call( inputs, function( input )
{
var label = input.nextElementSibling,
labelVal = label.innerHTML;
input.addEventListener( 'change', function( e )
{
var fileName = '';
if( this.files && this.files.length > 1 )
fileName = ( this.getAttribute( 'data-multiple-caption' ) || '' ).replace( '{count}', this.files.length );
else
fileName = e.target.value.split( '\\' ).pop();
if( fileName )
label.querySelector( 'span' ).innerHTML = fileName;
else
label.innerHTML = labelVal;
});
});
$('#phone').keyup(function() {
jQuery.validator.addMethod("alphanumeric", function(value, element) {
//return this.optional(element) || /^[a-z0-9\-]+$/i.test(value);
return this.optional(element) || /^[+]*[(]{0,1}[0-9]{1,3}[)]{0,1}[-\s\./0-9]*$/i.test(value);
}, "Numbers and dashes only");
});
$('#salesforce_submit').validate({
ignore: [],
rules: {
first_name: {
required: true,
minlength: 2
},
last_name: {
required: true,
minlength: 2
},
email: {
required: true,
email: true
},
phone: {
required: true,
//digits: true,
minlength: 10,
alphanumeric: true
},
zip: {
required: true,
digits: true,
minlength: 5
},
company: {
required: true,
minlength: 2
},
interestHidden: {
required: true,
min: 1
}/*,
description: {
required: true,
minlength: 5
}*/
},
messages: {
first_name: {
required: "Please enter your first name",
minlength: "Your first name seems a bit short, doesn't it?"
},
last_name: {
required: "Please enter your last name",
minlength: "Your last name seems a bit short, doesn't it?"
},
email: {
required: "Please enter your email address",
email: "Please enter a valid email address"
},
phone: {
required: "Please enter your phone number",
digits: "Please enter a valid phone number with only numbers",
minlength: "Your number seems a bit short, doesn't it?"
},
zip: {
required: "Please enter your zip code",
digits: "Please enter a valid zip code with only numbers",
minlength: "Your zip code seems a bit short, doesn't it?"
},
company: {
required: "Please enter your company name",
minlength: "Your company name seems a bit short. Please enter at least 2 characters"
},
interestHidden: {
required: "Please choose at least one interest",
min: "At least one interest needs chosen"
}/*,
description: {
required: "Please enter your project description",
minlength: "Your description seems a bit short, doesn't it?"
}*/
},
submitHandler: function(form) {
event.preventDefault();
var datastring = $('#salesforce_submit').serialize();
$.ajax({
url: '/php/quoteSend.php',
type: 'POST',
data: datastring
,
success: function(data) {
console.log(data);
if (data == 'Error!') {
alert('Unable to submit form!');
alert(data);
} else {
$('#salesforce_submit')[0].reset();
$('#consult-success').show();
$('#salesforce_submit').hide();
}
},
complete: function() {
//$("#salesforce_submit").submit();
location.href = "";
},
error: function(xhr, textStatus, errorThrown) {
alert(textStatus + '|' + errorThrown);
console.log('error');
}
});
}
});
Since jQuery Validate only validates select, textarea, and various types of input elements1, your only option is to give it what it wants.
Create a hidden element...
<input type="hidden" name="myImage" value="0" />
When the user clicks your image, use jQuery to manipulate the value of a type="hidden" input element...
$('#photo').on('click', function() {
$('[name="myImage"]').val('1');
});
And then programmatically validate its value instead. Since clicking on the image will not cause any validation, you can use the .valid() method to trigger validation on these hidden elements...
$('[name="myImage"]').valid();
You will need to leverage the ignore option since the plugin will not validate hidden elements by default. ignore: [] will effectively disable this and force the plugin to validate all hidden elements...
$('#salesforce_submit').validate({
ignore: [],
rules: { ....
Of course, you'll also need to have rules in place that properly validate the value of your hidden element.
Since the message will be placed near the hidden element, you'll have to leverage the errorPlacement function to place this message conditionally.
$('#salesforce_submit').validate({
ignore: [],
errorPlacement: function(error, element) {
if (element.attr('name') == 'myImage') {
// placement for hidden element
} else {
// default
error.insertAfter(element);
}
}
rules: { ....
1 newer versions of the plugin also support elements with the contenteditable attribute.
What about this, give all the checkboxes you trigger the same name e.g. "box". Add this custom rule "img_check":
jQuery.validator.addMethod("img_check", function() {
$(input[name='box']).each( function(){
if $(this).is(':checked') {
return true
}
})
// No box was checked
return false
}, "Please check at least one box");
Then add this rule:
rules: {
first_name: {
required: true,
minlength: 2
},
box[]: {
img_check: true
}
},
Why don't you check checkValue before going ahead with the submission process?
//Getting Value of the interest boxes
var interest = $('.interest');
var checkVal = '';
var checkValue = '';
interest.click(function() {
checkVal = [];
$(this).toggleClass('active');
$('.interestBox', this).toggleClass('active');
interest.each(function() {
if($(this).is('.active')) {
checkVal.push($(this).data('title'));
}
});
checkValue = checkVal.join(', ');
console.log(checkValue);
});
//Jquery Validate
$('#salesforce_submit').validate({
rules: {
first_name: {
required: true,
minlength: 2
}
},
messages: {
first_name: {
required: "Please enter your first name",
minlength: "Your first name seems a bit short, doesn't it?"
}
},
submitHandler: function(form) {
if(checkValue.length>0){
event.preventDefault();
var datastring = $('#salesforce_submit').serialize();
$.ajax({
url: '/php/quoteSend.php',
type: 'POST',
data: datastring
,
success: function(data) {
if (data == 'Error!') {
alert(data);
} else {
}
},
error: function(xhr, textStatus, errorThrown) {
alert(textStatus + '|' + errorThrown);
console.log('error');
}
});
}else console.log('Please select at least one interest');
}
});
.interest img {
height: 50px;
width: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js"></script>
<form id="salesforce_submit" type="Post">
<div><input id="first_name" placeholder="First Name*" class="input block" maxlength="40" name="first_name" type="text"></div>
<h3 class="interestTitle">A</h3>
<div class="interest" data-title="A">
<img src="https://www.mountaineers.org/images/placeholder-images/placeholder-400-x-400/image_preview" alt="A">
</div>
<h3 class="interestTitle">B</h3>
<div class="interest" data-title="B">
<img src="https://www.mountaineers.org/images/placeholder-images/placeholder-400-x-400/image_preview" alt="B">
</div>
<h3 class="interestTitle">C</h3>
<div class="interest" data-title="C">
<img src="https://www.mountaineers.org/images/placeholder-images/placeholder-400-x-400/image_preview" alt="C">
</div>
<input type="Submit" value="Submit">
I have a custom method
$.validator.addMethod("lettersandspaces", function(value, element) {
var value = this.elementValue(element).replace(/\s+/g, ' ').trim();
return this.optional(element) || /^[a-zA-Z][a-zA-Z\s]*$/i.test(value);
}, 'Your name may only contain letters');
Here I am trimming whitespace and replacing any repeating whitespaces with only one. I am then validating to make sure there are only letters and spaces.
Is it possible to make it so the trimmed value is submitted with the form instead of what the user entered?
Use the submitHandler and you can make any action before submiting the form ,(form.submit())
See beleow a working snippet
$.validator.addMethod("lettersandspaces", function(value, element) {
var value = this.elementValue(element).replace(/\s+/g, ' ').trim();
return this.optional(element) || /^[a-zA-Z][a-zA-Z\s]*$/i.test(value);
}, 'Your name may only contain letters');
$(document).ready(function () {
$("#form").validate({
rules: {
"name": {
required: true,
minlength: 5,
lettersandspaces: true
},
"age": {
required: true,
}
},
messages: {
"name": {
required: "Please, enter a name"
},
"age": {
required: "Please, enter your age",
}
},
submitHandler: function (form) { // for demo
var newName = $("#name").val().replace(/\s+/g, ' ').trim()
$("#name").val(newName);
$(form).valid();
alert("Name = '"+newName+"'");
// comment return and uncomment form.submit(
return false; //form.submit();
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.0/jquery.validate.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.0/additional-methods.js"></script>
<form id="form" method="post" action="#">
<label for="name">Name :</label>
<input type="text" name="name" id="name" /><br><br>
<label for="age">Age : </label>
<input type="age" name="age" id="age" /><br><br>
<button type="submit">Submit</button>
</form>
In validation form by jquery. If you want change value input name before validate. Let try:
$('#form').validate({
rules: {
'name': {
normalizer: function(){
return $('#name').val().(/\s+/g, ' ').trim();
}
}
}
})
When I use 'ignore' of validate() method, submission has been proceeded regardless of the result of validation(good or bad).
It is like 'ignore' make validation of all input elements bypass. So even if one or more input elements don't satisfy conditions for validation, the form has been submitted and server will work.
Oh, in my case, 'ignore' makes submitHandler and (even!) invalidHandler not work either.
What's wrong point? Here's my sampled(not entire) code below.
$('#frm').validate({
submitHandler: function() {
var applyMsg = "Proceed?";
var f = confirm(applyMsg);
if(f) {
//console.log(" confirm : "+ f );
return true;
} else {
//console.log(" no confirm : "+ f );
return false;
}
},
invalidHandler: function(form, validator) {
var errors = validator.numberOfInvalids();
if (errors) {
alert(validator.errorList[0].message);
validator.errorList[0].element.focus();
}
},
ignore: '.ignore',
rules: {
PHOTO_PLACE: {photo_place: true}
},
messages: {
PHOTO_PLACE: {required: ""},
ENT_DATE: {minlength: "", maxlength: ""}
}
});
<form id="frm" name="frm" method="post" class="app_frm">
<input type="hidden" id="PHOTO_PLACE" name="PHOTO_PLACE" />
<input type="text" name="ENT_DATE" minlength="8" maxlength="8" class="ignore" />
</form>
Thank you for any help.
I am trying to validate a form using jquery validation and I keep receiving an error "Uncaught TypeError: Cannot read property 'settings' of undefined".
The error is coming from the jquery-latest.min.js file and my jquery.validate.min.js file. Any suggestions on how to fix this?
Also, when I remove validationObj.form(); block, the error goes away, but then the validation rules are not running.
Here is my HTML:
<div id="contactForm">
<p>Contact Information</p></br>
<div id="contactInfo">
<label>First Name:</label>
<input type="text" name="fName" id="fName"/></br>
<label>Last Name:</label>
<input type="text" name="lName" id="lName"/></br>
<label>Email:</label>
<input type="text" name="email" id="email"/></br>
<label>Phone:</label>
<input type="text" name="phone" id="phone"/></br>
</div></br>
And here is my js:
var validationObj = $("#contactForm").validate
(
{
rules:
{
fName:{required:true},
lName:{required:true},
email:{required:true, email:true},
},//End rules
messages:
{
fName:{equalTo:"Please enter your first name"},
lName:{equalTo:"Please enter your last name"},
email:{minlength:"Please enter a valid email"},
},//End messages
errorPlacement:
function(error, element)
{
error.appendTo( element.next());
}
}//End validationObj
);//End var validationObj
validationObj.form();
$("form").submit
(function(e)
{
if(!validationObj.form())
{
alert("Form Errors");
}
}
);
}
Wrapped it in a form and removed the call before the submit. Working fiddle.
var validationObj = $("#contactForm").validate({
rules: {
fName: {
required: true
},
lName: {
required: true
},
email: {
required: true,
email: true
},
}, //End rules
messages: {
fName: {
equalTo: "Please enter your first name"
},
lName: {
equalTo: "Please enter your last name"
},
email: {
minlength: "Please enter a valid email"
},
}, //End messages
errorPlacement: function(error, element) {
error.appendTo(element.next());
}
} //End validationObj
); //End var validationObj
$("#contactForm").submit(function(e) {
if (!validationObj.form()) {
alert("Form Errors");
} else {
alert("Form Valid");
}
});
I have this view:
return Backbone.Marionette.ItemView.extend({
template: template,
ui: {
form: '#login',
button: '#submitbutton'
},
onRender: function() {
this.ui.form.on('submit', function(e) {
// e.preventDefault();
mylogin = new login();
mylogin.save({boxid:$("#boxid").val(),password:$("#passwordid").val(),validate:true});
vent.trigger('navigate', 'home');
// if(myLogin.validationError) {
// vent.trigger('navigate', 'home');
// }
return false;
});
}
});
and this model:
return Backbone.Model.extend({
validate: function(attrs, options){
if(attrs.boxid.length < 10)
{
return "user id must be more than 10 characters";
// return "BoxID should be greater than 10";
}
else if(attrs.password.length < 10)
{
return "password must be more than 10 characters";
// return "Password should be greater than 10";
}
else if((attrs.boxid!=myBoxid)||(attrs.password!=myPassword))
{
return "Your login credentials are incorrect";
}
},
});
And this login html template:
<div class>
<div>Information</div>
<div>
<form id="login" name="login" method="post">
<div>
<label for="boxid">BoxID</label>
<input id="boxid" name="box" placeholder="Enter your box ID">
</div>
<div>
<label for="password">Password</label>
<input id="passwordid" type="password" name="password" placeholder="Password">
</div>
<label id="errormsg"></label>
<button id="submitbutton">Login</button>
</form>
</div>
</div>
The problem is that each time the user enters wrong credentials the page reloads, are there any way to prevent this?
To make this work you should but back the e.preventDefault(); line.
More important is that the model has no url function http://backbonejs.org/#Model-url
return Backbone.Model.extend({
url: function () {
// see the docs, it can be a url string or a function
}
validate: function(attrs, options){
},
});