How can we require a user to place a specific number in a text input and validate against an exact number (or any value). In this case 001 (starting digits of an account number). The value 001 is a way to determine if the user is likely to have an account to proceed.
Am using jQuery.validate - http://jqueryvalidation.org
Have the following:
For validation I have:
$("#form1").validate({
messages: {
acn_01: {
required: 'Please enter a valid account number',
range: [001,001]
}
}
});
Range does not seem to work with [001] or [001,001]. Is there another method or technique to do this?
Thanks all.
Your code...
messages: { // <- MESSAGES option
acn_01: {
required: 'Please enter a valid account number',
range: [001,001] // <- this is not a message
}
}
The problem is that you are trying to put put rule parameters into the messages option. The messages option is for custom messages and the rules option is for declaring the rules/paramters.
$("#form1").validate({
rules: { // <- rules option
acn_01: {
required: true, // <- rule: parameter
range: [1, 1] // <- rule: parameter
}
},
messages: { // <- messages option
acn_01: {
required: 'Please enter a valid account number', // <- custom message
range: 'Please enter the number {0}' // <- custom message
}
}
});
DEMO: http://jsfiddle.net/wxfaborn/
BTW: You cannot use a string (001) or a pattern within the range method... it's only looking for a range of numbers, in this case from 1 up to 1.
EDIT:
Otherwise, you could use the pattern method (part of the additional-methods.js file) along with a regex as the parameter. Or you could use the .addMethod() method to write your own function, thereby creating a custom rule.
Here is a very simple demo of .addMethod().
jQuery.validator.addMethod("myRule", function(value, element, params) {
return this.optional(element) || value == params[0];
}, "Please enter the correct value of {0}");
$("#form1").validate({
rules: {
acn_01: {
required: true,
myRule: ["001"]
}
}, ....
http://jsfiddle.net/wxfaborn/1/
Why do you have to use this validate plugin when all your trying to do is compare the users input to "001"? Just make your own validate plugin that does what you want.
$.fn.validate001 = function(){
if(this.val()=="001")return true;
else return false;
};
$("#input").validate001();
If you need "001" to be at the beginning (but they may have numbers after that) use:
$.fn.validate001 = function(){
if(this.val().indexOf("001")==0)return true;
else return false;
};
$("#input").validate001();
Of if "001" needs to be at the end of the string use:
$.fn.validate001 = function(){
if(this.val().indexOf("001")==this.val().length-4)return true;
else return false;
};
$("#input").validate001();
I don't see a need to use a plugin for something so simple.
Related
Here is my regex:
var emailsRegex = /^[\W]*([\w+\-.%]+#[\w\-.]+\.[A-Za-z]{2,4}[\W]*;{1}[\W]*)*([\w+\-.%]+#[\w\-.]+\.[A-Za-z]{2,4})[\W]*$/;
Currently it allows fully qualified single emails and multiple emails separated by semicolon, example:
email1#hi.com
email1#hi.com; email2#hi.com
email1#hi.com; email2#hi.com; email3#hi.com
...are all valid.
I want this to stay the same, but also allow blank/empty inputs. My form is flagging $invalid with a blank input field, even though the required attribute is not specified on the input field.
I suspect this is because it is not passing the regex validation. Thanks!
Please do not use a regex to match an email. First of all your regex is wrong (it won't match emails like foo+bar#example.org which is perfectly valid given RFC822 and newer RFCs). You should better use a library like verifyjs or fogcreek's email checker to check that email.
Then all you have to do is to split your string around each emails using email_string.split(';') and apply the checker on each of them.
HTH
I ended up using string.split(;) and then passing through an improved RegEx which should account for 99% of email addresses in use today. And I'm doing it inside an Angular Directive.
It allows for empty inputs, multiple emails separated by ; which comply with the RFC for majority usage of email addresses.
HTML
<input type="text" id="emailCc" name="emailCc" ng-model="vm.ccRecipient" class="form-control input-sm" multiple-emails="vm.ccRecipient" placeholder="Email Cc" />
AngularJS
angular.module('my-app')
.directive('multipleEmails', function () {
return {
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
ctrl.$parsers.unshift(function (rawInput) {
var emails = rawInput.split(';');
//console.log(emails);
// Consider not using complex regex validation for emails. See: https://davidcel.is/posts/stop-validating-email-addresses-with-regex/
// Instead, consider just checking for an "#" and a "." and call it a done. The mail daemon will return whether its a valid or invalid/bounced email address
//var emailsRegex = /.+#.+\..+/i;
// define single email validator here
var regexPattern = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
// angular.foreach(emails, function() {
var validityArr = emails.map(function (str) {
if (rawInput) {
return regexPattern.test(str.trim());
} else if (!rawInput) {
return true;
}
}); // sample return is [true, true, true, false, false, false]
//console.log(emails, validityArr);
var atLeastOneInvalid = false;
angular.forEach(validityArr, function (value) {
if (value === false)
atLeastOneInvalid = true;
});
if (!atLeastOneInvalid) {
// ^ all I need is to call the angular email checker here, I think.
ctrl.$setValidity('multipleEmails', true);
return rawInput;
} else {
ctrl.$setValidity('multipleEmails', false);
return undefined;
}
});
}
};
});
I am using below code to validate fax number field in my qform
if(objFormEdit.postalCode.defaultValue.length <=5){
objFormEdit.postalCode.validateFormat('xxxxx','numeric', "Postal Code requires either a 5 or 9-digit number in either the format 'xxxxx' or 'xxxxx-xxxx'.");
}
else{
objFormEdit.postalCode.validateFormat('xxxxx-xxxx','numeric', "Postal Code requires either a 5 or 9-digit number in either the format 'xxxxx' or 'xxxxx-xxxx'.");
}
Its working fine but when i enter 1234-12345 then its change it to 12341-2345 and does not show any error. why its happening. I want error message in this case also.
Used custom function in qforms as below and it solved my problem.
function __isValidPostalCode()
{
var regx="^[0-9]{5}(?:-[0-9]{4})?$";
var regxObj = new RegExp(regx);
if( regxObj.test(this.value) == false )
{
this.error = "Postal Code requires either a 5 or 9-digit number in either the format 'xxxxx' or 'xxxxx-xxxx'.";
}
}
Load the function
_addValidator("isValidPostalCode", __isValidPostalCode);
called it as below
objFormEdit.postalCode.validateValidPostalCode();
I am trying to use this open source image uploader: https://github.com/blueimp
The documentation says that the function to match on File Type can be used to match on file name also.
https://github.com/blueimp/jQuery-File-Upload/blob/7d46990486ff08acfc001b6368b09bce6712c2c2/js/jquery.fileupload-validate.js
Can anyone see a way to use this to match on and restrict special characters in the file names?
Here is the RegEx that will match the characters that I specifically want to exclude. I am trying to prevent end users from using special characters in file names, instead of just depending on training them. English is the only concern in this case.
[&~##$^*()_+=/:?;\\|<>"',!%]
Here is the snipit from the source code (open source) that would evaluate it. Full code available at the link above.
// The File Upload Validation plugin extends the fileupload widget
// with file validation functionality:
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
options: {
/*
// The regular expression for allowed file types, matches
// against either file type or file name:
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
// The maximum allowed file size in bytes:
maxFileSize: 10000000, // 10 MB
// The minimum allowed file size in bytes:
minFileSize: undefined, // No minimal file size
// The limit of files to be uploaded:
maxNumberOfFiles: 10,
*/
// Function returning the current number of files,
// has to be overriden for maxNumberOfFiles validation:
getNumberOfFiles: $.noop,
// Error and info messages:
messages: {
maxNumberOfFiles: 'Maximum number of files exceeded',
acceptFileTypes: 'File type not allowed',
maxFileSize: 'File is too large',
minFileSize: 'File is too small'
}
},
processActions: {
validate: function (data, options) {
if (options.disabled) {
return data;
}
var dfd = $.Deferred(),
settings = this.options,
file = data.files[data.index],
fileSize;
if (options.minFileSize || options.maxFileSize) {
fileSize = file.size;
}
if ($.type(options.maxNumberOfFiles) === 'number' &&
(settings.getNumberOfFiles() || 0) + data.files.length >
options.maxNumberOfFiles) {
file.error = settings.i18n('maxNumberOfFiles');
} else if (options.acceptFileTypes &&
!(options.acceptFileTypes.test(file.type) ||
options.acceptFileTypes.test(file.name))) {
file.error = settings.i18n('acceptFileTypes');
} else if (fileSize > options.maxFileSize) {
file.error = settings.i18n('maxFileSize');
} else if ($.type(fileSize) === 'number' &&
fileSize < options.minFileSize) {
file.error = settings.i18n('minFileSize');
} else {
delete file.error;
}
if (file.error || data.files.error) {
data.files.error = true;
dfd.rejectWith(this, [data]);
} else {
dfd.resolveWith(this, [data]);
}
return dfd.promise();
}
}
});
Edit: Some things I have tried:
Thanks for the quick responses. Some things I have tried here:
Many of these return the the match even it it the name is preceeded by an invalid character.
See http://regexr.com/3be9o
I don't want asdf&ghjik.jpg to match as valid.
I guess I really want a-z A-Z 0-9 - _
[^&~##$^*()_+=/:?;\\|<>"',!%]([\w]+\-*[\w]+)+(\.|\/)(gif|jpe?g|png)
([^&~##$^*()_+=/:?;\\|<>"',!%])?([\w]+\-*[\w]+)+(\.|\/)(gif|jpe?g|png)
([\w]+\-+[\w]+)+(\.|\/)(gif|jpe?g|png)
[^&~##$^*()_+=/:?;\\|<>"',!%]*(\.jpg)|[^&~##$^*()_+=/:?;\\|<>"',!%]*(\.png)|
[^&~##$^*()_+=/:?;\\|<>"',!%]*(\.gif)|[^&~##$^*()_+=/:?;\\|<>"',!%]*(\.jpeg)
As #Nit pointed out in a comment, white-listing rules is always better than black-listing. This means always try to specify what's allowed rather than what's forbidden as it is very easy to miss something (Did you think of pound sign? Non-English alphabets? UTF characters in general?)
As a start you can use the very simple [\w\.\- ]
The \w metacharacter is used to find a word character.
A word character is a character from a-z, A-Z, 0-9, including the _ (underscore) character.
For a good explanation on what are good/bad file names in Windows take a look at this thread.
The script below is suppose to insert a message using .insertAfter() if a user doesn't type in an # symbol within a field . This script also displays an error message if the user types in a value that matches a value from the invalidEmailAddresses array.
For some reason only the second part of this script executes.
If a user types in an # symbol they get a message but if the user types in an address similar to test#yahoo.com a message doesn't display. Not sure if i organized the code correctly.
$(document).ready(function(){
$("input[name='emailAddress']").blur(function(){
// Actual Email Validation function
var hasError = false;
var emailaddressVal = $("input[name='emailAddress']").val();
var invalidEmailAddresses =
['goddady.com', 'aol.com', 'yahoo.com', 'yahoo.fr'];
if ($.inArray(emailaddressVal,invalidEmailAddresses) > 0) {
$( "<span id='emailMessage'>The email provided is not from a business related domain. Please use an appropriate email address instead.</span>" ).insertAfter( "input[name='emailAddress']" );
} else {
$ ('#emailMessage').css('display','none');
}
if ($("input[name='emailAddress']").val().indexOf('#') > -1) {
$ ('#emailMessage').css('display','none');
}
else {
$( "<span id='emailMessage'>The email provided does not contain an # symbol</span>" ).insertAfter( "input[name='emailAddress']" );
}
if(hasError == true) { return false; }
});
});
This is working if you add the following code
$(document).ready(function() {
$("input[name='emailAddress']").blur(function() {
// Actual Email Validation function
$('#emailMessage').html("");
var hasError = false;
var emailaddressVal = $("input[name='emailAddress']").val().trim();
var invalidEmailAddresses = ['goddady.com', 'aol.com', 'yahoo.com', 'yahoo.fr'];
if (!isValidEmailAddres(emailaddressVal)) {
$("<span id='emailMessage'>The email provided does not contain an # symbol</span>").insertAfter("input[name='emailAddress']");
hasError = true;
} else {
debugger
emailaddressVal = emailaddressVal.split('#').slice(1)[0].trim();
if ($.inArray(emailaddressVal, invalidEmailAddresses) >= 0) {
$("<span id='emailMessage'>The email provided is not from a business related domain. Please use an appropriate email address instead.</span>").insertAfter("input[name='emailAddress']");
} else {
$('#emailMessage').css('display', 'none');
}
}
if (hasError == true) {
return false;
}
});
function isValidEmailAddres(emailID) {
var regexExp = new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))#((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);
return regexExp.test(emailID);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input name="emailAddress" />
The issue lies with this if conditional: if ($.inArray(emailaddressVal,invalidEmailAddresses) > 0).
Since the $.inArray() method returns the index of a string found, when a value of 0 is returned, it is actually found—but at the start of the string (position 0, because JS is zero-based). So, you should use !== -1 instead, i.e.: if ($.inArray(emailaddressVal,invalidEmailAddresses) !== -1).
However, this does not completely solve your issue — $.inArray() only compares string, it does not search for it. Therefore if your string contains the blacklisted email domains, but does not match exactly, it will return false. In this case, you should use regular expression instead. The strategy is simple: use .each() to loop through your array, and take the value, use it to construct an expression which we will test your email address that is provided against.
Also, since there is the possibility that the user-entered email address fails both tests, two <div> of identical IDs will appear. This is invalid HTML. Instead, try using a class instead.
p/s: I also recommend changing listening to .blur() to .change() instead. It is more robust :)
With all the points above considered, I have refactored your code a little:
Declare a global (but still within function scope) error array called hasError. It will be used to store all error messages you get, since we cannot be sure if there will be one, or more than one error.
We construct two tests:
To test if email matches against blacklist using the string.search(regexp) method. If there is a match, the value returned will exceed -1. We then push the relevant error message into hasError in an object
To test if email contains the # sign, we use your default logic (which works beautifully). If there is an error, we push, again, the relevant error message into hasError in an object
At the end, we evaluate hasError. If it is not empty, then we know there is an error somewhere, and loop through it. The error messages are accessible via the messages keyword :)
Without further ado, here's your code:
$(document).ready(function() {
$("input[name='emailAddress']").change(function() {
// Actual Email Validation function
var hasError = [],
emailaddressVal = $("input[name='emailAddress']").val(),
invalidEmailAddresses = ['godaddy.com', 'aol.com', 'yahoo.com', 'yahoo.fr'];
// Check against blacklist
$.each(invalidEmailAddresses, function(i, v) {
var pattern = new RegExp(v, 'i');
if (emailaddressVal.search(pattern) > -1) {
hasError.push({
'test': 'blacklist',
'message': 'The email provided is not from a business related domain. Please use an appropriate email address instead.'
});
}
});
// Check if there is an '#' character
if ($("input[name='emailAddress']").val().indexOf('#') === -1) {
hasError.push({
'test': '# sign',
'message': 'The email provided does not contain an # symbol'
});
}
console.log(hasError);
// Error handling
$('#error').remove();
if(hasError.length > 0) {
var $error = $('<div id="error"><ul></ul></div>');
$.each(hasError, function(i,v) {
$error.find('ul').append('<li>'+v.message+'</li>');
});
$error.insertAfter("input[name='emailAddress']");
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<input name="emailAddress" type="email" />
</form>
I'm using the jQuery.validate plugin to validate inputs for my user registration form.
I've got the simple case working(make sure user name is at least 6 characters)
$('#new_user').validate({
rules: {
"user[name]": {
required: true,
minlength: 6,
remote:"/check_name"
}, ...
One caveat I'd like to add to the above rule is to allow a minimum of 2 Chinese characters OR 6 regular characters to pass the length test. (This is considered good usability for Chinese users, many of whom has 2-3 Chinese Character names in real life)
For example, I'd like the following names to pass the length test:
"张三"
"Michael"
and the following names to fail(due to being too short)
"张"
"Mike"
How do you write a custom javascript function to check for these conditions?
Something like :
function validate(string) {
var re = /^[\u3300-\u9fff\uf900-\ufaff]{2,}$/;
return string.length >= 6 || string.match(re);
}
validate("pat")
validate("patate")
validate("中")
validate("中国")
See the Unicode Roadmap for details [1]
[1] http://unicode.org/roadmaps/bmp/
You can use the internationalization plugin so that you can do this test:
function returnMinLength(){
var browserLanguage = jQuery.i18n.browserLang();
if (browserLanguage == "zh") // zh stands for chinese (I'm not sure)
return 2;
else
return 6;
}
Then, in your function:
rules: {
"user[name]": {
required: true,
minlength: returnMinLength(),
remote:"/check_name"
}, ...
Regards.