/** * @class ep.validate * */ /* * @copyright © Copyright 2006-2010, epages GmbH, All Rights Reserved. * * @module ep.validate */ define("ep/validate", [ "jquery", "ep", "util/mime", "ep/color", "ep/i18n" ], function ($, ep, mime) { /* * @dictionary ep.dict * * @translation {NOT_VALID} * {REQUIRED} * {NOT_IN_RANGELENGTH} * {LOWER_THAN_MINLENGTH} * {GREATER_THAN_MAXLENGTH} * {NOT_IN_RANGE} * {LOWER_THAN_MIN} * {GREATER_THAN_MAX} * {NO_EMAIL} * {NO_URL} * {NO_MIME} * {MIME_NOT_ACCEPT} * {NO_CREDITCARD_NUMBER} * {NO_NUMBER} * {NO_CURRENCY} * {NO_PERCENT} * {NO_DATE} * {NO_DATETIME} * {NO_TIME} * {NO_COLOR_VALUE} * {NO_UNIT} * {NO_UNIT_VALUE} * {NO_CSS_NUMBER} * {FLOAT_NOT_ALLOWED} * {UNKOWN_UNIT} * {NO_ENTRY_SELECTED} */ var invalid = 'NOT_VALID', isN = function( value ){ return !isNaN(value); }, pattern = function( value, pattern ) { return pattern ? ( new RegExp( ((/^\^/).test(pattern)?'':'^') + pattern + ((/\$$/).test(pattern)?'':'$') , '' ).test( value ) || invalid ) : true; }, required = function( value, req ) { return !value && req ? 'REQUIRED' : true; }, rangelength = function( value, min, max ) { min = min<0 ? 0 : min; max = max<0 ? 0 : max; var val = $.trim(value).length; if( isN(min) && min>val ){ return isN(max) ? 'NOT_IN_RANGELENGTH' : 'LOWER_THAN_MINLENGTH'; } if( isN(max) && val>max ){ return isN(min) ? 'NOT_IN_RANGELENGTH' : 'GREATER_THAN_MAXLENGTH'; } return true; }, range = function( value, min, max ) { var val = typeof value !== 'number' ? parseFloat(value,10) : value; if( isN(min) && min>val ){ return isN(max) ? 'NOT_IN_RANGE' : 'LOWER_THAN_MIN'; } if( isN(max) && val>max ){ return isN(min) ? 'NOT_IN_RANGE' : 'GREATER_THAN_MAX'; } return true; }, i18nMap = { 'date': 'd', 'dateLong': 'D', 'dateLong-time': 'f', 'dateLong-timeLong': 'F', 'date-time': 'l', 'date-timeLong': 'L', 'time': 't', 'timeLong': 'T', 'currency': 'c', 'number': 'n', 'percent': 'p' }; $.extend( $.scope('ep.validate'), { /** * Validate a email address. * * The `ep.validate.email()` method checks if the givn string an valid email address. * * ### Examples * Validate an email address. * * JavaScript: * * ep.validate.email( 'mmustermann@epages.com' ); * * Results: * * true * * Validate an email address with error return. * * JavaScript: * * ep.validate.email( 'mmustermann@epages' ); * * Results: * * NO_EMAIL * * * ### Dependencies * * + `ep` * + `ep.color` * + `jQuery.mime` * + `jQuery.i18n` * * @param {String} value A text to validate * @param {Object} [options] A map of additional options pass to the method. * @param {Boolean} options.required A boolean indication wether the value is required. * @param {Integer} options.minlength A minimum number of chars. * @param {Integer} options.maxlength A maximum number of chars. * * @method email * @static * @member ep.validate * * @since 6.11.0 */ email: function( value, options ){ value = $.trim(value); var opt = $.extend({},options||{}), valid = required( value, opt.required ); if( value && valid===true ){ valid = /^((([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.test(value) || 'NO_EMAIL'; // EPG-24121: check the local part of an email address for non-ASCII characters if( valid===true ){ var localatoms = value.split('@')[0].split('.'); $.each(localatoms, function(index) { valid = /^[\x00-\x7F]+$/.test(localatoms[index]) || 'NO_EMAIL'; return valid=='NO_EMAIL' ? false : true; }); } } return valid===true ? range( value, opt.minlength, opt.maxlength ) : valid; }, // url must be absolute /** * Validate a url. * * The `ep.validate.url()` method checks if the givn string an valid url. * * ### Examples * Validate an url. * * JavaScript: * * ep.validate.email( 'http://www.epages.com' ) * * Results: * * true * * Validate an url with error return. * * JavaScript: * * ep.validate.email( 'epages' ); * * Results: * * NO_URL * * * ### Dependencies * * + `ep` * + `ep.color` * + `jQuery.mime` * + `jQuery.i18n` * * @param {String} value A text to validate * @param {Object} [options] A map of additional options pass to the method. * @param {Boolean} options.required A boolean indication wether the value is required. * @param {Integer} options.minlength A minimum number of chars. * @param {Integer} options.maxlength A maximum number of chars. * * @method url * @static * @member ep.validate * * @since 6.11.0 */ url: function( value, options ){ value = $.trim(value); var opt = $.extend({},options||{}), valid = required( value, opt.required ); if( value && valid===true ){ valid = /^((https?|ftp):\/\/)?(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([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])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value) || 'NO_URL'; } return valid===true ? range( value, opt.minlength, opt.maxlength ) : valid; }, /** * Validate a mimetype. * * The `ep.validate.mimetype()` method checks if the givn string an valid mimetype and optional an accepted mimetype. * * ### Examples * Validate a mimetype. * * JavaScript: * * ep.validate.mimetype( 'image/jpeg' ) * * Results: * * true * * Validate a mimetype with error return. * * JavaScript: * * ep.validate.mimetype( 'img' ); * * Results: * * NO_MIME * * Validate an mimetype with accept option. * * JavaScript: * * ep.validate.mimetype( 'image/jpeg', {accept:'text/*'} ); * * Results: * * MIME_NOT_ACCEPT * * * ### Dependencies * * + `ep` * + `ep.color` * + `jQuery.mime` * + `jQuery.i18n` * * @param {String} value A text to validate * @param {Object} [options] A map of additional options pass to the method. * @param {Boolean} options.required A boolean indication wether the value is required. * @param {String} options.accept A list of accepted mimetypes or mimetype groups. * * @method mimetype * @static * @member ep.validate * * @since 6.11.0 */ mimetype: function( value, options ){ value = $.trim(value); var opt = $.extend({ accept: undefined },options||{}), valid = required( value, opt.required ); if( value && valid===true ){ valid = /^[a-z]+\/[a-z\d\.-]+$/i.test(value) || 'NO_MIME'; } if( value && opt.accept && valid===true ){ valid = mime.mime( value, opt.accept ) || 'MIME_NOT_ACCEPT'; } return valid; }, /** * Validate a creditcard number. * * The `ep.validate.creditcard()` method checks if the givn string an valid creditcard number. * * ### Examples * Validate a creditcard number. * * JavaScript: * * ep.validate.creditcard( '4111111111111111' ) * * Results: * * true * * Validate a creditcard with error return. * * JavaScript: * * ep.validate.creditcard( '4112334589700711' ); * * Results: * * NO_CREDITCARD_NUMBER * * * ### Dependencies * * + `ep` * + `ep.color` * + `jQuery.mime` * + `jQuery.i18n` * * @param {String} value A text to validate * @param {Object} [options] A map of additional options pass to the method. * @param {Boolean} options.required A boolean indication wether the value is required. * * @method creditcard * @static * @member ep.validate * * @since 6.11.0 */ creditcard: function( value, options ) { value = $.trim(value); var opt = $.extend({},options||{}), valid = required( value, opt.required ); if( value && valid===true ){ if( /[^0-9-]+/.test(value) ){ return false; } var nCheck = 0, nDigit = 0, bEven = false, cDigit; value = value.replace(/\D/g, ""); for( var n=value.length-1 ; n>=0 ; n-- ){ cDigit = value.charAt(n); nDigit = parseInt(cDigit, 10); if( bEven ){ if( (nDigit *= 2) > 9 ){ nDigit -= 9; } } nCheck += nDigit; bEven = !bEven; } valid = (nCheck % 10) === 0 || 'NO_CREDITCARD_NUMBER'; } return valid; }, /** * Validate a date. * * The `ep.validate.date()` method checks if the givn string an valid date. * * ### Examples * Validate a date. * * JavaScript: * * ep.validate.date( '01.02.2011', {format: 'd', region: 'de'} ); * * Results: * * true * * Validate a date with error return. * * JavaScript: * * ep.validate.date( '01/02/2011', {format: 'd', region: 'de'} ); * * Results: * * NO_DATE * * * ### Dependencies * * + `ep` * + `ep.color` * + `jQuery.mime` * + `jQuery.i18n` * * @param {String} value A text to validate * @param {Object} [options] A map of additional options pass to the method. * @param {Boolean} options.required A boolean indication wether the value is required. * @param {String} options.format A date formatter [look at jQuery.i18n plugin]. * @param {String} options.region An i18n region [look at jQuery.i18n plugin]. * @param {Boolean} options.strict A boolean indication wether to validate in strict mode. * @param {Integer} options.min A local timestamp (not UTC) as minimum valid date. * @param {Integer} options.max A local timestamp (not UTC) as maximum valid date. * * @method date * @static * @member ep.validate * * @since 6.11.0 */ date: function( value, options ){ value = $.trim(value); var opt = $.extend({ format: 'd', strict: false },options||{}), region = {region:opt.region}, valid = required( value, opt.required ); opt.format = i18nMap[opt.format] || opt.format; if( value && valid===true ){ switch(true){ case (/^(d|D)$/).test(opt.format): valid = 'NO_DATE'; break; case (/^(f|F|l|L)$/).test(opt.format): valid = 'NO_DATETIME'; break; case (/^(t|T)$/).test(opt.format): valid = 'NO_TIME'; break; default: valid = invalid; break; } valid = new RegExp( '^' + $.i18n.expStrDate( opt.format, opt.strict, region ) + '$', '' ).test(value) || valid; if( valid===true && value ){ var date = $.i18n.parseDate( value, opt.format, region ); valid = date instanceof Date ? range( date.getTime(), opt.min, opt.max ) : invalid; } } return valid; }, /** * Validate a number. * * The `ep.validate.number()` method checks if the givn string an valid number. * * ### Examples * Validate a number. * * JavaScript: * * ep.validate.date( '12,50', {format: 'n', region: 'de'} ); * * Results: * * true * * Validate a percent number. * * JavaScript: * * ep.validate.date( '12,50 %', {format: 'p2', region: 'de'} ); * * Results: * * true * * Validate a number with error return. * * JavaScript: * * ep.validate.date( '12.50', {format: 'n', region: 'de'} ); * * Results: * * NO_NUMBER * * * ### Dependencies * * + `ep` * + `ep.color` * + `jQuery.mime` * + `jQuery.i18n` * * @param {String} value A text to validate * @param {Object} [options] A map of additional options pass to the method. * @param {Boolean} options.required A boolean indication wether the value is required. * @param {String} options.format A date formatter [look at the jQuery.i18n plugin]. * @param {String} options.region An i18n region [look at the jQuery.i18n plugin]. * @param {Boolean} options.strict A boolean indication wether to validate in strict mode. * @param {Integer} options.min A minimum valid number. * @param {Integer} options.max A maximum valid number. * * @method number * @static * @member ep.validate * * @since 6.11.0 */ number: function( value, options ){ value = $.trim(value); var opt = $.extend({ format: 'n', strict: false },options||{}), region = {region:opt.region,currency:opt.currency}, valid = required( value, opt.required ); opt.format = i18nMap[opt.format] || opt.format; if( value && valid===true ){ var msg = { n:'NO_NUMBER', c:'NO_CURRENCY', p:'NO_PERCENT' }; opt.format.replace(/^(n|c|p)\d*$/,function(str,$1){ valid = msg[$1] || invalid; }); valid = new RegExp( '^' + $.i18n.expStrNumber( opt.format, opt.strict, region ) + '$', '' ).test(value) || valid; } if( value && valid===true ){ var num = $.i18n.parseNumber( value, 10, region ); valid = isNaN(num) ? invalid : range( num, opt.min, opt.max ); } return valid; }, /** * Validate a css color. * * The `ep.validate.cssColor()` method checks if the givn string an css color. * * ### Examples * Validate a css color. * * JavaScript: * * ep.validate.cssColor( '#336699' ); * * ep.validate.cssColor( 'green' ); * * ep.validate.cssColor( 'rgb(100,200,50)' ); * * Results: * * true * * Validate a css color with error return. * * JavaScript: * * ep.validate.cssColor( 'dunkelblau' ); * * Results: * * NO_COLOR_VALUE * * * ### Dependencies * * + `ep` * + `ep.color` * + `jQuery.mime` * + `jQuery.i18n` * * @param {String} value A text to validate * * @method cssColor * @static * @member ep.validate * * @since 6.11.0 */ cssColor: function( value ){ value = $.trim(value); return ep.color.stringToHex(value, true)!==undefined || 'NO_COLOR_VALUE'; }, /** * Validate a css size. * * The `ep.validate.cssSize()` method checks if the givn string an valid css size. * * ### Examples * Validate an css size. * * JavaScript: * * ep.validate.cssSize( '24em' ); * * Results: * * true * * Validate an css size with error return. * * JavaScript: * * ep.validate.cssSize( '24pixel' ); * * Results: * * UNKNOWN_UNIT * * * ### Dependencies * * + `ep` * + `ep.color` * + `jQuery.mime` * + `jQuery.i18n` * * @param {String} value A text to validate * @param {Object} [options] A map of additional options pass to the method. * @param {Boolean} options.required A boolean indication wether the value is required. * @param {Integer} options.min A minimum valid number. * @param {Integer} options.max A maximum valid number. * * @method cssSize * @static * @member ep.validate * * @since 6.11.0 */ cssSize: function( value, options ){ value = $.trim(value); var opt = $.extend({},options||{}), valid = required( value, opt.required ); if( ( value || value==="" ) && valid===true ){ switch(true){ case (/^[0-9]+(px|pt)$/i).test(value) || /^[0-9]*\.?[0-9]+(pc|%|mm|cm|em|in|ex)$/i.test(value) || /^[0]+$/.test(value): valid = true; break; case (/^[0-9]+$/).test(value): valid = 'NO_UNIT'; break; case value === "": valid = 'NO_UNIT_VALUE'; break; case (/^[^0-9]*\.?[^0-9]/).test(value): valid = 'NO_CSS_NUMBER'; break; case (/^[0-9]*\.[0-9]+(?:px|pt)$/i).test(value): valid = 'FLOAT_NOT_ALLOWED'; break; case (/^[0-9]*\.[0-9]$/).test(value): valid = 'NO_UNIT'; break; case (/^[0-9]*\.?[0-9]+[a-z]+$/).test(value): valid = 'UNKNOWN_UNIT'; break; default: valid = invalid; break; } } if( value && valid===true ){ var num = parseFloat(value.replace(/\W+$/,''),10); valid = isNaN(num) ? invalid : range( num, opt.min, opt.max ); } return valid; }, /** * US zipcode validation. * * The `ep.validate.uszip()` method checks if five digits are given and an US address entry is selected (the hidden inputs are set). * */ uszip: function( value, options ){ var opt = $.extend({},options||{}), valid = required( value, opt.required ), i; if( value && valid===true ){ if( !/^[0-9]*$/.test(value) ){ valid = 'NOT_VALID'; } } if( value && valid===true ){ valid = rangelength( value, opt.minlength, opt.maxlength ); } if( value && valid===true ){ if (options.hidden) { for (i = 0; i < options.hidden.length; i++) { if ($(options.hidden[i]).val() === '') { valid = 'NO_ENTRY_SELECTED'; break; } } } } return valid; }, /** * Basic validate method. * * The `ep.validate.basic()` method is a basic method for validation. * * ### Examples * Validate a string. * * JavaScript: * * ep.validate.basic( 'Lorem ipsum ...', { * required: true, * pattern: '^[\w\.]+$', * minlegth: 10, * maxlength: 20 * }); * * Results: * * true * * Validate a string with error return. * * JavaScript: * * ep.validate.basic( 'Lorem ipsum ...', { * required: true, * pattern: '^[\w\.]+$', * minlegth: 10, * maxlength: 15 * }); * * Results: * * NOT_IN_RANGELENGTH * * * ### Dependencies * * + `ep` * + `ep.color` * + `jQuery.mime` * + `jQuery.i18n` * * @param {String} value A text to validate * @param {Object} [options] A map of additional options pass to the method. * @param {Boolean} options.required A boolean indication wether the value is required. * @param {String} options.pattern A pattern string for regular expression. * @param {Integer} options.minlength A minimum number of chars. * @param {Integer} options.maxlength A maximum number of chars. * * @method basic * @static * @member ep.validate * * @since 6.11.0 */ basic: function( value, options ){ var opt = $.extend({},options||{}), valid = required( value, opt.required ); if( value && valid===true ){ valid = pattern( value, opt.pattern); } if( value && valid===true ){ valid = rangelength( value, opt.minlength, opt.maxlength ); } return valid; } /* TODO: validate by server, ajax: function( value, options ){ } */ }); return ep; });