{"version":3,"sources":["expressive.annotations.validate.js"],"names":["$","window","backup","ea","buffer","console","api","settings","debug","optimize","enumsAsNumbers","registerAllMethods","dependencyTriggers","apply","options","target","source","key","hasOwnProperty","typeHelper","isBool","isString","undefined","each","this","find","off","validationHelper","bindFields","logger","info","string","format","addMethod","name","func","toolchain","addValueParser","noConflict","message","log","prep","Date","warn","fail","error","date","tryParse","lines","split","stamp","datetime","fline","shift","length","indent","join","methods","old","arguments","registerMethods","model","essentialMethods","fieldName","i","body","initialize","that","now","setHours","getTime","dateString","parse","year","month","day","setFullYear","hour","minute","second","days","hours","minutes","seconds","str","trim","strA","strB","strC","toLowerCase","CompareOrdinal","prefix","slice","StartsWith","suffix","EndsWith","substr","indexOf","Contains","test","regex","RegExp","guid","msg","values","isArray","Math","min","max","l","sum","parseFloat","arr","Array","Sum","push","parsers","idx","parser","array","contains","item","object","keys","obj","value","parseJSON","ex","text","params","makeParam","replacer","isObject","JSON","stringify","replace","applyParam","param","spaces","toString","bool","number","n","isNumeric","isFinite","timespan","isTimeSpan","match","exec","sign","d","milliseconds","pad","getHours","getMinutes","getSeconds","isDate","millisec","isGuid","toUpperCase","enumeration","isNaN","Object","String","Boolean","prototype","call","type","field","parseFunc","findValueParser","tryAutoParse","modelHelper","getPrefix","lastIndexOf","extractValue","form","rawValue","parsedValue","element","attr","is","filter","val","deserializeObject","fieldsMap","constsMap","enumsMap","parsersMap","buildField","fieldValue","props","parent","arrayIndex","arrayName","arrayPat","endMatch","pop","adjustGivenValue","checked","ctxEval","exp","ctx","Function","referencesMap","collectReferences","fields","refField","validateReferences","referencedFields","validator","validate","not","ignore","valid","force","namespacedEvents","event","bound","hasClass","addClass","on","buildAdapter","adapter","rules","messages","errFieldsMap","re","computeAssertThat","method","methodsList","expression","exprVal","condition","computeRequiredIf","allowEmpty","annotations","unobtrusive","adapters","add","result","trigger","jQuery"],"mappings":"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","file":"../expressive.annotations.validate.min.js","sourcesContent":["/* expressive.annotations.validate.js - v2.7.4\r\n * Client-side component of ExpressiveAnnotations - annotation-based conditional validation library.\r\n * https://github.com/jwaliszko/ExpressiveAnnotations\r\n *\r\n * Copyright (c) 2014 Jarosław Waliszko\r\n * Licensed MIT: http://opensource.org/licenses/MIT */\r\n\r\n(function($, window) {\r\n 'use strict';\r\nvar\r\n backup = window.ea, // map over the ea in case of overwrite\r\n buffer = window.console,\r\n\r\n api = { // to be accessed from outer scope\r\n settings: {\r\n debug: false, // outputs debug messages to the web console (should be disabled in release code not to introduce redundant overhead)\r\n optimize: true, // if flag is on, requirement expression is not needlessly evaluated for non-empty fields (otherwise, it is evaluated\r\n // and such an evaluation result is provided to the eavalid event)\r\n enumsAsNumbers: true, // specifies whether values of enum types are internally treated as integral numerics or string identifiers (should be consistent\r\n // with the way of how input fields values are stored in HTML)\r\n registerAllMethods: false, // specifies whether all of the built-in and custom methods are to be registered within the model context (excluding these\r\n // having naming conflicts with the field identifiers), or the essential ones only (actually used in the expression)\r\n dependencyTriggers: 'change keyup', // a string containing one or more space-separated DOM field event types (such as \"change\", \"keyup\" or custom event\r\n // names) for which fields directly dependent on referenced DOM field are validated - for this feature to be off\r\n // entirely, initialize with empty string, null or undefined (validation will be fired on form submit attempt only)\r\n\r\n apply: function(options) { // alternative way of settings setup (recommended), crucial to invoke e.g. for new set of dependency triggers to be re-bound\r\n function verifySetup() {\r\n if (!typeHelper.isBool(api.settings.debug)) {\r\n throw 'EA settings error: debug value must be a boolean (true or false)';\r\n }\r\n if (!typeHelper.isBool(api.settings.optimize)) {\r\n throw 'EA settings error: optimize value must be a boolean (true or false)';\r\n }\r\n if (!typeHelper.isBool(api.settings.enumsAsNumbers)) {\r\n throw 'EA settings error: enumsAsNumbers value must be a boolean (true or false)';\r\n }\r\n if (!typeHelper.isBool(api.settings.registerAllMethods)) {\r\n throw 'EA settings error: registerAllMethods value must be a boolean (true or false)';\r\n }\r\n if (!typeHelper.isString(api.settings.dependencyTriggers)\r\n && api.settings.dependencyTriggers !== null && api.settings.dependencyTriggers !== undefined) {\r\n throw 'EA settings error: dependencyTriggers value must be a string (multiple event types can be bound at once by including each one separated by a space), null or undefined';\r\n }\r\n }\r\n function extend(target, source) { // custom implementation over jQuery.extend() because null/undefined merge is needed as well\r\n for (var key in source) {\r\n if (source.hasOwnProperty(key)) {\r\n target[key] = source[key];\r\n }\r\n }\r\n }\r\n\r\n extend(api.settings, options);\r\n verifySetup();\r\n\r\n $('form').each(function() {\r\n $(this).find('input, select, textarea').off('.expressive.annotations'); // remove all event handlers in the '.expressive.annotations' namespace\r\n validationHelper.bindFields(this, true);\r\n });\r\n\r\n logger.info(typeHelper.string.format(\"EA settings applied:\\n{0}\", options));\r\n }\r\n },\r\n addMethod: function(name, func) { // provide custom function to be accessible for expression\r\n toolchain.addMethod(name, func); // parameters: name - method name\r\n }, // func - method body\r\n // e.g. if server-side uses following attribute: [AssertThat(\"IsBloodType(BloodType)\")], where IsBloodType() is a custom method available at C# side,\r\n // its client-side equivalent, mainly function of the same signature (name and the number of parameters), must be also provided, i.e.\r\n // ea.addMethod('IsBloodType', function(group) {\r\n // return /^(A|B|AB|0)[\\+-]$/.test(group);\r\n // });\r\n addValueParser: function(name, func) { // provide custom deserialization methods for values of these DOM fields, which are accordingly decorated with ValueParser attribute at the server-side\r\n typeHelper.addValueParser(name, func); // parameters: name - parser name\r\n }, // func - parse logic\r\n // e.g. for objects when stored in non-json format or dates when stored in non-standard format (not proper for Date.parse(dateString)),\r\n // i.e. suppose DOM field date string is given in dd/mm/yyyy format:\r\n // ea.addValueParser('dateparser', function(value, field) { // parameters: value - raw data string extracted by default from DOM element\r\n // // field - DOM element name for which parser was invoked\r\n // var arr = value.split('/'); return new Date(arr[2], arr[1] - 1, arr[0]).getTime(); // return milliseconds since January 1, 1970, 00:00:00 UTC\r\n // });\r\n // multiple parsers can be registered at once when, separated by whitespace, are provided to name parameter, i.e. ea.addValueParser('p1 p2', ...\r\n // finally, if value parser is registered under the name of some type, e.g. datetime, int32, etc., all DOM fields of such a type are going to be deserialized using such a parser\r\n noConflict: function() {\r\n if (window.ea === this) {\r\n window.ea = backup;\r\n }\r\n return this;\r\n }\r\n },\r\n\r\n logger = {\r\n info: function(message) {\r\n if (api.settings.debug && buffer && typeof buffer.log === 'function') { // flush in debug mode only\r\n buffer.log('[info] ' + logger.prep(message, new Date()));\r\n }\r\n },\r\n warn: function(message) {\r\n if (buffer && typeof buffer.warn === 'function') {\r\n buffer.warn('[warn] ' + logger.prep(message, new Date()));\r\n }\r\n },\r\n fail: function(message) {\r\n if (buffer && typeof buffer.error === 'function') {\r\n buffer.error('[fail] ' + logger.prep(message, new Date()));\r\n }\r\n },\r\n prep: function(message, date) {\r\n message = typeHelper.string.tryParse(message);\r\n var lines = message.split('\\n');\r\n var stamp = date !== undefined && date !== null ? '(' + typeHelper.datetime.stamp(date) + '): ' : '';\r\n var fline = stamp + lines.shift();\r\n return lines.length > 0\r\n ? fline + '\\n' + typeHelper.string.indent(lines.join('\\n'), 19)\r\n : fline;\r\n }\r\n },\r\n\r\n toolchain = {\r\n methods: {},\r\n addMethod: function(name, func) { // add multiple function signatures to methods object (methods overloading, based only on numbers of arguments)\r\n var old = this.methods[name];\r\n this.methods[name] = function() {\r\n if (func.length === arguments.length) {\r\n return func.apply(this, arguments);\r\n }\r\n if (typeof old === 'function') {\r\n return old.apply(this, arguments);\r\n }\r\n return func.apply(this, arguments); // no exact signature match, most likely variable number of arguments is accepted\r\n };\r\n },\r\n registerMethods: function(model, essentialMethods, fieldName) {\r\n var i, name, body;\r\n this.initialize();\r\n if (api.settings.registerAllMethods) {\r\n for (name in this.methods) {\r\n if (this.methods.hasOwnProperty(name)) {\r\n if (model.hasOwnProperty(name)) {\r\n logger.warn(typeHelper.string.format('Field {0} - skipping {1}(...) method registration, naming conflict with the field identifier.', fieldName, name));\r\n continue;\r\n }\r\n body = this.methods[name];\r\n model[name] = body;\r\n }\r\n }\r\n return;\r\n }\r\n\r\n for (i = 0; i < essentialMethods.length; i++) {\r\n name = essentialMethods[i];\r\n if (this.methods.hasOwnProperty(name)) { // if not available, exception will be thrown later, during expression evaluation (not thrown here on purpose - too early, let the log to become more complete)\r\n body = this.methods[name];\r\n model[name] = body;\r\n }\r\n }\r\n },\r\n initialize: function() {\r\n var that = this;\r\n this.addMethod('Now', function() { // return milliseconds\r\n return Date.now(); // now() is faster than new Date().getTime()\r\n });\r\n this.addMethod('Today', function() { // return milliseconds\r\n return new Date(new Date().setHours(0, 0, 0, 0)).getTime();\r\n });\r\n this.addMethod('ToDate', function(dateString) { // return milliseconds\r\n return Date.parse(dateString);\r\n });\r\n this.addMethod('Date', function(year, month, day) { // months are 1-based, return milliseconds\r\n return new Date(new Date(year, month - 1, day).setFullYear(year)).getTime();\r\n });\r\n this.addMethod('Date', function(year, month, day, hour, minute, second) { // months are 1-based, return milliseconds\r\n return new Date(new Date(year, month - 1, day, hour, minute, second).setFullYear(year)).getTime();\r\n });\r\n this.addMethod('TimeSpan', function(days, hours, minutes, seconds) { // return milliseconds\r\n return seconds * 1e3 + minutes * 6e4 + hours * 36e5 + days * 864e5;\r\n });\r\n this.addMethod('Length', function(str) {\r\n return str !== null && str !== undefined ? str.length : 0;\r\n });\r\n this.addMethod('Trim', function(str) {\r\n return str !== null && str !== undefined ? $.trim(str) : null;\r\n });\r\n this.addMethod('Concat', function(strA, strB) {\r\n return [strA, strB].join('');\r\n });\r\n this.addMethod('Concat', function(strA, strB, strC) {\r\n return [strA, strB, strC].join('');\r\n });\r\n this.addMethod('CompareOrdinal', function(strA, strB) {\r\n if (strA === strB) {\r\n return 0;\r\n }\r\n if (strA !== null && strB === null) {\r\n return 1;\r\n }\r\n if (strA === null && strB !== null) {\r\n return -1;\r\n }\r\n return strA > strB ? 1 : -1;\r\n });\r\n this.addMethod('CompareOrdinalIgnoreCase', function(strA, strB) {\r\n strA = (strA !== null && strA !== undefined) ? strA.toLowerCase() : null;\r\n strB = (strB !== null && strB !== undefined) ? strB.toLowerCase() : null;\r\n return that.methods.CompareOrdinal(strA, strB);\r\n });\r\n this.addMethod('StartsWith', function(str, prefix) {\r\n return str !== null && str !== undefined && prefix !== null && prefix !== undefined && str.slice(0, prefix.length) === prefix;\r\n });\r\n this.addMethod('StartsWithIgnoreCase', function(str, prefix) {\r\n str = (str !== null && str !== undefined) ? str.toLowerCase() : null;\r\n prefix = (prefix !== null && prefix !== undefined) ? prefix.toLowerCase() : null;\r\n return that.methods.StartsWith(str, prefix);\r\n });\r\n this.addMethod('EndsWith', function(str, suffix) {\r\n return str !== null && str !== undefined && suffix !== null && suffix !== undefined && str.slice(-suffix.length) === suffix;\r\n });\r\n this.addMethod('EndsWithIgnoreCase', function(str, suffix) {\r\n str = (str !== null && str !== undefined) ? str.toLowerCase() : null;\r\n suffix = (suffix !== null && suffix !== undefined) ? suffix.toLowerCase() : null;\r\n return that.methods.EndsWith(str, suffix);\r\n });\r\n this.addMethod('Contains', function(str, substr) {\r\n return str !== null && str !== undefined && substr !== null && substr !== undefined && str.indexOf(substr) > -1;\r\n });\r\n this.addMethod('ContainsIgnoreCase', function(str, substr) {\r\n str = (str !== null && str !== undefined) ? str.toLowerCase() : null;\r\n substr = (substr !== null && substr !== undefined) ? substr.toLowerCase() : null;\r\n return that.methods.Contains(str, substr);\r\n });\r\n this.addMethod('IsNullOrWhiteSpace', function(str) {\r\n return str === null || !/\\S/.test(str);\r\n });\r\n this.addMethod('IsDigitChain', function(str) {\r\n return /^[0-9]+$/.test(str);\r\n });\r\n this.addMethod('IsNumber', function(str) {\r\n return /^[+-]?(?:(?:[0-9]+)|(?:[0-9]+[eE][+-]?[0-9]+)|(?:[0-9]*\\.[0-9]+(?:[eE][+-]?[0-9]+)?))$/.test(str);\r\n });\r\n this.addMethod('IsEmail', function(str) {\r\n // taken from HTML5 specification: http://www.w3.org/TR/html5/forms.html#e-mail-state-(type=email)\r\n return /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(str);\r\n });\r\n this.addMethod('IsPhone', function(str) {\r\n // taken from PhoneAttribute implementation: https://referencesource.microsoft.com/#System.ComponentModel.DataAnnotations/DataAnnotations/PhoneAttribute.cs, adjusted for JavaScript regex engine - since JS doesn't use lookbehind feature, alternative approach used (as described here: http://stackoverflow.com/q/7376238/270315)\r\n return /^(\\+\\s?)?((?!\\+.*)\\(\\+?\\d+([\\s\\-\\.]?\\d+)?\\)|\\d+)([\\s\\-\\.]?(\\(\\d+([\\s\\-\\.]?\\d+)?\\)|\\d+))*(\\s?(x|ext\\.?)\\s?\\d+)?$/.test(str);\r\n });\r\n this.addMethod('IsUrl', function(str) {\r\n // contributed by Diego Perini: https://gist.github.com/dperini/729294 (https://mathiasbynens.be/demo/url-regex)\r\n return /^(?:(?:https?|ftp):\\/\\/)(?:\\S+(?::\\S*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))(?::\\d{2,5})?(?:\\/\\S*)?$/i.test(str);\r\n });\r\n this.addMethod('IsRegexMatch', function(str, regex) {\r\n return str !== null && str !== undefined && regex !== null && regex !== undefined && new RegExp(regex).test(str);\r\n });\r\n this.addMethod('Guid', function(str) {\r\n var guid = typeHelper.guid.tryParse(str);\r\n if (guid.error) {\r\n throw guid.msg;\r\n }\r\n return guid;\r\n });\r\n this.addMethod('Min', function(values) { // accepts both, array and variable number of arguments\r\n if (arguments.length === 0)\r\n throw \"no arguments\";\r\n\r\n if (arguments.length === 1) {\r\n if (typeHelper.isArray(values)) {\r\n if (values.length === 0)\r\n throw \"empty sequence\";\r\n return Math.min.apply(null, values);\r\n }\r\n }\r\n return Math.min.apply(null, arguments);\r\n });\r\n this.addMethod('Max', function(values) { // accepts both, array and variable number of arguments\r\n if (arguments.length === 0)\r\n throw \"no arguments\";\r\n\r\n if (arguments.length === 1) {\r\n if (typeHelper.isArray(values)) {\r\n if (values.length === 0)\r\n throw \"empty sequence\";\r\n return Math.max.apply(null, values);\r\n }\r\n }\r\n return Math.max.apply(null, arguments);\r\n });\r\n this.addMethod('Sum', function(values) { // accepts both, array and variable number of arguments\r\n if (arguments.length === 0)\r\n throw \"no arguments\";\r\n\r\n var sum = 0, i, l;\r\n if (arguments.length === 1) {\r\n if (typeHelper.isArray(values)) {\r\n if (values.length === 0)\r\n throw \"empty sequence\";\r\n for (i = 0, l = values.length; i < l; i++) {\r\n sum += parseFloat(values[i]);\r\n }\r\n return sum;\r\n }\r\n }\r\n for (i = 0, l = arguments.length; i < l; i++) {\r\n sum += parseFloat(arguments[i]);\r\n }\r\n return sum;\r\n });\r\n this.addMethod('Average', function(values) { // accepts both, array and variable number of arguments\r\n if (arguments.length === 0)\r\n throw \"no arguments\";\r\n\r\n var sum, i, l, arr = new Array();\r\n if (arguments.length === 1) {\r\n if (typeHelper.isArray(values)) {\r\n if (values.length === 0)\r\n throw \"empty sequence\";\r\n sum = that.methods.Sum(values);\r\n return sum / values.length;\r\n }\r\n }\r\n for (i = 0, l = arguments.length; i < l; i++) {\r\n arr.push(arguments[i]);\r\n }\r\n sum = that.methods.Sum(arr);\r\n return sum / arguments.length;\r\n });\r\n }\r\n },\r\n\r\n typeHelper = {\r\n parsers: {},\r\n addValueParser: function(name, func) {\r\n $.each(name.split(/\\s+/), function(idx, parser) {\r\n if (/\\S/.test(parser)) {\r\n typeHelper.parsers[parser] = func;\r\n }\r\n });\r\n },\r\n array: {\r\n contains: function(arr, item) {\r\n var i = arr.length;\r\n while (i--) {\r\n if (arr[i] === item) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n },\r\n object: {\r\n keys: function(obj) {\r\n var key, arr = [];\r\n for (key in obj) {\r\n if (obj.hasOwnProperty(key)) {\r\n arr.push(key);\r\n }\r\n }\r\n return arr;\r\n },\r\n tryParse: function(value) {\r\n try {\r\n return $.parseJSON(value);\r\n } catch (ex) {\r\n return { error: true, msg: 'Given value was not recognized as a valid JSON. ' + ex };\r\n }\r\n }\r\n },\r\n string: {\r\n format: function(text, params) {\r\n function makeParam(value) {\r\n var replacer = function(key, value) {\r\n return typeof value === 'function' ? 'function(...) {...}' : value;\r\n }\r\n if (api.settings.registerAllMethods) {\r\n replacer = null; // do not print all of the methods not to disturb the console output\r\n }\r\n value = typeHelper.isObject(value) ? JSON.stringify(value, replacer, 4): value;\r\n value = typeHelper.isString(value) ? value.replace(/\\$/g, '$$$$'): value; // escape $ sign for string.replace()\r\n return value;\r\n }\r\n function applyParam(text, param, idx) {\r\n return text.replace(new RegExp('\\\\{' + idx + '\\\\}', 'gm'), param);\r\n }\r\n\r\n var i;\r\n if (params instanceof Array) {\r\n for (i = 0; i < params.length; i++) {\r\n text = applyParam(text, makeParam(params[i]), i);\r\n }\r\n return text;\r\n }\r\n for (i = 0; i < arguments.length - 1; i++) {\r\n text = applyParam(text, makeParam(arguments[i + 1]), i);\r\n }\r\n return text;\r\n },\r\n indent: function(str, spaces) {\r\n var indent = Array((spaces || 0) + 1).join(' ');\r\n return str.replace(/^/gm, indent);\r\n },\r\n tryParse: function(value) {\r\n if (typeHelper.isString(value)) {\r\n return value;\r\n }\r\n if (value !== undefined && value !== null) {\r\n return value.toString();\r\n }\r\n return { error: true, msg: 'Given value was not recognized as a valid string.' };\r\n }\r\n },\r\n bool: {\r\n tryParse: function(value) {\r\n if (typeHelper.isBool(value)) {\r\n return value;\r\n }\r\n if (typeHelper.isString(value)) {\r\n value = $.trim(value).toLowerCase();\r\n if (value === 'true' || value === 'false') {\r\n return value === 'true';\r\n }\r\n }\r\n return { error: true, msg: 'Given value was not recognized as a valid boolean.' };\r\n }\r\n },\r\n number: {\r\n tryParse: function(value) {\r\n function isNumber(n) {\r\n return typeHelper.isNumeric(parseFloat(n)) && isFinite(n);\r\n }\r\n\r\n if (isNumber(value)) {\r\n return parseFloat(value);\r\n }\r\n return { error: true, msg: 'Given value was not recognized as a valid number.' };\r\n }\r\n },\r\n timespan: {\r\n tryParse: function(value) {\r\n if (typeHelper.isTimeSpan(value)) {\r\n var DAY = 2, HOUR = 3, MINUTE = 4, SECOND = 5, MILLISECOND = 6;\r\n var match = /(\\-)?(?:(\\d*)\\.)?(\\d+)\\:(\\d+)(?:\\:(\\d+)\\.?(\\d{3})?)?/.exec(value);\r\n var sign = (match[1] === '-') ? -1 : 1;\r\n var d = {\r\n days: typeHelper.number.tryParse(match[DAY] || 0) * sign,\r\n hours: typeHelper.number.tryParse(match[HOUR] || 0) * sign,\r\n minutes: typeHelper.number.tryParse(match[MINUTE] || 0) * sign,\r\n seconds: typeHelper.number.tryParse(match[SECOND] || 0) * sign,\r\n milliseconds: typeHelper.number.tryParse(match[MILLISECOND] || 0) * sign\r\n };\r\n var millisec = d.milliseconds +\r\n d.seconds * 1e3 + // 1000\r\n d.minutes * 6e4 + // 1000 * 60\r\n d.hours * 36e5 + // 1000 * 60 * 60\r\n d.days * 864e5; // 1000 * 60 * 60 * 24\r\n return millisec;\r\n }\r\n return { error: true, msg: 'Given value was not recognized as a valid .NET style timespan string.' };\r\n }\r\n },\r\n datetime: {\r\n stamp: function(date) {\r\n function pad(n) { return ('0' + n).slice(-2); }\r\n return pad(date.getHours()) + ':' + pad(date.getMinutes()) + ':' + pad(date.getSeconds());\r\n },\r\n tryParse: function(value) {\r\n if (typeHelper.isDate(value)) {\r\n return value.getTime(); // return the time value in milliseconds\r\n }\r\n if (typeHelper.isString(value)) {\r\n var millisec = Date.parse(value); // default parsing of string representing an RFC 2822 or ISO 8601 date\r\n if (typeHelper.isNumeric(millisec)) {\r\n return millisec;\r\n }\r\n }\r\n return { error: true, msg: 'Given value was not recognized as a valid RFC 2822 or ISO 8601 date.' };\r\n }\r\n },\r\n guid: {\r\n tryParse: function(value) {\r\n if (typeHelper.isGuid(value)) {\r\n return value.toUpperCase();\r\n }\r\n return { error: true, msg: 'Given value was not recognized as a valid guid - guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).' };\r\n }\r\n },\r\n enumeration: {\r\n tryParse: function(value) {\r\n return api.settings.enumsAsNumbers ? typeHelper.number.tryParse(value) : typeHelper.string.tryParse(value);\r\n }\r\n },\r\n isTimeSpan: function(value) {\r\n return /(\\-)?(?:(\\d*)\\.)?(\\d+)\\:(\\d+)(?:\\:(\\d+)\\.?(\\d{3})?)?/.test(value); // regex for recognition of .NET style timespan string, taken from moment.js v2.9.0\r\n },\r\n isNumeric: function(value) {\r\n return typeof value === 'number' && !isNaN(value);\r\n },\r\n isDate: function(value) {\r\n return value instanceof Date;\r\n },\r\n isObject: function(value) {\r\n return typeof value === 'object' || value instanceof Object;\r\n },\r\n isString: function(value) {\r\n return typeof value === 'string' || value instanceof String;\r\n },\r\n isBool: function(value) {\r\n return typeof value === 'boolean' || value instanceof Boolean;\r\n },\r\n isGuid: function(value) {\r\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value); // basic check\r\n },\r\n isArray: function(value) {\r\n return Object.prototype.toString.call(value) === '[object Array]';\r\n },\r\n tryParse: function(value, type, field, parser) {\r\n var parseFunc;\r\n if (parser !== null && parser !== undefined) {\r\n parseFunc = typeHelper.findValueParser(field, parser); // pointed by attribute custom field-specific parser lookup - highest parsing priority\r\n if (!parseFunc.error) {\r\n return parseFunc(value, field);\r\n }\r\n logger.warn(parseFunc.msg);\r\n }\r\n parseFunc = typeHelper.findValueParser(field, type); // custom type-specific parser lookup - secondary parsing priority\r\n if (!parseFunc.error) {\r\n logger.warn(typeHelper.string.format('Overridden {0} type parsing runs for {1} field. All fields of {0} type are going to be parsed using your value parser. If such a behavior is unintentional, change the name of your value parser to one, which does not indicate at {0} (or any other) type name.', type, field));\r\n return parseFunc(value, field);\r\n }\r\n return typeHelper.tryAutoParse(value, type); // built-in parser lookup - lowest parsing priority\r\n },\r\n tryAutoParse: function(value, type) {\r\n return typeHelper.hasOwnProperty(type)\r\n ? typeHelper[type].tryParse(value)\r\n : typeHelper.object.tryParse(value);\r\n },\r\n findValueParser: function(field, parser) {\r\n var parseFunc = typeHelper.parsers[parser]; // custom parsing lookup\r\n if (typeof parseFunc === 'function') {\r\n return parseFunc;\r\n }\r\n return { error: true, msg: typeHelper.string.format('Custom value parser {0} not found. Consider its registration with ea.addValueParser(), or remove redundant ValueParser attribute from {1} model field.', parser, field) };\r\n }\r\n },\r\n\r\n modelHelper = {\r\n getPrefix: function(str) {\r\n return (str !== undefined && str !== null) ? str.substr(0, str.lastIndexOf('.') + 1) : '';\r\n },\r\n extractValue: function(form, name, prefix, type, parser) {\r\n function getValue(element) {\r\n var elementType = element.attr('type');\r\n switch (elementType) {\r\n case 'checkbox':\r\n if (element.length > 2) {\r\n logger.warn(typeHelper.string.format('DOM field {0} is ambiguous (unless custom value parser is provided).', element.attr('name')));\r\n }\r\n return element.is(':checked');\r\n case 'radio':\r\n return element.filter(':checked').val();\r\n default:\r\n if (element.length > 1) {\r\n logger.warn(typeHelper.string.format('DOM field {0} is ambiguous (unless custom value parser is provided).', element.attr('name')));\r\n }\r\n return element.val();\r\n }\r\n }\r\n\r\n var field, fieldName, rawValue, parsedValue;\r\n fieldName = prefix + name;\r\n field = $(form).find(typeHelper.string.format(':input[name=\"{0}\"]', fieldName));\r\n if (field.length === 0) {\r\n throw typeHelper.string.format('DOM field {0} not found.', fieldName);\r\n }\r\n rawValue = getValue(field);\r\n if (rawValue === null || rawValue === undefined || rawValue === '') { // field value not set\r\n return null;\r\n }\r\n parsedValue = typeHelper.tryParse(rawValue, type, fieldName, parser); // convert field value to required type\r\n if (parsedValue !== null && parsedValue !== undefined && parsedValue.error) {\r\n throw typeHelper.string.format('DOM field {0} value conversion to {1} failed. {2}', fieldName, type, parsedValue.msg);\r\n }\r\n return parsedValue;\r\n },\r\n deserializeObject: function(form, fieldsMap, constsMap, enumsMap, parsersMap, prefix) {\r\n function buildField(fieldName, fieldValue, object) {\r\n var props, parent, i, match, arrayIndex, arrayName, arrayPat;\r\n arrayPat = /^([a-z_0-9]+)\\[([0-9]+)\\]$/i;\r\n props = fieldName.split('.');\r\n parent = object;\r\n for (i = 0; i < props.length - 1; i++) {\r\n fieldName = props[i];\r\n\r\n match = arrayPat.exec(fieldName); // check for array element access\r\n if (match) {\r\n fieldName = match[1];\r\n arrayIndex = match[2];\r\n if (!parent.hasOwnProperty(fieldName)) {\r\n parent[fieldName] = {};\r\n }\r\n parent[fieldName][arrayIndex] = parent[fieldName][arrayIndex] || {}; // create if needed\r\n parent = parent[fieldName][arrayIndex];\r\n continue;\r\n }\r\n\r\n if (!parent.hasOwnProperty(fieldName)) {\r\n parent[fieldName] = {};\r\n }\r\n parent = parent[fieldName];\r\n }\r\n fieldName = props[props.length - 1];\r\n\r\n var endMatch = arrayPat.exec(fieldName);\r\n if (endMatch) { // our fieldName matches array access pattern i.e. arr[idx]\r\n arrayName = endMatch[1];\r\n arrayIndex = endMatch[2];\r\n parent[arrayName] = parent[arrayName] || []; // create if needed\r\n parent[arrayName][arrayIndex] = fieldValue;\r\n } else {\r\n parent[fieldName] = fieldValue;\r\n }\r\n }\r\n\r\n var model = {}, name, type, value, parser;\r\n for (name in fieldsMap) {\r\n if (fieldsMap.hasOwnProperty(name)) {\r\n type = fieldsMap[name];\r\n parser = parsersMap[name];\r\n value = this.extractValue(form, name, prefix, type, parser);\r\n buildField(name, value, model);\r\n }\r\n }\r\n for (name in constsMap) {\r\n if (constsMap.hasOwnProperty(name)) {\r\n value = constsMap[name];\r\n buildField(name, value, model);\r\n }\r\n }\r\n for (name in enumsMap) {\r\n if (enumsMap.hasOwnProperty(name)) {\r\n value = api.settings.enumsAsNumbers ? enumsMap[name] : name.split('.').pop();\r\n buildField(name, value, model);\r\n }\r\n }\r\n return model;\r\n },\r\n adjustGivenValue: function(value, element, params) {\r\n value = element.type === 'checkbox' ? element.checked : value; // special treatment for checkbox, because when unchecked, false value should be retrieved instead of undefined\r\n\r\n var field = element.name.replace(params.prefix, '');\r\n var parser = params.parsersMap[field];\r\n if (parser !== null && parser !== undefined) {\r\n var parseFunc = typeHelper.findValueParser(element.name, parser); // pointed by attribute custom field-specific parser lookup - highest parsing priority\r\n if (!parseFunc.error) {\r\n return parseFunc(value, element.name);\r\n }\r\n logger.warn(parseFunc.msg);\r\n }\r\n return value;\r\n },\r\n ctxEval: function(exp, ctx) { // evaluates expression in the scope of context object\r\n return (new Function('expression', 'context', 'with(context){return eval(expression)}'))(exp, ctx); // function constructor used on purpose (a hack), for 'with' statement not to collide with strict mode, which\r\n // is applied to entire module scope (BTW 'use strict'; pragma intentionally not put to function constructor)\r\n }\r\n },\r\n\r\n validationHelper = {\r\n referencesMap: [],\r\n collectReferences: function(fields, refField, prefix) {\r\n var i, name;\r\n for (i = 0; i < fields.length; i++) {\r\n name = prefix + fields[i];\r\n if (name !== refField) {\r\n this.referencesMap[name] = this.referencesMap[name] || [];\r\n if (!typeHelper.array.contains(this.referencesMap[name], refField)) {\r\n this.referencesMap[name].push(refField);\r\n }\r\n }\r\n }\r\n },\r\n validateReferences: function(name, form) {\r\n var i, field, referencedFields, validator;\r\n validator = $(form).validate(); // get validator attached to the form\r\n referencedFields = this.referencesMap[name];\r\n if (referencedFields !== undefined && referencedFields !== null) {\r\n logger.info(typeHelper.string.format('Validation triggered for the following dependencies of {0} field:\\n{1}.', name, referencedFields.join(', ')));\r\n i = referencedFields.length;\r\n while (i--) {\r\n field = $(form).find(typeHelper.string.format(':input[data-val][name=\"{0}\"]', referencedFields[i])).not(validator.settings.ignore);\r\n if (field.length !== 0) {\r\n field.valid();\r\n }\r\n }\r\n } else {\r\n logger.info(typeHelper.string.format('No fields dependent on {0} detected.', name));\r\n }\r\n },\r\n bindFields: function(form, force) { // attach validation handlers to dependency triggers (events) for some form elements\r\n if (api.settings.dependencyTriggers !== null && api.settings.dependencyTriggers !== undefined && api.settings.dependencyTriggers !== '') {\r\n var namespacedEvents = [];\r\n $.each(api.settings.dependencyTriggers.split(/\\s+/), function(idx, event) {\r\n if (/\\S/.test(event)) {\r\n namespacedEvents.push(typeHelper.string.format('{0}.expressive.annotations', event));\r\n }\r\n });\r\n // attach handlers to all inputs that do not have 'ea-triggers-bound' class (unless force is true)\r\n $(form).find('input, select, textarea').not(function(idx, element) {\r\n var bound = $(element).hasClass('ea-triggers-bound');\r\n $(element).addClass('ea-triggers-bound');\r\n return !force && bound;\r\n }).on(namespacedEvents.join(' '), function(event) {\r\n var field = $(this).attr('name');\r\n logger.info(typeHelper.string.format('Dependency validation trigger - {0} event, handled.', event.type));\r\n validationHelper.validateReferences(field, form); // validate referenced fields only\r\n });\r\n }\r\n }\r\n },\r\n\r\n buildAdapter = function(adapter, options) {\r\n var rules = {\r\n prefix: modelHelper.getPrefix(options.element.name),\r\n form: options.form\r\n };\r\n for (var key in options.params) {\r\n if (options.params.hasOwnProperty(key)) {\r\n rules[key] = options.params[key] !== undefined ? $.parseJSON(options.params[key]) : {};\r\n }\r\n }\r\n if (options.message) {\r\n options.messages[adapter] = function(params, element) {\r\n var message, field, guid, value;\r\n message = options.message;\r\n for (field in params.errFieldsMap) {\r\n if (params.errFieldsMap.hasOwnProperty(field)) {\r\n guid = params.errFieldsMap[field];\r\n value = modelHelper.extractValue(params.form, field, params.prefix, 'string', null);\r\n\r\n var re = new RegExp(guid, 'g'); // with this regex...\r\n message = message.replace(re, value); // ...occurrences are replaced globally\r\n }\r\n }\r\n return message;\r\n };\r\n }\r\n validationHelper.bindFields(options.form);\r\n validationHelper.collectReferences(typeHelper.object.keys(rules.fieldsMap), options.element.name, rules.prefix);\r\n options.rules[adapter] = rules;\r\n },\r\n\r\n computeAssertThat = function(method, value, element, params) {\r\n value = modelHelper.adjustGivenValue(value, element, params); // preprocess given value (here basically we are concerned about determining if such a value is null or not, to determine if the attribute\r\n // logic should be invoked or not - full type-detection parsing is not required at this stage, but we may have to extract such a value using\r\n // value parser, e.g. for an array which values are distracted among multiple fields)\r\n if (value !== undefined && value !== null && value !== '') { // check if the field value is set (continue if so, otherwise skip condition verification)\r\n var model = modelHelper.deserializeObject(params.form, params.fieldsMap, params.constsMap, params.enumsMap, params.parsersMap, params.prefix);\r\n toolchain.registerMethods(model, params.methodsList, element.name);\r\n var message = 'Field {0} - {1} expression:\\n[{2}]\\nto be executed within the following context{3}:\\n{4}';\r\n logger.info(typeHelper.string.format(message, element.name, method, params.expression, api.settings.registerAllMethods ? ' (methods not shown)' : '', model));\r\n var exprVal = modelHelper.ctxEval(params.expression, model); // verify assertion, if not satisfied => notify (return false)\r\n return {\r\n valid: exprVal,\r\n condition: exprVal\r\n }\r\n }\r\n return {\r\n valid: true,\r\n condition: undefined // undefined always when value is set (computation redundant)\r\n }\r\n },\r\n\r\n computeRequiredIf = function(method, value, element, params) {\r\n value = modelHelper.adjustGivenValue(value, element, params);\r\n\r\n var exprVal = undefined, model;\r\n var message = 'Field {0} - {1} expression:\\n[{2}]\\nto be executed within the following context{3}:\\n{4}';\r\n if (!api.settings.optimize) { // no optimization - compute requirement condition (which now may have changed) despite the fact field value may be provided\r\n model = modelHelper.deserializeObject(params.form, params.fieldsMap, params.constsMap, params.enumsMap, params.parsersMap, params.prefix);\r\n toolchain.registerMethods(model, params.methodsList, element.name);\r\n logger.info(typeHelper.string.format(message, element.name, method, params.expression, api.settings.registerAllMethods ? ' (methods not shown)' : '', model));\r\n exprVal = modelHelper.ctxEval(params.expression, model);\r\n }\r\n\r\n if (value === undefined || value === null || value === '' // check if the field value is not set (undefined, null or empty string treated at client as null at server)\r\n || (!/\\S/.test(value) && !params.allowEmpty)) {\r\n\r\n if (exprVal !== undefined) {\r\n return {\r\n valid: !exprVal,\r\n condition: exprVal\r\n }\r\n }\r\n\r\n model = modelHelper.deserializeObject(params.form, params.fieldsMap, params.constsMap, params.enumsMap, params.parsersMap, params.prefix);\r\n toolchain.registerMethods(model, params.methodsList, element.name);\r\n logger.info(typeHelper.string.format(message, element.name, method, params.expression, api.settings.registerAllMethods ? ' (methods not shown)' : '', model));\r\n exprVal = modelHelper.ctxEval(params.expression, model); // verify requirement, if satisfied => notify (return false)\r\n return {\r\n valid: !exprVal,\r\n condition: exprVal\r\n }\r\n }\r\n return {\r\n valid: true,\r\n condition: exprVal // undefined when optimize flag is on and value is not set (computation redundant)\r\n }\r\n },\r\n\r\n annotations = ' abcdefghijklmnopqrstuvwxyz'; // suffixes for attributes annotating single field multiple times\r\n\r\n // bind requirements first...\r\n $.each(annotations.split(''), function() { // it would be ideal to have exactly as many handlers as there are unique annotations, but the number of annotations isn't known untill DOM is ready\r\n var adapter = typeHelper.string.format('requiredif{0}', $.trim(this));\r\n $.validator.unobtrusive.adapters.add(adapter, ['expression', 'fieldsMap', 'constsMap', 'enumsMap', 'methodsList', 'parsersMap', 'errFieldsMap', 'allowEmpty'], function(options) {\r\n buildAdapter(adapter, options);\r\n });\r\n });\r\n\r\n // ...then move to asserts\r\n $.each(annotations.split(''), function() {\r\n var adapter = typeHelper.string.format('assertthat{0}', $.trim(this));\r\n $.validator.unobtrusive.adapters.add(adapter, ['expression', 'fieldsMap', 'constsMap', 'enumsMap', 'methodsList', 'parsersMap', 'errFieldsMap'], function(options) {\r\n buildAdapter(adapter, options);\r\n });\r\n });\r\n\r\n $.each(annotations.split(''), function() {\r\n var suffix = $.trim(this);\r\n var method = typeHelper.string.format('assertthat{0}', suffix);\r\n $.validator.addMethod(method, function(value, element, params) {\r\n try {\r\n var result = computeAssertThat(method, value, element, params);\r\n\r\n logger.info(typeHelper.string.format('Field {0} - {1} outcome: {2}, assertion {3}.',\r\n element.name,\r\n method,\r\n result.condition === undefined\r\n ? 'assertion expression computation redundant'\r\n : result.condition\r\n ? 'expression true'\r\n : 'expression false',\r\n result.valid ? 'satisfied' : 'not satisfied'));\r\n\r\n $(element).trigger('eavalid', ['assertthat', result.valid, params.expression]);\r\n return result.valid;\r\n } catch (ex) {\r\n logger.fail(ex);\r\n }\r\n }, '');\r\n });\r\n\r\n $.each(annotations.split(''), function() {\r\n var suffix = $.trim(this);\r\n var method = typeHelper.string.format('requiredif{0}', suffix);\r\n $.validator.addMethod(method, function(value, element, params) {\r\n try {\r\n var result = computeRequiredIf(method, value, element, params);\r\n\r\n logger.info(typeHelper.string.format('Field {0} - {1} outcome: {2}, requirement {3}.',\r\n element.name,\r\n method,\r\n result.condition === undefined\r\n ? 'requirement expression computation redundant'\r\n : result.condition\r\n ? 'required'\r\n : 'not required',\r\n result.valid ? 'satisfied' : 'not satisfied'));\r\n\r\n $(element).trigger('eavalid', ['requiredif', result.valid, params.expression, result.condition, annotations.indexOf(suffix)]);\r\n return result.valid;\r\n } catch (ex) {\r\n logger.fail(ex);\r\n }\r\n }, '');\r\n });\r\n\r\n window.ea = api; // expose some tiny api to the ea global object\r\n\r\n}(jQuery, window));\r\n"]}