I have multiple forms in different page, Is there a way to write a single function which would take care of validation or should i write code for each form separately.
$(document).ready(function () {
$('#fvujq-form1').validate();
$('#fvujq-form2').validate();
});
Note: Each form has its own rules.
Update:
$("form").each(function () {
$(this).validate({
rules: {
username: {
required: true
},
password: {
required: true
},
name: {
required: true,
},
cperson: {
required: true,
}
},
submitHandler: function (form) {
return false; //temporarily prevent full submit
}
});
});
Now the username and password of different form and name and person is of different form in different page. Is it right to proceed in this way of having a common form submission.
You should test using $('form').validate();, if that doesn't work, then use:
$('form').each(function(){
$(this).validate();
});
You can use the $("form") selector to validate all elements of type form if that's what you are asking for. I would not recommend that specifically for a page with multiple forms though.
If you can give each input element in your form a custom xx-field-type attribute eg:
<input type='text' xx-field-type='email'/>
You could use:
jQuery.fn.extend({
validate: function() {
var input_list = this.find("input");
for (var i = 0; i < input_list.length; i++) {
switch(input_list[i].attr("xx-field-type")) {
case 'username':
var value = input_list[i].val();
if (value.match(/^[a-z0-9]+$/) != true) {
return false;
}
break;
case 'password':
var value = input_list[i].val();
if (value.match(/[a-z]+/) != true
|| value.match(/[A-Z]+/) != true
|| value.match(/[0-9]+/) != true) {
return false;
}
break;
case 'email':
var value = input_list[i].val();
if (value.match(/^[a-z0-9]+#[a-z0-9]$/) != true) {
return false;
}
break;
default:
continue;
}
}
return true;
}
});
This would go through each input field of a form, check the value of it's xx-field-type attribute and use that to choose the rules that the value must match. Returns false if any fail otherwise returns true.
If you can't add custom attributes you could use classes but it feels hacky to denote form type using an attribute intended for setting display related stuff.
Untested
the field types I've used and the regexps are just for the purposes of demonstration.
Related
I have a form with multiple fields (lets say 4 for this example).
I am using javascript functions on each field to validate them, generating an error indication - a red box, or a hint as text next to the box.
like so ..
<input
...
onkeyup="validateName()"
onblur="checkDuplicateName(); validateName()"
>
So what I would like to do is not allow a submit if any of the fields do not validate.
So the question is - what is the best way to set it up so submit is disabled unless all 4 fields are valid?
I will use either
document.getElementById("mySubmit").disabled=true;
or
event.preventDefault()
(..though trying to avoid Jquery) to prevent the submit.
How should I keep track of the condition of the 4 fields?
Should I create a global variable like - window.validFields, so I can access it from each of my validation functions - adding one to the variable for each field that is valid, and subtracting one when invalid? (window.validFields==4 allows a submit)
Not sure the best way to accomplish this.
Any help would be appreciated, thanks.
Assuming a form like this …
<form class="is-invalid" id="form" method="post">
<input type="text" id="lorem">
<input type="text" id="ipsum">
<input type="text" id="dolor">
<input type="text" id="amet">
<button id="submit">Submit</button>
</form>
… you could do the following …
(function () {
var fields = {
lorem: false,
ipsum: false,
dolor: false,
amet: false
},
isValid = false,
form = document.getElementById('form'),
i,
tmpInput;
// Binding submit-event to prevent form-submit
form.addEventListener('submit', onSubmit, false);
// Binding events on input-elements (keyup & blur)
for ( i in fields ) {
tmpInput = document.getElementById(i);
tmpInput.addEventListener('keyup', checkInput, false);
tmpInput.addEventListener('blur', checkInput, false);
}
// Checking form state by iterating over the fields object;
// Adding/removing 'is-valid'-class and setting `isValid`-flag
function checkFormState() {
for ( var j in fields ) {
if ( !fields[j] ) {
isValid = false;
form.className += /\bis-invalid\b/i.test(form.className)
? ''
: 'is-invalid';
return;
}
}
form.className = form.className.replace(/\bis-invalid\b/i, '');
isValid = true;
}
// Abort the submit, if the `isValid`-flag is `false`
function onSubmit(evnt) {
if ( !isValid ) {
evnt.preventDefault();
return false;
}
}
// Setting the corresponding value in the `fields`-object;
// Checking the form state
function checkInput() {
fields[this.id] = this.value.length > 5; // or any other validation rule
checkFormState();
}
})();
There's an object with the IDs of the relevant input-fields that holds each validation state. On keyup and blur each input field is checked. If it passes the validation, the corresponding value in the fields-object is set to true. Additionally the state of the form is checked on each event on an input element.
The checkState-function iterates over the fields-object. If it finds a property, that is false, the 'is-invalid'-class is set on the form-element (if it isn't already set), the isValid-flag is set to false and the function is aborted.
Otherwise — all input-fields are valid —, the isValid-flag is set to true and the 'is-invalid'-class is removed from the form-element. Now, the form can be submitted.
This all works without a single global variable. Mission accomplished!
I made a Fiddle where you can test this.
PS: Have in mind, that the addEventListener-method is only supported by IEs down to version 9. If you have to support version 8 and below, you need a workaround like this.
I hope this helps you.
You can use the forms submit event, like this:
HTML:
<form method="post" onsubmit="return MyValidation(); " ...
JS:
(function() {
var field1Valid = false;
var field2Valid = false;
window.validateField1 = function(elmnt) {
// do some validation...
if(everything == OK) {
field1Valid = true;
setButtonDisabled(false);
}
else {
field1Valid = false;
setButtonDisabled(true);
}
}
window.validateField2 = function(elmnt) {
// do some validation...
if(everything == OK) {
field2Valid = true;
setButtonDisabled(false);
}
else {
field2Valid = false;
setButtonDisabled(true);
}
}
window.checkDuplicateName = function() {
// do some more validation...
}
window.setButtonDisabled = function(disabled) {
document.getElementById('submit').disabled = disabled;
}
window.MyValidation = function() {
return field1Valid && field2Valid;
}
}());
The above example also checks whether to disable the submit button or not.
Another way would be to handle all your validation logic within the form submit event, but validating input immediately is always nicer.
There are also quite some validation plugins available for use with jQuery, if you're interested. Building this yourself can get messy quickly if you have multiple fields that need to be validated in multiple ways...
I have an issue with the knockout validation on hasfocus binding.
I am trying to validate the control and show an error message when the control looses focus. but when the form loads itself rule is getting triggered and it shows the error message.
is there anyway to tell on load of the form or when we initialize the rules not to fire?
self.lostfocus = ko.observable(false);
self.lostfocus.extend({ NoBlankValidationlookup: { params: { control: self }, message: "Search Text cannot be empty"} });
ko.validation.rules['NoBlankValidationlookup'] = {
validator: function (val, params)
{
////if the control looses focus then validate.
if (!val)
{
if (params.control.Value().length == 0)
{
return false;
}
else
{
return true;
}
}
else
{
return true;
}
},
message: 'Please enter at least 0 characters.'
};
//HTML
<div id="Div1" class="vm" style="display: block !important; text-align: left" data-bind="validationMessage:lostfocus"></div>
Please adivce.
use isModified(false) with your validated observable on form load.
so run something like this:
self.lostfocus.isModified(false)
You can add valueUpdate to specify when to call your rules, for instance:
self.lostfocus.extend({valueUpdate: 'afterKeyDown', NoBlankValidationlookup:
{ params: { control: self }, message: "Search Text cannot be empty"} });
I'm running into issues with the following code:
var setupSearch = {
searchSuggest: function(field) {
$.getJSON('/get-all-journals', {'url':'on'}, function(data) {
var SHCount = Number($.cookie('SHCount'));
var SHArray = new Array();
for (i=1; i <= SHCount; i++) {
SHArray.push($.cookie('SH'+i));
}
$(field).ddautocomplete(removeDuplicate(SHArray), data.response.docs, {
matchContains: true,
max: 5,
cacheLength: 5000,
selectFirst: false,
scroll: false,
formatResult: function(str) { return str; },
formatItem2: function(item) {
return item.journal_display_name;
},
formatMatch2: function(item) {
return item.journal_display_name;
},
formatResult2: function(item) {
return item.journal_display_name;
}
});
});
},
searchForm: function(form) {
var field = form.find('textarea');
// Setup query field for default text behavior
// setupField(field);
setupSearch.searchSuggest(field);
field.autogrow();
field.keydown(function(e) {
if (e.keyCode == 13) {
form.submit();
return false;
}
});
// Make all forms submitting through Advanced Search Form
form.submit(function(e) {
e.preventDefault();
setupSearch.submitSearch(form, field);
});
},
submitSearch: function(form, field) {
if (advancedSearch.checkMinFields() || (!field.hasClass('defaultText') && field.val() != '')) {
// Sync the refine lists
// syncCheckboxLists($('#refineList input'), $('#advancedRefineList input'));
form.find('button').addClass('active');
$('#advancedSearchForm').submit();
} else {
$('#queryField').focus();
}
},
When I try to use the autocomplete drop-down by hitting enter, it seems to hit a "race condition" where the form will submit what I've typed rather than what autocomplete places into the textfield. Is there some way I can control the order of events so that the form.submit() will use what autocomplete fills into the text field?
The actual autocomplete dropdown menu is most likely represented as a styled list (or some other element) that is floated to be positioned below the textbox. On submit, have your function wait (a second or two max) for the autocomplete menu to be either destroyed or hidden. This will ensure that the plugin has time to fill in the textbox before the data is submitted.
EDIT
Try something like this:
$("#myDropdown").bind("autocompleteclose", function(){
// Continue with submitting your form
});
Use that where you would submit your form, and put the submitting code inside the callback. That way, it will wait for the autocomplete to close before submitting the form. You will want to add some kind of timeout to this to prevent it from submitting after a long delay (not sure when something like this might happen, though).
I'm using jQuery Validation Plugin 1.9.0 (from http://bassistance.de/). The problem is that I can't figure out how to validate a text field only if a user type something in it. If the user did not write anything that field should not be treated as required.
Do not set the required rule option -
rules : {
text1 : {
required: false, // Or do not specify the option
minlength: 3 // validation if it has value
}
},
if ( value != '' ) {
// Do your validation here
}
You can pass a function to a validation rule. For instance
$("#demoForm").validate({
rules: {
"requiredField": {sampleRule: function(e){
var input = $(e);
if(input.val())
return true;
return false;
}
}
},
messages : {
"requiredField": "This field is invalid"
}
Where "sampleRule" can be any rule you want eg. "required" or "minlength". The function gives the power to add conditional rule.
Is is possible to restrict the user input to only the source values with JQuery autocomplete plugin?
For example, if the source array contains "Bold","Normal","Default","100","200", the user is allowed to only type those values.
I see you already have a solution. Here's a similar way to do this, since I already put some time in on it.
http://jsfiddle.net/pxfunc/j3AN7/
var validOptions = ["Bold", "Normal", "Default", "100", "200"]
previousValue = "";
$('#ac').autocomplete({
autoFocus: true,
source: validOptions
}).keyup(function() {
var isValid = false;
for (i in validOptions) {
if (validOptions[i].toLowerCase().match(this.value.toLowerCase())) {
isValid = true;
}
}
if (!isValid) {
this.value = previousValue
} else {
previousValue = this.value;
}
});
I have a simple alternative. Check this out:
http://jsfiddle.net/uwR3Z/2/
Basically an onChange event on the textbox to clear out the value works the same.
Here is the js:
var validOptions = ["Bold", "Normal", "Default", "100", "200"];
$('#auto-complete-input').autocomplete({
autoFocus: true,
source: validOptions
});
function clearAutoCompleteInput() {
$("#auto-complete-input").val('');
}
And html:
<label for="auto-complete-input">Select one: </label>
<input id="auto-complete-input" type="text" onChange="clearAutoCompleteInput()" />
I agree with the comment made by Rephael, as you want to limit the possible values to the one in autocomplete, a safer choice would be to have a select dropdown.
As a final user can be frustrating to enter data in a textbox and not being able to write what I want. The choice of a select dropdown is "socially" accepted to be limited.
I figured out a way.
Add the following option to the plugin. This works for when the source is an array.
change: function (event, ui) {
if (!ui.item) {
var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val()) + "$", "i"),
valid = false;
$.each(YOUR_SOURCE_ARRAY_NAME, function (index, value) {
if (value.match(matcher)) {
this.selected = valid = true;
return false;
}
});
if (!valid) {
// remove invalid value, as it didn't match anything
$(this).val("");
return false;
}
}
}
This is an old question but I what I do is
set a flag to false when entering the field (onfocus)
Set the flag to true in the autocomplete select event
Test that flag in the field onblur event.
If it is true the input is good, otherwise it is bad.