I am using jQuery mobile theme and jQuery validate plugin for validation purpose. The behavior of the plugin is un-expected. First see my html code
<ul data-role="listview" data-inset="true" id="updatepage">
<form method="POST" action="/update-account-info" accept-charset="UTF-8" data-ajax="false" id="updateUser">
<div data-role="content">
<li data-role="fieldcontain">
<input required="required" class="slide1el" id="first_name" data-clear-btn="true" placeholder="First Name" name="first_name" type="text" value="Awais">
<div class="error-wrapper"></div>
</li>
<li data-role="fieldcontain">
<input class="slide1el" id="last_name" data-clear-btn="true" placeholder="Last Name" name="last_name" type="text" value="Qarni">
<div class="error-wrapper"></div>
</li>
<li data-role="fieldcontain">
<input class="slide1el" id="website" data-clear-btn="true" placeholder="Website URL" name="website" type="text">
<div class="error-wrapper"></div>
</li>
<div>
<div class="ui-block-a"><button type="button" data-theme="a">Cancel</button></div>
<div class="ui-block-b"><button type="submit" data-theme="a">Submit</button></div>
</div>
</div>
</form>
</ul>
And here is my javascrip code
jQuery("#updateUser").validate({
errorElement: "label",
focusCleanup: true,
rules: {
first_name: {
required : true
},
last_name: {
required : true
},
website: {
required : true,
url : true
}
},
messages : {
first_name : {
required : 'First Name is required',
},
last_name : {
required : 'Last Name is required',
},
website : {
required : 'Website is required',
url : 'Please enter correct URL'
}
},
onkeyup: false,
errorPlacement: function (error, element) {
element.parents('li').find('div.error-wrapper').html(error)
element.parents('li').find('div.error-wrapper').find('label').removeClass('error_text');
},
// set the errorClass as a random string to prevent label disappearing when valid
errorClass : "error_text",
validClass : "ui-focus",
// use highlight and unhighlight
highlight: function (element, errorClass, validClass) {
jQuery(element).parent().addClass(errorClass).removeClass(validClass);
},
unhighlight: function (element, errorClass, validClass) {
jQuery(element).parent().removeClass(errorClass)
jQuery(element).parent().next().find('label').remove();
jQuery(element).parent().parent().next().find('label').remove();
}
});
What I am currently doing that when user submits form, I try to validate the form. If input field is empty, add a red border to the field and show the custom error message in div class=error-wrapper.
But when I submit error button, it only creates focus on first empty field it finds in DOM. And when I click anywhere in DOM, it shows the error class and highlight the textbox. I saw it in firebug, when I click submit button, It adds a ui-focus class to the empty element. When I click anywhere in DOM, the ui-focus class is automatically removed and my error classes are added.
I even tried to remove ui-focus class but it doesn't work. Kindly guide me what am I doing wrong?
What's not clear from your code is what the point of the highlight/unhighlight functions are?
I found that if I removed them and also set focusInvalid:false everything started working nicely.
So your validate call ends up looking like this (I took out the rules and messages for brevity):
jQuery("#updateUser").validate({
focusCleanup: true,
focusInvalid: false,
/* rules and messages here */
onkeyup: false,
errorPlacement: function (error, element) {
element.parents('li').find('div.error-wrapper').html(error)
element.parents('li').find('div.error-wrapper').find('label').removeClass('error_text');
},
errorClass : "error_text",
validClass : "ui-focus"
});
It works as I would expect, see here: http://jsfiddle.net/ryleyb/DC5Sz/1/
Related
I am using jQuery validation to validate my form fields. I've two fields, named "comment" and "account name". The comment field has a validation method where required is set to false. The account name field has a validation method where required is set to true. When the user clicks the submit button without entering any value on both fields, the comment field was not highlighted in green even though this field is not required. Why is that so?
$(document).ready(function () {
$.validator.setDefaults({
highlight: function (element, errorClass, validClass) {
if (element.type === "radio") {
this.findByName(element.name).addClass(errorClass).removeClass(validClass);
} else {
$(element).closest('.form-group').removeClass('has-success').addClass('has-error has-feedback');
$(element).closest('.form-group').find('span.glyphicon').remove();
$(element).closest('.form-group').append('<span class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>');
}
},
unhighlight: function (element, errorClass, validClass) {
if (element.type === "radio") {
this.findByName(element.name).removeClass(errorClass).addClass(validClass);
} else {
$(element).closest('.form-group').removeClass('has-error has-feedback').addClass('has-success has-feedback');
$(element).closest('.form-group').find('span.glyphicon').remove();
$(element).closest('.form-group').append('<span class="glyphicon glyphicon-ok form-control-feedback" aria-hidden="true"></span>');
}
}
});
$('#dataForm').validate({
rules: {
accountNameInput: {
required: true
},
commentInput: {
required: false
}
},
submitHandler: function (form) {
alert('success');
}
});
});
<form id="dataForm" method="post" action="#">
<div class="form-group">
<label class="control-label" for="commentInput">Comments</label>
<textarea class="commentInput" id="commentInput" name="commentInput" rows="5"></textarea>
</div>
<div class="form-group">
<label class="control-label" for="accountNameInput">Account name</label>
<input type="text" id="accountNameInput" name="accountNameInput"
placeholder="Account name" class="form-control font-bold" value="" />
</div>
<input type="submit" class="btn btn-primary" value="Save" id="saveButton" />
</form>
DEMO: https://jsfiddle.net/Issaki1/gud7xjy0/
Your commentInput field is not "required", therefore this field will be totally ignored for validation whenever it's left empty.
However, you can programmatically force it to validate using the .valid() method whenever the submit is clicked.
$('#saveButton').on('click', function() {
$('#commentInput').valid(); // <- force validation test on this field
});
Working DEMO: jsfiddle.net/gud7xjy0/6/
Optionally, you can also force this empty field to validate when you focusout of it...
// force eager validation on this one field
$('#commentInput').on('focusout', function() {
$(this).valid();
});
Working DEMO 2: jsfiddle.net/gud7xjy0/9/
However, this demo #2 does not make sense; since validation for the form is still "lazy" (the other field will be ignored on focusout until the submit is clicked). Option #2 only makes sense when you have your whole form setup to also implement "eager" style validation.
I have a form which I want to validate but I cannot get the validator working.
the main page is in ASP.NET C#.
I have the main tag and will be using an ajax callout on the submitHandler to submit the form.
Inside the form tag, I have a div which is a jquery dialog box. Inside that div, I have all the fields and the button to submit the form (which is actually a button with a jquery .click event).
Fields are like this:
<input class="last_name_class modal__input__font" id="lastname" style="width:100%;" type="text" value="" runat="server" />
This is the button to submit
<input class="btn_red" id="btn_Submit" type="button" value="CREATE CUSTOMER" />
When the button is clicked, it fires this:
$('#btn_Submit').click(function () {
$('#form1').valid();
});
And this is my validate() function
$('#form1').validate({
rules: {
<%=lastname.ClientID%> :{
required: true,
},
<%=firstnames.UniqueID%> :{
required: true,
},
<%=dob.UniqueID%> :{
required: true,
},
<%=addressline1.UniqueID%> :{
required: true,
},
<%=suburb.UniqueID%> :{
required: true,
},
<%=state.UniqueID%> :{
required: true,
},
<%=postcode.UniqueID%> :{
required: true,
},
},
highlight: function(element, errorClass) {
alert(element);
$(element).addClass(errorClass);
$(element.form).find("label[for=" + element.id + "]").addClass(errorClass);
},
unhighlight: function(element, errorClass) {
$(element).removeClass(errorClass);
$(element.form).find("label[for=" + element.id + "]").removeClass(errorClass);
},
submitHandler: function (form) {
// do other things for a valid form
//form.submit();
}
});
When I click on the button nothing seems to happen. I can't even tell if the validate is being triggered.
Thanks
Jquery validation works on element name, check this line:
<input class="last_name_class modal__input__font" id="lastname" style="width:100%;" type="text" value="" runat="server" />
there is no name specified. Change this to:
<input class="last_name_class modal__input__font" id="lastname" name="lastname" style="width:100%;" type="text" value="" runat="server" />
and try again.
I'm using the following knockout validation plugin: https://github.com/Knockout-Contrib/Knockout-Validation
I want to validate my fields when I click on the "Submit" button, not everytime when I change the input's value. How can I do that?
Javascript:
ko.validation.init({
insertMessages:false,
messagesOnModified:false,
decorateElement: true,
errorElementClass: 'wrong-field'
}, true);
var viewModel = {
firstName: ko.observable().extend({minLength: 2, maxLength: 10}),
lastName: ko.observable().extend({required: true}),
age: ko.observable().extend({min: 1, max: 100}),
submit: function() {
if (viewModel.errors().length === 0) {
alert('Thank you.');
}
else {
alert('Please check your submission.');
viewModel.errors.showAllMessages();
}
},
};
viewModel.errors = ko.validation.group(viewModel);
ko.applyBindings(viewModel);
HTML:
<fieldset>
<div class="row" data-bind="validationElement: firstName">
<label>First name:</label>
<input type="text" data-bind="textInput: firstName"/>
</div>
<div class="row" data-bind="validationElement: lastName">
<label>Last name:</label>
<input data-bind="value: lastName"/>
</div>
<div class="row">
<div class="row">
<label>Age:</label>
<input data-bind="value: age" required="required"/>
</div>
</div>
</fieldset>
<fieldset>
<button type="button" data-bind='click: submit'>Submit</button>
</fieldset>
This is my jsfiddle: http://jsfiddle.net/xristo91/KHFn8/6464/
Well, yes the validators do get fired when the observables change. But... you can trick'em with the onlyIf Option of the validators.
I made a Fiddler sample how it could work .
The question here is more... what do you want to do after the first time the user clicked....
Basically the sample puts an onlyIf condition to all validators, and the validateNow observable, decides when the validators should evaluate..basically as you wanted... in the submit method.
self.validateNow = ko.observable(false);
the onlyIf gets evaluated on all validator:
self.firstName = ko.observable().extend({
minLength: {
message:"minlength",
params: 2,
onlyIf: function() {
return self.validateNow();
}
},
and the validateNow only gets set on the submit
self.submit = function() {
self.validateNow(true);
... I also rearenged a bit the data-bindings, because your sample only puts the red box around on of the inputs.
I'm used to create my closures with constructors..so the sample is not the same "architecure" as yours, but I think you will undertsand it
I'm new to jQuery and the .Validate jQuery Validation Plugin. I'm trying to integrate it into a multi-step form. Basically, I've set up a switch based on which next button the user presses and want to validate only that specific part of the form based on that.
When I successfully validate the first part of the form and move onto the second fieldset, the next set of fields come up already throwing validation errors. I've tried disabling the fields (which prevents the slider logic I'm using from working for some reason), specifically telling it to ignore that fieldset by class and directly declaring ignore: ":hidden" even though it's the default behavior.
I've placed the code I'm having trouble with in a jsFiddle here: http://jsfiddle.net/13x7Lbk7/4/ (updated)
Here is the specific part of my code that calls validation for the first step of the form:
$(".next").click(function(){
// Initialize form
var form = $("#frmSignup");
// Determine which step of the form we're on
switch($(this).attr("value")) {
case "step1":
$("#frmSignup").validate({
rules: {
txtZipCode: {
required: true,
number: true,
minlength: 5,
maxlength: 5,
},
txtSchoolName: {
required: true,
minlength: 5,
},
},
messages: {
txtZipCode: {
required: "Zip Code Required",
number: "Enter a valid 5 digit zip code",
minlength: "Enter a valid 5 digit zip code",
},
txtSchoolName: {
required: "School Name Required",
},
},
});
break;
// --- SNIP ---
} // End step switch
if ($("#frmSignup").valid() == true){
// Fieldset logic is here, see jsFiddle if you're curious
} // End isValid if
}); // End click function
And here is the relevant HTML for the first two fieldsets:
<fieldset class="fsStep1">
<h2>Step 1</h2>
<h3>Information</h3>
<label for="txtZipCode">Zip Code</label>
<input type="text" name="txtZipCode" value="" pattern="\d*" id="txtZipCode" required />
<label for="txtExample">Example Field</label>
<input type="text" name="txtExample" value="" id="txtExample" required />
<hr />
<button name="next" value="step1" class="next action-button">Next</button>
</fieldset>
<fieldset class="fsStep2">
<h2>Step 2</h2>
<h3>Example</h3>
<label for="txtInfo">Info</label>
<input type="text" name="txtInfo" id="txtInfo" value="" pattern="[a-zA-Z -]+" required />
<label for="txtOther">Other</label>
<input type="text" name="txtOther" id="txtOther" value="" pattern="[a-zA-Z -]+" required />
<hr />
<input type="button" name="previous" class="previous action-button" value="Previous" />
<button name="next" value="step2" class="next action-button">Next</button>
</fieldset>
I'm sure I'm missing something boneheaded here, but I keep going through the code, reviewing documentation, searching the web and I've been coming up against a blank wall all day. Please put me out of my mysery and tell me exactly why I'm stupid. :) Thank you!
Ok, if it does not like hidden fields, use this trick to hide them:
/*Hide all except first fieldset*/
#frmSignup fieldset:not(.shown) {
height:0;
overflow:hidden;
position: absolute;
top: -9999px;
}
Add the .shown class to your first fieldset.
You have no .next elements, but buttons named next.
So replace $(".next").click with $("button[name='next']").click.
Instead of if ($("#frmSignup").valid() == true), you can do if ($("#frmSignup").valid()).
And you'll need to remove the required attributes in your HTML, as hidden elements are not filled yet, so they prevent you from going to the next step. Let $.validate() do the job.
JS Fiddle Demo
Awesome people of Stack Overflow,
I'm trying to use Happy.js for validating my form, and it works fine. However, since my form is long and the submit button is at the very bottom of the form, I need a way to let the user know that there a errors on the form.
I'd love some help adding this functionality. Maybe unhiding a div right below the submit button or something like that.
Here's the HTML:
<form name="data" action="#" method="POST" id="JumpstartForm">
<label for="f1" class="control-label">First Name<span class='required'>*</span> </label>
<input title="First Name" type="text" id="f1" name="First_Name" class="input-large" value="" size="25" />
<div class="centered"><input type="submit" id="submitSignup" value="Submit" class="green-button" /></div>
</form>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://www.democracy-nc.org/jumpstart/js/happy.js"></script>
<script src="http://www.democracy-nc.org/jumpstart/js/happy.methods.js"></script>
Here's the js bit:
$(document).ready(function () {
$('#JumpstartForm').isHappy({
fields: {
// reference the field you're talking about, probably by `id`
// but you could certainly do $('[name=name]') as well.
'#f1': {
required: true,
message: 'Please enter your first name'
},
}
});
});
I created a JSfiddle: http://jsfiddle.net/gcasalett/E9Lq7/1/
Live page: http://democracy-nc.org/jumpstart/index.html
First post, so please be kind. Thanks!
What you need it's to use the callback that the plugin provide, called unHappy that it's called when the validation fails for any reason.
For other options you can check the Happy.js mainpage http://happyjs.com/
$(document).ready(function () {
$('#JumpstartForm').isHappy({
fields: {
// reference the field you're talking about, probably by `id`
// but you could certainly do $('[name=name]') as well.
'#f1': {
required: true,
message: 'Please enter your first name'
},
unHappy: function () {
//here you can show a div, or scroll to the last error.
},
}
});
});
Updated jsFiddle : http://jsfiddle.net/E9Lq7/4/