2016-04-24 14:26:11 +00:00
/ * !
* Parsley . js
2016-05-04 15:40:49 +00:00
* Version 2.3 . 11 - built Fri , Apr 15 th 2016 , 9 : 21 am
2016-04-24 14:26:11 +00:00
* http : //parsleyjs.org
* Guillaume Potier - < guillaume @ wisembly . com >
* Marc - Andre Lafortune - < petroselinum @ marc - andre . ca >
* MIT Licensed
* /
// The source code below is generated by babel as
// Parsley is written in ECMAScript 6
//
var _slice = Array . prototype . slice ;
function _toConsumableArray ( arr ) { if ( Array . isArray ( arr ) ) { for ( var i = 0 , arr2 = Array ( arr . length ) ; i < arr . length ; i ++ ) arr2 [ i ] = arr [ i ] ; return arr2 ; } else { return Array . from ( arr ) ; } }
( function ( global , factory ) {
typeof exports === 'object' && typeof module !== 'undefined' ? module . exports = factory ( require ( 'jquery' ) ) : typeof define === 'function' && define . amd ? define ( [ 'jquery' ] , factory ) : global . parsley = factory ( global . jQuery ) ;
} ) ( this , function ( $ ) {
'use strict' ;
var globalID = 1 ;
var pastWarnings = { } ;
var ParsleyUtils _ _ParsleyUtils = {
// Parsley DOM-API
// returns object from dom attributes and values
attr : function attr ( $element , namespace , obj ) {
var i ;
var attribute ;
var attributes ;
var regex = new RegExp ( '^' + namespace , 'i' ) ;
if ( 'undefined' === typeof obj ) obj = { } ; else {
// Clear all own properties. This won't affect prototype's values
for ( i in obj ) {
if ( obj . hasOwnProperty ( i ) ) delete obj [ i ] ;
}
}
if ( 'undefined' === typeof $element || 'undefined' === typeof $element [ 0 ] ) return obj ;
attributes = $element [ 0 ] . attributes ;
for ( i = attributes . length ; i -- ; ) {
attribute = attributes [ i ] ;
if ( attribute && attribute . specified && regex . test ( attribute . name ) ) {
obj [ this . camelize ( attribute . name . slice ( namespace . length ) ) ] = this . deserializeValue ( attribute . value ) ;
}
}
return obj ;
} ,
checkAttr : function checkAttr ( $element , namespace , _checkAttr ) {
return $element . is ( '[' + namespace + _checkAttr + ']' ) ;
} ,
setAttr : function setAttr ( $element , namespace , attr , value ) {
$element [ 0 ] . setAttribute ( this . dasherize ( namespace + attr ) , String ( value ) ) ;
} ,
generateID : function generateID ( ) {
return '' + globalID ++ ;
} ,
/** Third party functions **/
// Zepto deserialize function
deserializeValue : function deserializeValue ( value ) {
var num ;
try {
return value ? value == "true" || ( value == "false" ? false : value == "null" ? null : ! isNaN ( num = Number ( value ) ) ? num : /^[\[\{]/ . test ( value ) ? $ . parseJSON ( value ) : value ) : value ;
} catch ( e ) {
return value ;
}
} ,
// Zepto camelize function
camelize : function camelize ( str ) {
return str . replace ( /-+(.)?/g , function ( match , chr ) {
return chr ? chr . toUpperCase ( ) : '' ;
} ) ;
} ,
// Zepto dasherize function
dasherize : function dasherize ( str ) {
return str . replace ( /::/g , '/' ) . replace ( /([A-Z]+)([A-Z][a-z])/g , '$1_$2' ) . replace ( /([a-z\d])([A-Z])/g , '$1_$2' ) . replace ( /_/g , '-' ) . toLowerCase ( ) ;
} ,
warn : function warn ( ) {
var _window$console ;
if ( window . console && 'function' === typeof window . console . warn ) ( _window$console = window . console ) . warn . apply ( _window$console , arguments ) ;
} ,
warnOnce : function warnOnce ( msg ) {
if ( ! pastWarnings [ msg ] ) {
pastWarnings [ msg ] = true ;
this . warn . apply ( this , arguments ) ;
}
} ,
_resetWarnings : function _resetWarnings ( ) {
pastWarnings = { } ;
} ,
trimString : function trimString ( string ) {
return string . replace ( /^\s+|\s+$/g , '' ) ;
} ,
namespaceEvents : function namespaceEvents ( events , namespace ) {
events = this . trimString ( events || '' ) . split ( /\s+/ ) ;
if ( ! events [ 0 ] ) return '' ;
return $ . map ( events , function ( evt ) {
return evt + '.' + namespace ;
} ) . join ( ' ' ) ;
} ,
// Object.create polyfill, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill
objectCreate : Object . create || ( function ( ) {
var Object = function Object ( ) { } ;
return function ( prototype ) {
if ( arguments . length > 1 ) {
throw Error ( 'Second argument not supported' ) ;
}
if ( typeof prototype != 'object' ) {
throw TypeError ( 'Argument must be an object' ) ;
}
Object . prototype = prototype ;
var result = new Object ( ) ;
Object . prototype = null ;
return result ;
} ;
} ) ( )
} ;
var ParsleyUtils _ _default = ParsleyUtils _ _ParsleyUtils ;
// All these options could be overriden and specified directly in DOM using
// `data-parsley-` default DOM-API
// eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"`
// eg: `data-parsley-stop-on-first-failing-constraint="false"`
var ParsleyDefaults = {
// ### General
// Default data-namespace for DOM API
namespace : 'data-parsley-' ,
// Supported inputs by default
inputs : 'input, textarea, select' ,
// Excluded inputs by default
excluded : 'input[type=button], input[type=submit], input[type=reset], input[type=hidden]' ,
// Stop validating field on highest priority failing constraint
priorityEnabled : true ,
// ### Field only
// identifier used to group together inputs (e.g. radio buttons...)
multiple : null ,
// identifier (or array of identifiers) used to validate only a select group of inputs
group : null ,
// ### UI
// Enable\Disable error messages
uiEnabled : true ,
// Key events threshold before validation
validationThreshold : 3 ,
// Focused field on form validation error. 'first'|'last'|'none'
focus : 'first' ,
// event(s) that will trigger validation before first failure. eg: `input`...
trigger : false ,
// event(s) that will trigger validation after first failure.
triggerAfterFailure : 'input' ,
// Class that would be added on every failing validation Parsley field
errorClass : 'parsley-error' ,
// Same for success validation
successClass : 'parsley-success' ,
// Return the `$element` that will receive these above success or error classes
// Could also be (and given directly from DOM) a valid selector like `'#div'`
classHandler : function classHandler ( ParsleyField ) { } ,
// Return the `$element` where errors will be appended
// Could also be (and given directly from DOM) a valid selector like `'#div'`
errorsContainer : function errorsContainer ( ParsleyField ) { } ,
// ul elem that would receive errors' list
errorsWrapper : '<ul class="parsley-errors-list"></ul>' ,
// li elem that would receive error message
errorTemplate : '<li></li>'
} ;
var ParsleyAbstract = function ParsleyAbstract ( ) {
this . _ _id _ _ = ParsleyUtils _ _default . generateID ( ) ;
} ;
ParsleyAbstract . prototype = {
asyncSupport : true , // Deprecated
_pipeAccordingToValidationResult : function _pipeAccordingToValidationResult ( ) {
var _this = this ;
var pipe = function pipe ( ) {
var r = $ . Deferred ( ) ;
if ( true !== _this . validationResult ) r . reject ( ) ;
return r . resolve ( ) . promise ( ) ;
} ;
return [ pipe , pipe ] ;
} ,
actualizeOptions : function actualizeOptions ( ) {
ParsleyUtils _ _default . attr ( this . $element , this . options . namespace , this . domOptions ) ;
if ( this . parent && this . parent . actualizeOptions ) this . parent . actualizeOptions ( ) ;
return this ;
} ,
_resetOptions : function _resetOptions ( initOptions ) {
this . domOptions = ParsleyUtils _ _default . objectCreate ( this . parent . options ) ;
this . options = ParsleyUtils _ _default . objectCreate ( this . domOptions ) ;
// Shallow copy of ownProperties of initOptions:
for ( var i in initOptions ) {
if ( initOptions . hasOwnProperty ( i ) ) this . options [ i ] = initOptions [ i ] ;
}
this . actualizeOptions ( ) ;
} ,
_listeners : null ,
// Register a callback for the given event name
// Callback is called with context as the first argument and the `this`
// The context is the current parsley instance, or window.Parsley if global
// A return value of `false` will interrupt the calls
on : function on ( name , fn ) {
this . _listeners = this . _listeners || { } ;
var queue = this . _listeners [ name ] = this . _listeners [ name ] || [ ] ;
queue . push ( fn ) ;
return this ;
} ,
// Deprecated. Use `on` instead
subscribe : function subscribe ( name , fn ) {
$ . listenTo ( this , name . toLowerCase ( ) , fn ) ;
} ,
// Unregister a callback (or all if none is given) for the given event name
off : function off ( name , fn ) {
var queue = this . _listeners && this . _listeners [ name ] ;
if ( queue ) {
if ( ! fn ) {
delete this . _listeners [ name ] ;
} else {
for ( var i = queue . length ; i -- ; ) if ( queue [ i ] === fn ) queue . splice ( i , 1 ) ;
}
}
return this ;
} ,
// Deprecated. Use `off`
unsubscribe : function unsubscribe ( name , fn ) {
$ . unsubscribeTo ( this , name . toLowerCase ( ) ) ;
} ,
// Trigger an event of the given name
// A return value of `false` interrupts the callback chain
// Returns false if execution was interrupted
trigger : function trigger ( name , target , extraArg ) {
target = target || this ;
var queue = this . _listeners && this . _listeners [ name ] ;
var result ;
var parentResult ;
if ( queue ) {
for ( var i = queue . length ; i -- ; ) {
result = queue [ i ] . call ( target , target , extraArg ) ;
if ( result === false ) return result ;
}
}
if ( this . parent ) {
return this . parent . trigger ( name , target , extraArg ) ;
}
return true ;
} ,
// Reset UI
reset : function reset ( ) {
// Field case: just emit a reset event for UI
if ( 'ParsleyForm' !== this . _ _class _ _ ) {
this . _resetUI ( ) ;
return this . _trigger ( 'reset' ) ;
}
// Form case: emit a reset event for each field
for ( var i = 0 ; i < this . fields . length ; i ++ ) this . fields [ i ] . reset ( ) ;
this . _trigger ( 'reset' ) ;
} ,
// Destroy Parsley instance (+ UI)
destroy : function destroy ( ) {
// Field case: emit destroy event to clean UI and then destroy stored instance
this . _destroyUI ( ) ;
if ( 'ParsleyForm' !== this . _ _class _ _ ) {
this . $element . removeData ( 'Parsley' ) ;
this . $element . removeData ( 'ParsleyFieldMultiple' ) ;
this . _trigger ( 'destroy' ) ;
return ;
}
// Form case: destroy all its fields and then destroy stored instance
for ( var i = 0 ; i < this . fields . length ; i ++ ) this . fields [ i ] . destroy ( ) ;
this . $element . removeData ( 'Parsley' ) ;
this . _trigger ( 'destroy' ) ;
} ,
asyncIsValid : function asyncIsValid ( group , force ) {
ParsleyUtils _ _default . warnOnce ( "asyncIsValid is deprecated; please use whenValid instead" ) ;
return this . whenValid ( { group : group , force : force } ) ;
} ,
_findRelated : function _findRelated ( ) {
return this . options . multiple ? this . parent . $element . find ( '[' + this . options . namespace + 'multiple="' + this . options . multiple + '"]' ) : this . $element ;
}
} ;
var requirementConverters = {
string : function string ( _string ) {
return _string ;
} ,
integer : function integer ( string ) {
if ( isNaN ( string ) ) throw 'Requirement is not an integer: "' + string + '"' ;
return parseInt ( string , 10 ) ;
} ,
number : function number ( string ) {
if ( isNaN ( string ) ) throw 'Requirement is not a number: "' + string + '"' ;
return parseFloat ( string ) ;
} ,
reference : function reference ( string ) {
// Unused for now
var result = $ ( string ) ;
if ( result . length === 0 ) throw 'No such reference: "' + string + '"' ;
return result ;
} ,
boolean : function boolean ( string ) {
return string !== 'false' ;
} ,
object : function object ( string ) {
return ParsleyUtils _ _default . deserializeValue ( string ) ;
} ,
regexp : function regexp ( _regexp ) {
var flags = '' ;
// Test if RegExp is literal, if not, nothing to be done, otherwise, we need to isolate flags and pattern
if ( /^\/.*\/(?:[gimy]*)$/ . test ( _regexp ) ) {
// Replace the regexp literal string with the first match group: ([gimy]*)
// If no flag is present, this will be a blank string
flags = _regexp . replace ( /.*\/([gimy]*)$/ , '$1' ) ;
// Again, replace the regexp literal string with the first match group:
// everything excluding the opening and closing slashes and the flags
_regexp = _regexp . replace ( new RegExp ( '^/(.*?)/' + flags + '$' ) , '$1' ) ;
} else {
// Anchor regexp:
_regexp = '^' + _regexp + '$' ;
}
return new RegExp ( _regexp , flags ) ;
}
} ;
var convertArrayRequirement = function convertArrayRequirement ( string , length ) {
var m = string . match ( /^\s*\[(.*)\]\s*$/ ) ;
if ( ! m ) throw 'Requirement is not an array: "' + string + '"' ;
var values = m [ 1 ] . split ( ',' ) . map ( ParsleyUtils _ _default . trimString ) ;
if ( values . length !== length ) throw 'Requirement has ' + values . length + ' values when ' + length + ' are needed' ;
return values ;
} ;
var convertRequirement = function convertRequirement ( requirementType , string ) {
var converter = requirementConverters [ requirementType || 'string' ] ;
if ( ! converter ) throw 'Unknown requirement specification: "' + requirementType + '"' ;
return converter ( string ) ;
} ;
var convertExtraOptionRequirement = function convertExtraOptionRequirement ( requirementSpec , string , extraOptionReader ) {
var main = null ;
var extra = { } ;
for ( var key in requirementSpec ) {
if ( key ) {
var value = extraOptionReader ( key ) ;
if ( 'string' === typeof value ) value = convertRequirement ( requirementSpec [ key ] , value ) ;
extra [ key ] = value ;
} else {
main = convertRequirement ( requirementSpec [ key ] , string ) ;
}
}
return [ main , extra ] ;
} ;
// A Validator needs to implement the methods `validate` and `parseRequirements`
var ParsleyValidator = function ParsleyValidator ( spec ) {
$ . extend ( true , this , spec ) ;
} ;
ParsleyValidator . prototype = {
// Returns `true` iff the given `value` is valid according the given requirements.
validate : function validate ( value , requirementFirstArg ) {
if ( this . fn ) {
// Legacy style validator
if ( arguments . length > 3 ) // If more args then value, requirement, instance...
requirementFirstArg = [ ] . slice . call ( arguments , 1 , - 1 ) ; // Skip first arg (value) and last (instance), combining the rest
return this . fn . call ( this , value , requirementFirstArg ) ;
}
if ( $ . isArray ( value ) ) {
if ( ! this . validateMultiple ) throw 'Validator `' + this . name + '` does not handle multiple values' ;
return this . validateMultiple . apply ( this , arguments ) ;
} else {
if ( this . validateNumber ) {
if ( isNaN ( value ) ) return false ;
arguments [ 0 ] = parseFloat ( arguments [ 0 ] ) ;
return this . validateNumber . apply ( this , arguments ) ;
}
if ( this . validateString ) {
return this . validateString . apply ( this , arguments ) ;
}
throw 'Validator `' + this . name + '` only handles multiple values' ;
}
} ,
// Parses `requirements` into an array of arguments,
// according to `this.requirementType`
parseRequirements : function parseRequirements ( requirements , extraOptionReader ) {
if ( 'string' !== typeof requirements ) {
// Assume requirement already parsed
// but make sure we return an array
return $ . isArray ( requirements ) ? requirements : [ requirements ] ;
}
var type = this . requirementType ;
if ( $ . isArray ( type ) ) {
var values = convertArrayRequirement ( requirements , type . length ) ;
for ( var i = 0 ; i < values . length ; i ++ ) values [ i ] = convertRequirement ( type [ i ] , values [ i ] ) ;
return values ;
} else if ( $ . isPlainObject ( type ) ) {
return convertExtraOptionRequirement ( type , requirements , extraOptionReader ) ;
} else {
return [ convertRequirement ( type , requirements ) ] ;
}
} ,
// Defaults:
requirementType : 'string' ,
priority : 2
} ;
var ParsleyValidatorRegistry = function ParsleyValidatorRegistry ( validators , catalog ) {
this . _ _class _ _ = 'ParsleyValidatorRegistry' ;
// Default Parsley locale is en
this . locale = 'en' ;
this . init ( validators || { } , catalog || { } ) ;
} ;
var typeRegexes = {
email : /^((([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 ,
// Follow https://www.w3.org/TR/html5/infrastructure.html#floating-point-numbers
number : /^-?(\d*\.)?\d+(e[-+]?\d+)?$/i ,
integer : /^-?\d+$/ ,
digits : /^\d+$/ ,
alphanum : /^\w+$/i ,
url : new RegExp ( "^" +
// protocol identifier
"(?:(?:https?|ftp)://)?" + // ** mod: make scheme optional
// user:pass authentication
"(?:\\S+(?::\\S*)?@)?" + "(?:" +
// IP address exclusion
// private & local networks
// "(?!(?:10|127)(?:\\.\\d{1,3}){3})" + // ** mod: allow local networks
// "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" + // ** mod: allow local networks
// "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" + // ** mod: allow local networks
// IP address dotted notation octets
// excludes loopback network 0.0.0.0
// excludes reserved space >= 224.0.0.0
// excludes network & broacast addresses
// (first & last IP address of each class)
"(?:[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]))" + "|" +
// host name
'(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)' +
// domain name
'(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*' +
// TLD identifier
'(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))' + ")" +
// port number
"(?::\\d{2,5})?" +
// resource path
"(?:/\\S*)?" + "$" , 'i' )
} ;
typeRegexes . range = typeRegexes . number ;
// See http://stackoverflow.com/a/10454560/8279
var decimalPlaces = function decimalPlaces ( num ) {
var match = ( '' + num ) . match ( /(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/ ) ;
if ( ! match ) {
return 0 ;
}
return Math . max ( 0 ,
// Number of digits right of decimal point.
( match [ 1 ] ? match [ 1 ] . length : 0 ) - (
// Adjust for scientific notation.
match [ 2 ] ? + match [ 2 ] : 0 ) ) ;
} ;
ParsleyValidatorRegistry . prototype = {
init : function init ( validators , catalog ) {
this . catalog = catalog ;
// Copy prototype's validators:
this . validators = $ . extend ( { } , this . validators ) ;
for ( var name in validators ) this . addValidator ( name , validators [ name ] . fn , validators [ name ] . priority ) ;
window . Parsley . trigger ( 'parsley:validator:init' ) ;
} ,
// Set new messages locale if we have dictionary loaded in ParsleyConfig.i18n
setLocale : function setLocale ( locale ) {
if ( 'undefined' === typeof this . catalog [ locale ] ) throw new Error ( locale + ' is not available in the catalog' ) ;
this . locale = locale ;
return this ;
} ,
// Add a new messages catalog for a given locale. Set locale for this catalog if set === `true`
addCatalog : function addCatalog ( locale , messages , set ) {
if ( 'object' === typeof messages ) this . catalog [ locale ] = messages ;
if ( true === set ) return this . setLocale ( locale ) ;
return this ;
} ,
// Add a specific message for a given constraint in a given locale
addMessage : function addMessage ( locale , name , message ) {
if ( 'undefined' === typeof this . catalog [ locale ] ) this . catalog [ locale ] = { } ;
this . catalog [ locale ] [ name ] = message ;
return this ;
} ,
// Add messages for a given locale
addMessages : function addMessages ( locale , nameMessageObject ) {
for ( var name in nameMessageObject ) this . addMessage ( locale , name , nameMessageObject [ name ] ) ;
return this ;
} ,
// Add a new validator
//
// addValidator('custom', {
// requirementType: ['integer', 'integer'],
// validateString: function(value, from, to) {},
// priority: 22,
// messages: {
// en: "Hey, that's no good",
// fr: "Aye aye, pas bon du tout",
// }
// })
//
// Old API was addValidator(name, function, priority)
//
addValidator : function addValidator ( name , arg1 , arg2 ) {
if ( this . validators [ name ] ) ParsleyUtils _ _default . warn ( 'Validator "' + name + '" is already defined.' ) ; else if ( ParsleyDefaults . hasOwnProperty ( name ) ) {
ParsleyUtils _ _default . warn ( '"' + name + '" is a restricted keyword and is not a valid validator name.' ) ;
return ;
}
return this . _setValidator . apply ( this , arguments ) ;
} ,
updateValidator : function updateValidator ( name , arg1 , arg2 ) {
if ( ! this . validators [ name ] ) {
ParsleyUtils _ _default . warn ( 'Validator "' + name + '" is not already defined.' ) ;
return this . addValidator . apply ( this , arguments ) ;
}
return this . _setValidator . apply ( this , arguments ) ;
} ,
removeValidator : function removeValidator ( name ) {
if ( ! this . validators [ name ] ) ParsleyUtils _ _default . warn ( 'Validator "' + name + '" is not defined.' ) ;
delete this . validators [ name ] ;
return this ;
} ,
_setValidator : function _setValidator ( name , validator , priority ) {
if ( 'object' !== typeof validator ) {
// Old style validator, with `fn` and `priority`
validator = {
fn : validator ,
priority : priority
} ;
}
if ( ! validator . validate ) {
validator = new ParsleyValidator ( validator ) ;
}
this . validators [ name ] = validator ;
for ( var locale in validator . messages || { } ) this . addMessage ( locale , name , validator . messages [ locale ] ) ;
return this ;
} ,
getErrorMessage : function getErrorMessage ( constraint ) {
var message ;
// Type constraints are a bit different, we have to match their requirements too to find right error message
if ( 'type' === constraint . name ) {
var typeMessages = this . catalog [ this . locale ] [ constraint . name ] || { } ;
message = typeMessages [ constraint . requirements ] ;
} else message = this . formatMessage ( this . catalog [ this . locale ] [ constraint . name ] , constraint . requirements ) ;
return message || this . catalog [ this . locale ] . defaultMessage || this . catalog . en . defaultMessage ;
} ,
// Kind of light `sprintf()` implementation
formatMessage : function formatMessage ( string , parameters ) {
if ( 'object' === typeof parameters ) {
for ( var i in parameters ) string = this . formatMessage ( string , parameters [ i ] ) ;
return string ;
}
return 'string' === typeof string ? string . replace ( /%s/i , parameters ) : '' ;
} ,
// Here is the Parsley default validators list.
// A validator is an object with the following key values:
// - priority: an integer
// - requirement: 'string' (default), 'integer', 'number', 'regexp' or an Array of these
// - validateString, validateMultiple, validateNumber: functions returning `true`, `false` or a promise
// Alternatively, a validator can be a function that returns such an object
//
validators : {
notblank : {
validateString : function validateString ( value ) {
return ( /\S/ . test ( value )
) ;
} ,
priority : 2
} ,
required : {
validateMultiple : function validateMultiple ( values ) {
return values . length > 0 ;
} ,
validateString : function validateString ( value ) {
return ( /\S/ . test ( value )
) ;
} ,
priority : 512
} ,
type : {
validateString : function validateString ( value , type ) {
var _ref = arguments . length <= 2 || arguments [ 2 ] === undefined ? { } : arguments [ 2 ] ;
var _ref$step = _ref . step ;
var step = _ref$step === undefined ? '1' : _ref$step ;
var _ref$base = _ref . base ;
var base = _ref$base === undefined ? 0 : _ref$base ;
var regex = typeRegexes [ type ] ;
if ( ! regex ) {
throw new Error ( 'validator type `' + type + '` is not supported' ) ;
}
if ( ! regex . test ( value ) ) return false ;
if ( 'number' === type ) {
if ( ! /^any$/i . test ( step || '' ) ) {
var nb = Number ( value ) ;
var decimals = Math . max ( decimalPlaces ( step ) , decimalPlaces ( base ) ) ;
if ( decimalPlaces ( nb ) > decimals ) // Value can't have too many decimals
return false ;
// Be careful of rounding errors by using integers.
var toInt = function toInt ( f ) {
return Math . round ( f * Math . pow ( 10 , decimals ) ) ;
} ;
if ( ( toInt ( nb ) - toInt ( base ) ) % toInt ( step ) != 0 ) return false ;
}
}
return true ;
} ,
requirementType : {
'' : 'string' ,
step : 'string' ,
base : 'number'
} ,
priority : 256
} ,
pattern : {
validateString : function validateString ( value , regexp ) {
return regexp . test ( value ) ;
} ,
requirementType : 'regexp' ,
priority : 64
} ,
minlength : {
validateString : function validateString ( value , requirement ) {
return value . length >= requirement ;
} ,
requirementType : 'integer' ,
priority : 30
} ,
maxlength : {
validateString : function validateString ( value , requirement ) {
return value . length <= requirement ;
} ,
requirementType : 'integer' ,
priority : 30
} ,
length : {
validateString : function validateString ( value , min , max ) {
return value . length >= min && value . length <= max ;
} ,
requirementType : [ 'integer' , 'integer' ] ,
priority : 30
} ,
mincheck : {
validateMultiple : function validateMultiple ( values , requirement ) {
return values . length >= requirement ;
} ,
requirementType : 'integer' ,
priority : 30
} ,
maxcheck : {
validateMultiple : function validateMultiple ( values , requirement ) {
return values . length <= requirement ;
} ,
requirementType : 'integer' ,
priority : 30
} ,
check : {
validateMultiple : function validateMultiple ( values , min , max ) {
return values . length >= min && values . length <= max ;
} ,
requirementType : [ 'integer' , 'integer' ] ,
priority : 30
} ,
min : {
validateNumber : function validateNumber ( value , requirement ) {
return value >= requirement ;
} ,
requirementType : 'number' ,
priority : 30
} ,
max : {
validateNumber : function validateNumber ( value , requirement ) {
return value <= requirement ;
} ,
requirementType : 'number' ,
priority : 30
} ,
range : {
validateNumber : function validateNumber ( value , min , max ) {
return value >= min && value <= max ;
} ,
requirementType : [ 'number' , 'number' ] ,
priority : 30
} ,
equalto : {
validateString : function validateString ( value , refOrValue ) {
var $reference = $ ( refOrValue ) ;
if ( $reference . length ) return value === $reference . val ( ) ; else return value === refOrValue ;
} ,
priority : 256
}
}
} ;
var ParsleyUI = { } ;
var diffResults = function diffResults ( newResult , oldResult , deep ) {
var added = [ ] ;
var kept = [ ] ;
for ( var i = 0 ; i < newResult . length ; i ++ ) {
var found = false ;
for ( var j = 0 ; j < oldResult . length ; j ++ ) if ( newResult [ i ] . assert . name === oldResult [ j ] . assert . name ) {
found = true ;
break ;
}
if ( found ) kept . push ( newResult [ i ] ) ; else added . push ( newResult [ i ] ) ;
}
return {
kept : kept ,
added : added ,
removed : ! deep ? diffResults ( oldResult , newResult , true ) . added : [ ]
} ;
} ;
ParsleyUI . Form = {
_actualizeTriggers : function _actualizeTriggers ( ) {
var _this2 = this ;
this . $element . on ( 'submit.Parsley' , function ( evt ) {
_this2 . onSubmitValidate ( evt ) ;
} ) ;
this . $element . on ( 'click.Parsley' , 'input[type="submit"], button[type="submit"]' , function ( evt ) {
_this2 . onSubmitButton ( evt ) ;
} ) ;
// UI could be disabled
if ( false === this . options . uiEnabled ) return ;
this . $element . attr ( 'novalidate' , '' ) ;
} ,
focus : function focus ( ) {
this . _focusedField = null ;
if ( true === this . validationResult || 'none' === this . options . focus ) return null ;
for ( var i = 0 ; i < this . fields . length ; i ++ ) {
var field = this . fields [ i ] ;
if ( true !== field . validationResult && field . validationResult . length > 0 && 'undefined' === typeof field . options . noFocus ) {
this . _focusedField = field . $element ;
if ( 'first' === this . options . focus ) break ;
}
}
if ( null === this . _focusedField ) return null ;
return this . _focusedField . focus ( ) ;
} ,
_destroyUI : function _destroyUI ( ) {
// Reset all event listeners
this . $element . off ( '.Parsley' ) ;
}
} ;
ParsleyUI . Field = {
_reflowUI : function _reflowUI ( ) {
this . _buildUI ( ) ;
// If this field doesn't have an active UI don't bother doing something
if ( ! this . _ui ) return ;
// Diff between two validation results
var diff = diffResults ( this . validationResult , this . _ui . lastValidationResult ) ;
// Then store current validation result for next reflow
this . _ui . lastValidationResult = this . validationResult ;
// Handle valid / invalid / none field class
this . _manageStatusClass ( ) ;
// Add, remove, updated errors messages
this . _manageErrorsMessages ( diff ) ;
// Triggers impl
this . _actualizeTriggers ( ) ;
// If field is not valid for the first time, bind keyup trigger to ease UX and quickly inform user
if ( ( diff . kept . length || diff . added . length ) && ! this . _failedOnce ) {
this . _failedOnce = true ;
this . _actualizeTriggers ( ) ;
}
} ,
// Returns an array of field's error message(s)
getErrorsMessages : function getErrorsMessages ( ) {
// No error message, field is valid
if ( true === this . validationResult ) return [ ] ;
var messages = [ ] ;
for ( var i = 0 ; i < this . validationResult . length ; i ++ ) messages . push ( this . validationResult [ i ] . errorMessage || this . _getErrorMessage ( this . validationResult [ i ] . assert ) ) ;
return messages ;
} ,
// It's a goal of Parsley that this method is no longer required [#1073]
addError : function addError ( name ) {
var _ref2 = arguments . length <= 1 || arguments [ 1 ] === undefined ? { } : arguments [ 1 ] ;
var message = _ref2 . message ;
var assert = _ref2 . assert ;
var _ref2$updateClass = _ref2 . updateClass ;
var updateClass = _ref2$updateClass === undefined ? true : _ref2$updateClass ;
this . _buildUI ( ) ;
this . _addError ( name , { message : message , assert : assert } ) ;
if ( updateClass ) this . _errorClass ( ) ;
} ,
// It's a goal of Parsley that this method is no longer required [#1073]
updateError : function updateError ( name ) {
var _ref3 = arguments . length <= 1 || arguments [ 1 ] === undefined ? { } : arguments [ 1 ] ;
var message = _ref3 . message ;
var assert = _ref3 . assert ;
var _ref3$updateClass = _ref3 . updateClass ;
var updateClass = _ref3$updateClass === undefined ? true : _ref3$updateClass ;
this . _buildUI ( ) ;
this . _updateError ( name , { message : message , assert : assert } ) ;
if ( updateClass ) this . _errorClass ( ) ;
} ,
// It's a goal of Parsley that this method is no longer required [#1073]
removeError : function removeError ( name ) {
var _ref4 = arguments . length <= 1 || arguments [ 1 ] === undefined ? { } : arguments [ 1 ] ;
var _ref4$updateClass = _ref4 . updateClass ;
var updateClass = _ref4$updateClass === undefined ? true : _ref4$updateClass ;
this . _buildUI ( ) ;
this . _removeError ( name ) ;
// edge case possible here: remove a standard Parsley error that is still failing in this.validationResult
// but highly improbable cuz' manually removing a well Parsley handled error makes no sense.
if ( updateClass ) this . _manageStatusClass ( ) ;
} ,
_manageStatusClass : function _manageStatusClass ( ) {
if ( this . hasConstraints ( ) && this . needsValidation ( ) && true === this . validationResult ) this . _successClass ( ) ; else if ( this . validationResult . length > 0 ) this . _errorClass ( ) ; else this . _resetClass ( ) ;
} ,
_manageErrorsMessages : function _manageErrorsMessages ( diff ) {
if ( 'undefined' !== typeof this . options . errorsMessagesDisabled ) return ;
// Case where we have errorMessage option that configure an unique field error message, regardless failing validators
if ( 'undefined' !== typeof this . options . errorMessage ) {
if ( diff . added . length || diff . kept . length ) {
this . _insertErrorWrapper ( ) ;
if ( 0 === this . _ui . $errorsWrapper . find ( '.parsley-custom-error-message' ) . length ) this . _ui . $errorsWrapper . append ( $ ( this . options . errorTemplate ) . addClass ( 'parsley-custom-error-message' ) ) ;
return this . _ui . $errorsWrapper . addClass ( 'filled' ) . find ( '.parsley-custom-error-message' ) . html ( this . options . errorMessage ) ;
}
return this . _ui . $errorsWrapper . removeClass ( 'filled' ) . find ( '.parsley-custom-error-message' ) . remove ( ) ;
}
// Show, hide, update failing constraints messages
for ( var i = 0 ; i < diff . removed . length ; i ++ ) this . _removeError ( diff . removed [ i ] . assert . name ) ;
for ( i = 0 ; i < diff . added . length ; i ++ ) this . _addError ( diff . added [ i ] . assert . name , { message : diff . added [ i ] . errorMessage , assert : diff . added [ i ] . assert } ) ;
for ( i = 0 ; i < diff . kept . length ; i ++ ) this . _updateError ( diff . kept [ i ] . assert . name , { message : diff . kept [ i ] . errorMessage , assert : diff . kept [ i ] . assert } ) ;
} ,
_addError : function _addError ( name , _ref5 ) {
var message = _ref5 . message ;
var assert = _ref5 . assert ;
this . _insertErrorWrapper ( ) ;
this . _ui . $errorsWrapper . addClass ( 'filled' ) . append ( $ ( this . options . errorTemplate ) . addClass ( 'parsley-' + name ) . html ( message || this . _getErrorMessage ( assert ) ) ) ;
} ,
_updateError : function _updateError ( name , _ref6 ) {
var message = _ref6 . message ;
var assert = _ref6 . assert ;
this . _ui . $errorsWrapper . addClass ( 'filled' ) . find ( '.parsley-' + name ) . html ( message || this . _getErrorMessage ( assert ) ) ;
} ,
_removeError : function _removeError ( name ) {
this . _ui . $errorsWrapper . removeClass ( 'filled' ) . find ( '.parsley-' + name ) . remove ( ) ;
} ,
_getErrorMessage : function _getErrorMessage ( constraint ) {
var customConstraintErrorMessage = constraint . name + 'Message' ;
if ( 'undefined' !== typeof this . options [ customConstraintErrorMessage ] ) return window . Parsley . formatMessage ( this . options [ customConstraintErrorMessage ] , constraint . requirements ) ;
return window . Parsley . getErrorMessage ( constraint ) ;
} ,
_buildUI : function _buildUI ( ) {
// UI could be already built or disabled
if ( this . _ui || false === this . options . uiEnabled ) return ;
var _ui = { } ;
// Give field its Parsley id in DOM
this . $element . attr ( this . options . namespace + 'id' , this . _ _id _ _ ) ;
/** Generate important UI elements and store them in this **/
// $errorClassHandler is the $element that woul have parsley-error and parsley-success classes
_ui . $errorClassHandler = this . _manageClassHandler ( ) ;
// $errorsWrapper is a div that would contain the various field errors, it will be appended into $errorsContainer
_ui . errorsWrapperId = 'parsley-id-' + ( this . options . multiple ? 'multiple-' + this . options . multiple : this . _ _id _ _ ) ;
_ui . $errorsWrapper = $ ( this . options . errorsWrapper ) . attr ( 'id' , _ui . errorsWrapperId ) ;
// ValidationResult UI storage to detect what have changed bwt two validations, and update DOM accordingly
_ui . lastValidationResult = [ ] ;
_ui . validationInformationVisible = false ;
// Store it in this for later
this . _ui = _ui ;
} ,
// Determine which element will have `parsley-error` and `parsley-success` classes
_manageClassHandler : function _manageClassHandler ( ) {
// An element selector could be passed through DOM with `data-parsley-class-handler=#foo`
if ( 'string' === typeof this . options . classHandler && $ ( this . options . classHandler ) . length ) return $ ( this . options . classHandler ) ;
// Class handled could also be determined by function given in Parsley options
var $handler = this . options . classHandler . call ( this , this ) ;
// If this function returned a valid existing DOM element, go for it
if ( 'undefined' !== typeof $handler && $handler . length ) return $handler ;
// Otherwise, if simple element (input, texatrea, select...) it will perfectly host the classes
if ( ! this . options . multiple || this . $element . is ( 'select' ) ) return this . $element ;
// But if multiple element (radio, checkbox), that would be their parent
return this . $element . parent ( ) ;
} ,
_insertErrorWrapper : function _insertErrorWrapper ( ) {
var $errorsContainer ;
// Nothing to do if already inserted
if ( 0 !== this . _ui . $errorsWrapper . parent ( ) . length ) return this . _ui . $errorsWrapper . parent ( ) ;
if ( 'string' === typeof this . options . errorsContainer ) {
if ( $ ( this . options . errorsContainer ) . length ) return $ ( this . options . errorsContainer ) . append ( this . _ui . $errorsWrapper ) ; else ParsleyUtils _ _default . warn ( 'The errors container `' + this . options . errorsContainer + '` does not exist in DOM' ) ;
} else if ( 'function' === typeof this . options . errorsContainer ) $errorsContainer = this . options . errorsContainer . call ( this , this ) ;
if ( 'undefined' !== typeof $errorsContainer && $errorsContainer . length ) return $errorsContainer . append ( this . _ui . $errorsWrapper ) ;
var $from = this . $element ;
if ( this . options . multiple ) $from = $from . parent ( ) ;
return $from . after ( this . _ui . $errorsWrapper ) ;
} ,
_actualizeTriggers : function _actualizeTriggers ( ) {
var _this3 = this ;
var $toBind = this . _findRelated ( ) ;
2016-05-04 15:40:49 +00:00
var trigger ;
2016-04-24 14:26:11 +00:00
// Remove Parsley events already bound on this field
$toBind . off ( '.Parsley' ) ;
if ( this . _failedOnce ) $toBind . on ( ParsleyUtils _ _default . namespaceEvents ( this . options . triggerAfterFailure , 'Parsley' ) , function ( ) {
_this3 . validate ( ) ;
2016-05-04 15:40:49 +00:00
} ) ; else if ( trigger = ParsleyUtils _ _default . namespaceEvents ( this . options . trigger , 'Parsley' ) ) {
$toBind . on ( trigger , function ( event ) {
2016-04-24 14:26:11 +00:00
_this3 . _eventValidate ( event ) ;
} ) ;
}
} ,
_eventValidate : function _eventValidate ( event ) {
// For keyup, keypress, keydown, input... events that could be a little bit obstrusive
// do not validate if val length < min threshold on first validation. Once field have been validated once and info
// about success or failure have been displayed, always validate with this trigger to reflect every yalidation change.
if ( /key|input/ . test ( event . type ) ) if ( ! ( this . _ui && this . _ui . validationInformationVisible ) && this . getValue ( ) . length <= this . options . validationThreshold ) return ;
this . validate ( ) ;
} ,
_resetUI : function _resetUI ( ) {
// Reset all event listeners
this . _failedOnce = false ;
this . _actualizeTriggers ( ) ;
// Nothing to do if UI never initialized for this field
if ( 'undefined' === typeof this . _ui ) return ;
// Reset all errors' li
this . _ui . $errorsWrapper . removeClass ( 'filled' ) . children ( ) . remove ( ) ;
// Reset validation class
this . _resetClass ( ) ;
// Reset validation flags and last validation result
this . _ui . lastValidationResult = [ ] ;
this . _ui . validationInformationVisible = false ;
} ,
_destroyUI : function _destroyUI ( ) {
this . _resetUI ( ) ;
if ( 'undefined' !== typeof this . _ui ) this . _ui . $errorsWrapper . remove ( ) ;
delete this . _ui ;
} ,
_successClass : function _successClass ( ) {
this . _ui . validationInformationVisible = true ;
this . _ui . $errorClassHandler . removeClass ( this . options . errorClass ) . addClass ( this . options . successClass ) ;
} ,
_errorClass : function _errorClass ( ) {
this . _ui . validationInformationVisible = true ;
this . _ui . $errorClassHandler . removeClass ( this . options . successClass ) . addClass ( this . options . errorClass ) ;
} ,
_resetClass : function _resetClass ( ) {
this . _ui . $errorClassHandler . removeClass ( this . options . successClass ) . removeClass ( this . options . errorClass ) ;
}
} ;
var ParsleyForm = function ParsleyForm ( element , domOptions , options ) {
this . _ _class _ _ = 'ParsleyForm' ;
this . $element = $ ( element ) ;
this . domOptions = domOptions ;
this . options = options ;
this . parent = window . Parsley ;
this . fields = [ ] ;
this . validationResult = null ;
} ;
var ParsleyForm _ _statusMapping = { pending : null , resolved : true , rejected : false } ;
ParsleyForm . prototype = {
onSubmitValidate : function onSubmitValidate ( event ) {
var _this4 = this ;
// This is a Parsley generated submit event, do not validate, do not prevent, simply exit and keep normal behavior
if ( true === event . parsley ) return ;
// If we didn't come here through a submit button, use the first one in the form
var $submitSource = this . _$submitSource || this . $element . find ( 'input[type="submit"], button[type="submit"]' ) . first ( ) ;
this . _$submitSource = null ;
this . $element . find ( '.parsley-synthetic-submit-button' ) . prop ( 'disabled' , true ) ;
if ( $submitSource . is ( '[formnovalidate]' ) ) return ;
var promise = this . whenValidate ( { event : event } ) ;
if ( 'resolved' === promise . state ( ) && false !== this . _trigger ( 'submit' ) ) {
// All good, let event go through. We make this distinction because browsers
// differ in their handling of `submit` being called from inside a submit event [#1047]
} else {
// Rejected or pending: cancel this submit
event . stopImmediatePropagation ( ) ;
event . preventDefault ( ) ;
if ( 'pending' === promise . state ( ) ) promise . done ( function ( ) {
_this4 . _submit ( $submitSource ) ;
} ) ;
}
} ,
onSubmitButton : function onSubmitButton ( event ) {
this . _$submitSource = $ ( event . target ) ;
} ,
// internal
// _submit submits the form, this time without going through the validations.
// Care must be taken to "fake" the actual submit button being clicked.
_submit : function _submit ( $submitSource ) {
if ( false === this . _trigger ( 'submit' ) ) return ;
// Add submit button's data
if ( $submitSource ) {
var $synthetic = this . $element . find ( '.parsley-synthetic-submit-button' ) . prop ( 'disabled' , false ) ;
if ( 0 === $synthetic . length ) $synthetic = $ ( '<input class="parsley-synthetic-submit-button" type="hidden">' ) . appendTo ( this . $element ) ;
$synthetic . attr ( {
name : $submitSource . attr ( 'name' ) ,
value : $submitSource . attr ( 'value' )
} ) ;
}
this . $element . trigger ( $ . extend ( $ . Event ( 'submit' ) , { parsley : true } ) ) ;
} ,
// Performs validation on fields while triggering events.
// @returns `true` if all validations succeeds, `false`
// if a failure is immediately detected, or `null`
// if dependant on a promise.
// Consider using `whenValidate` instead.
validate : function validate ( options ) {
if ( arguments . length >= 1 && ! $ . isPlainObject ( options ) ) {
ParsleyUtils _ _default . warnOnce ( 'Calling validate on a parsley form without passing arguments as an object is deprecated.' ) ;
var _arguments = _slice . call ( arguments ) ;
var group = _arguments [ 0 ] ;
var force = _arguments [ 1 ] ;
var event = _arguments [ 2 ] ;
options = { group : group , force : force , event : event } ;
}
return ParsleyForm _ _statusMapping [ this . whenValidate ( options ) . state ( ) ] ;
} ,
whenValidate : function whenValidate ( ) {
var _$$when$done$fail$always ,
_this5 = this ;
var _ref7 = arguments . length <= 0 || arguments [ 0 ] === undefined ? { } : arguments [ 0 ] ;
var group = _ref7 . group ;
var force = _ref7 . force ;
var event = _ref7 . event ;
this . submitEvent = event ;
if ( event ) {
this . submitEvent = $ . extend ( { } , event , { preventDefault : function preventDefault ( ) {
ParsleyUtils _ _default . warnOnce ( "Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`" ) ;
_this5 . validationResult = false ;
} } ) ;
}
this . validationResult = true ;
// fire validate event to eventually modify things before very validation
this . _trigger ( 'validate' ) ;
// Refresh form DOM options and form's fields that could have changed
this . _refreshFields ( ) ;
var promises = this . _withoutReactualizingFormOptions ( function ( ) {
return $ . map ( _this5 . fields , function ( field ) {
return field . whenValidate ( { force : force , group : group } ) ;
} ) ;
} ) ;
return ( _$$when$done$fail$always = $ . when . apply ( $ , _toConsumableArray ( promises ) ) . done ( function ( ) {
_this5 . _trigger ( 'success' ) ;
} ) . fail ( function ( ) {
_this5 . validationResult = false ;
_this5 . focus ( ) ;
_this5 . _trigger ( 'error' ) ;
} ) . always ( function ( ) {
_this5 . _trigger ( 'validated' ) ;
} ) ) . pipe . apply ( _$$when$done$fail$always , _toConsumableArray ( this . _pipeAccordingToValidationResult ( ) ) ) ;
} ,
// Iterate over refreshed fields, and stop on first failure.
// Returns `true` if all fields are valid, `false` if a failure is detected
// or `null` if the result depends on an unresolved promise.
// Prefer using `whenValid` instead.
isValid : function isValid ( options ) {
if ( arguments . length >= 1 && ! $ . isPlainObject ( options ) ) {
ParsleyUtils _ _default . warnOnce ( 'Calling isValid on a parsley form without passing arguments as an object is deprecated.' ) ;
var _arguments2 = _slice . call ( arguments ) ;
var group = _arguments2 [ 0 ] ;
var force = _arguments2 [ 1 ] ;
options = { group : group , force : force } ;
}
return ParsleyForm _ _statusMapping [ this . whenValid ( options ) . state ( ) ] ;
} ,
// Iterate over refreshed fields and validate them.
// Returns a promise.
// A validation that immediately fails will interrupt the validations.
whenValid : function whenValid ( ) {
var _this6 = this ;
var _ref8 = arguments . length <= 0 || arguments [ 0 ] === undefined ? { } : arguments [ 0 ] ;
var group = _ref8 . group ;
var force = _ref8 . force ;
this . _refreshFields ( ) ;
var promises = this . _withoutReactualizingFormOptions ( function ( ) {
return $ . map ( _this6 . fields , function ( field ) {
return field . whenValid ( { group : group , force : force } ) ;
} ) ;
} ) ;
return $ . when . apply ( $ , _toConsumableArray ( promises ) ) ;
} ,
_refreshFields : function _refreshFields ( ) {
return this . actualizeOptions ( ) . _bindFields ( ) ;
} ,
_bindFields : function _bindFields ( ) {
var _this7 = this ;
var oldFields = this . fields ;
this . fields = [ ] ;
this . fieldsMappedById = { } ;
this . _withoutReactualizingFormOptions ( function ( ) {
_this7 . $element . find ( _this7 . options . inputs ) . not ( _this7 . options . excluded ) . each ( function ( _ , element ) {
var fieldInstance = new window . Parsley . Factory ( element , { } , _this7 ) ;
// Only add valid and not excluded `ParsleyField` and `ParsleyFieldMultiple` children
if ( ( 'ParsleyField' === fieldInstance . _ _class _ _ || 'ParsleyFieldMultiple' === fieldInstance . _ _class _ _ ) && true !== fieldInstance . options . excluded ) if ( 'undefined' === typeof _this7 . fieldsMappedById [ fieldInstance . _ _class _ _ + '-' + fieldInstance . _ _id _ _ ] ) {
_this7 . fieldsMappedById [ fieldInstance . _ _class _ _ + '-' + fieldInstance . _ _id _ _ ] = fieldInstance ;
_this7 . fields . push ( fieldInstance ) ;
}
} ) ;
$ ( oldFields ) . not ( _this7 . fields ) . each ( function ( _ , field ) {
field . _trigger ( 'reset' ) ;
} ) ;
} ) ;
return this ;
} ,
// Internal only.
// Looping on a form's fields to do validation or similar
// will trigger reactualizing options on all of them, which
// in turn will reactualize the form's options.
// To avoid calling actualizeOptions so many times on the form
// for nothing, _withoutReactualizingFormOptions temporarily disables
// the method actualizeOptions on this form while `fn` is called.
_withoutReactualizingFormOptions : function _withoutReactualizingFormOptions ( fn ) {
var oldActualizeOptions = this . actualizeOptions ;
this . actualizeOptions = function ( ) {
return this ;
} ;
var result = fn ( ) ;
this . actualizeOptions = oldActualizeOptions ;
return result ;
} ,
// Internal only.
// Shortcut to trigger an event
// Returns true iff event is not interrupted and default not prevented.
_trigger : function _trigger ( eventName ) {
return this . trigger ( 'form:' + eventName ) ;
}
} ;
var ConstraintFactory = function ConstraintFactory ( parsleyField , name , requirements , priority , isDomConstraint ) {
if ( ! /ParsleyField/ . test ( parsleyField . _ _class _ _ ) ) throw new Error ( 'ParsleyField or ParsleyFieldMultiple instance expected' ) ;
var validatorSpec = window . Parsley . _validatorRegistry . validators [ name ] ;
var validator = new ParsleyValidator ( validatorSpec ) ;
$ . extend ( this , {
validator : validator ,
name : name ,
requirements : requirements ,
priority : priority || parsleyField . options [ name + 'Priority' ] || validator . priority ,
isDomConstraint : true === isDomConstraint
} ) ;
this . _parseRequirements ( parsleyField . options ) ;
} ;
var capitalize = function capitalize ( str ) {
var cap = str [ 0 ] . toUpperCase ( ) ;
return cap + str . slice ( 1 ) ;
} ;
ConstraintFactory . prototype = {
validate : function validate ( value , instance ) {
var args = this . requirementList . slice ( 0 ) ; // Make copy
args . unshift ( value ) ;
args . push ( instance ) ;
return this . validator . validate . apply ( this . validator , args ) ;
} ,
_parseRequirements : function _parseRequirements ( options ) {
var _this8 = this ;
this . requirementList = this . validator . parseRequirements ( this . requirements , function ( key ) {
return options [ _this8 . name + capitalize ( key ) ] ;
} ) ;
}
} ;
var ParsleyField = function ParsleyField ( field , domOptions , options , parsleyFormInstance ) {
this . _ _class _ _ = 'ParsleyField' ;
this . $element = $ ( field ) ;
// Set parent if we have one
if ( 'undefined' !== typeof parsleyFormInstance ) {
this . parent = parsleyFormInstance ;
}
this . options = options ;
this . domOptions = domOptions ;
// Initialize some properties
this . constraints = [ ] ;
this . constraintsByName = { } ;
this . validationResult = true ;
// Bind constraints
this . _bindConstraints ( ) ;
} ;
var parsley _field _ _statusMapping = { pending : null , resolved : true , rejected : false } ;
ParsleyField . prototype = {
// # Public API
// Validate field and trigger some events for mainly `ParsleyUI`
// @returns `true`, an array of the validators that failed, or
// `null` if validation is not finished. Prefer using whenValidate
validate : function validate ( options ) {
if ( arguments . length >= 1 && ! $ . isPlainObject ( options ) ) {
ParsleyUtils _ _default . warnOnce ( 'Calling validate on a parsley field without passing arguments as an object is deprecated.' ) ;
options = { options : options } ;
}
var promise = this . whenValidate ( options ) ;
if ( ! promise ) // If excluded with `group` option
return true ;
switch ( promise . state ( ) ) {
case 'pending' :
return null ;
case 'resolved' :
return true ;
case 'rejected' :
return this . validationResult ;
}
} ,
// Validate field and trigger some events for mainly `ParsleyUI`
// @returns a promise that succeeds only when all validations do
// or `undefined` if field is not in the given `group`.
whenValidate : function whenValidate ( ) {
var _whenValid$always$done$fail$always ,
_this9 = this ;
var _ref9 = arguments . length <= 0 || arguments [ 0 ] === undefined ? { } : arguments [ 0 ] ;
var force = _ref9 . force ;
var group = _ref9 . group ;
// do not validate a field if not the same as given validation group
this . refreshConstraints ( ) ;
if ( group && ! this . _isInGroup ( group ) ) return ;
this . value = this . getValue ( ) ;
// Field Validate event. `this.value` could be altered for custom needs
this . _trigger ( 'validate' ) ;
return ( _whenValid$always$done$fail$always = this . whenValid ( { force : force , value : this . value , _refreshed : true } ) . always ( function ( ) {
_this9 . _reflowUI ( ) ;
} ) . done ( function ( ) {
_this9 . _trigger ( 'success' ) ;
} ) . fail ( function ( ) {
_this9 . _trigger ( 'error' ) ;
} ) . always ( function ( ) {
_this9 . _trigger ( 'validated' ) ;
} ) ) . pipe . apply ( _whenValid$always$done$fail$always , _toConsumableArray ( this . _pipeAccordingToValidationResult ( ) ) ) ;
} ,
hasConstraints : function hasConstraints ( ) {
return 0 !== this . constraints . length ;
} ,
// An empty optional field does not need validation
needsValidation : function needsValidation ( value ) {
if ( 'undefined' === typeof value ) value = this . getValue ( ) ;
// If a field is empty and not required, it is valid
// Except if `data-parsley-validate-if-empty` explicitely added, useful for some custom validators
if ( ! value . length && ! this . _isRequired ( ) && 'undefined' === typeof this . options . validateIfEmpty ) return false ;
return true ;
} ,
_isInGroup : function _isInGroup ( group ) {
if ( $ . isArray ( this . options . group ) ) return - 1 !== $ . inArray ( group , this . options . group ) ;
return this . options . group === group ;
} ,
// Just validate field. Do not trigger any event.
// Returns `true` iff all constraints pass, `false` if there are failures,
// or `null` if the result can not be determined yet (depends on a promise)
// See also `whenValid`.
isValid : function isValid ( options ) {
if ( arguments . length >= 1 && ! $ . isPlainObject ( options ) ) {
ParsleyUtils _ _default . warnOnce ( 'Calling isValid on a parsley field without passing arguments as an object is deprecated.' ) ;
var _arguments3 = _slice . call ( arguments ) ;
var force = _arguments3 [ 0 ] ;
var value = _arguments3 [ 1 ] ;
options = { force : force , value : value } ;
}
var promise = this . whenValid ( options ) ;
if ( ! promise ) // Excluded via `group`
return true ;
return parsley _field _ _statusMapping [ promise . state ( ) ] ;
} ,
// Just validate field. Do not trigger any event.
// @returns a promise that succeeds only when all validations do
// or `undefined` if the field is not in the given `group`.
// The argument `force` will force validation of empty fields.
// If a `value` is given, it will be validated instead of the value of the input.
whenValid : function whenValid ( ) {
var _this10 = this ;
var _ref10 = arguments . length <= 0 || arguments [ 0 ] === undefined ? { } : arguments [ 0 ] ;
var _ref10$force = _ref10 . force ;
var force = _ref10$force === undefined ? false : _ref10$force ;
var value = _ref10 . value ;
var group = _ref10 . group ;
var _refreshed = _ref10 . _refreshed ;
// Recompute options and rebind constraints to have latest changes
if ( ! _refreshed ) this . refreshConstraints ( ) ;
// do not validate a field if not the same as given validation group
if ( group && ! this . _isInGroup ( group ) ) return ;
this . validationResult = true ;
// A field without constraint is valid
if ( ! this . hasConstraints ( ) ) return $ . when ( ) ;
// Value could be passed as argument, needed to add more power to 'field:validate'
if ( 'undefined' === typeof value || null === value ) value = this . getValue ( ) ;
if ( ! this . needsValidation ( value ) && true !== force ) return $ . when ( ) ;
var groupedConstraints = this . _getGroupedConstraints ( ) ;
var promises = [ ] ;
$ . each ( groupedConstraints , function ( _ , constraints ) {
// Process one group of constraints at a time, we validate the constraints
// and combine the promises together.
var promise = $ . when . apply ( $ , _toConsumableArray ( $ . map ( constraints , function ( constraint ) {
return _this10 . _validateConstraint ( value , constraint ) ;
} ) ) ) ;
promises . push ( promise ) ;
if ( promise . state ( ) === 'rejected' ) return false ; // Interrupt processing if a group has already failed
} ) ;
return $ . when . apply ( $ , promises ) ;
} ,
// @returns a promise
_validateConstraint : function _validateConstraint ( value , constraint ) {
var _this11 = this ;
var result = constraint . validate ( value , this ) ;
// Map false to a failed promise
if ( false === result ) result = $ . Deferred ( ) . reject ( ) ;
// Make sure we return a promise and that we record failures
return $ . when ( result ) . fail ( function ( errorMessage ) {
if ( ! ( _this11 . validationResult instanceof Array ) ) _this11 . validationResult = [ ] ;
_this11 . validationResult . push ( {
assert : constraint ,
errorMessage : 'string' === typeof errorMessage && errorMessage
} ) ;
} ) ;
} ,
// @returns Parsley field computed value that could be overrided or configured in DOM
getValue : function getValue ( ) {
var value ;
// Value could be overriden in DOM or with explicit options
if ( 'function' === typeof this . options . value ) value = this . options . value ( this ) ; else if ( 'undefined' !== typeof this . options . value ) value = this . options . value ; else value = this . $element . val ( ) ;
// Handle wrong DOM or configurations
if ( 'undefined' === typeof value || null === value ) return '' ;
return this . _handleWhitespace ( value ) ;
} ,
// Actualize options that could have change since previous validation
// Re-bind accordingly constraints (could be some new, removed or updated)
refreshConstraints : function refreshConstraints ( ) {
return this . actualizeOptions ( ) . _bindConstraints ( ) ;
} ,
/ * *
* Add a new constraint to a field
*
* @ param { String } name
* @ param { Mixed } requirements optional
* @ param { Number } priority optional
* @ param { Boolean } isDomConstraint optional
* /
addConstraint : function addConstraint ( name , requirements , priority , isDomConstraint ) {
if ( window . Parsley . _validatorRegistry . validators [ name ] ) {
var constraint = new ConstraintFactory ( this , name , requirements , priority , isDomConstraint ) ;
// if constraint already exist, delete it and push new version
if ( 'undefined' !== this . constraintsByName [ constraint . name ] ) this . removeConstraint ( constraint . name ) ;
this . constraints . push ( constraint ) ;
this . constraintsByName [ constraint . name ] = constraint ;
}
return this ;
} ,
// Remove a constraint
removeConstraint : function removeConstraint ( name ) {
for ( var i = 0 ; i < this . constraints . length ; i ++ ) if ( name === this . constraints [ i ] . name ) {
this . constraints . splice ( i , 1 ) ;
break ;
}
delete this . constraintsByName [ name ] ;
return this ;
} ,
// Update a constraint (Remove + re-add)
updateConstraint : function updateConstraint ( name , parameters , priority ) {
return this . removeConstraint ( name ) . addConstraint ( name , parameters , priority ) ;
} ,
// # Internals
// Internal only.
// Bind constraints from config + options + DOM
_bindConstraints : function _bindConstraints ( ) {
var constraints = [ ] ;
var constraintsByName = { } ;
// clean all existing DOM constraints to only keep javascript user constraints
for ( var i = 0 ; i < this . constraints . length ; i ++ ) if ( false === this . constraints [ i ] . isDomConstraint ) {
constraints . push ( this . constraints [ i ] ) ;
constraintsByName [ this . constraints [ i ] . name ] = this . constraints [ i ] ;
}
this . constraints = constraints ;
this . constraintsByName = constraintsByName ;
// then re-add Parsley DOM-API constraints
for ( var name in this . options ) this . addConstraint ( name , this . options [ name ] , undefined , true ) ;
// finally, bind special HTML5 constraints
return this . _bindHtml5Constraints ( ) ;
} ,
// Internal only.
// Bind specific HTML5 constraints to be HTML5 compliant
_bindHtml5Constraints : function _bindHtml5Constraints ( ) {
// html5 required
if ( this . $element . hasClass ( 'required' ) || this . $element . attr ( 'required' ) ) this . addConstraint ( 'required' , true , undefined , true ) ;
// html5 pattern
if ( 'string' === typeof this . $element . attr ( 'pattern' ) ) this . addConstraint ( 'pattern' , this . $element . attr ( 'pattern' ) , undefined , true ) ;
// range
if ( 'undefined' !== typeof this . $element . attr ( 'min' ) && 'undefined' !== typeof this . $element . attr ( 'max' ) ) this . addConstraint ( 'range' , [ this . $element . attr ( 'min' ) , this . $element . attr ( 'max' ) ] , undefined , true ) ;
// HTML5 min
else if ( 'undefined' !== typeof this . $element . attr ( 'min' ) ) this . addConstraint ( 'min' , this . $element . attr ( 'min' ) , undefined , true ) ;
// HTML5 max
else if ( 'undefined' !== typeof this . $element . attr ( 'max' ) ) this . addConstraint ( 'max' , this . $element . attr ( 'max' ) , undefined , true ) ;
// length
if ( 'undefined' !== typeof this . $element . attr ( 'minlength' ) && 'undefined' !== typeof this . $element . attr ( 'maxlength' ) ) this . addConstraint ( 'length' , [ this . $element . attr ( 'minlength' ) , this . $element . attr ( 'maxlength' ) ] , undefined , true ) ;
// HTML5 minlength
else if ( 'undefined' !== typeof this . $element . attr ( 'minlength' ) ) this . addConstraint ( 'minlength' , this . $element . attr ( 'minlength' ) , undefined , true ) ;
// HTML5 maxlength
else if ( 'undefined' !== typeof this . $element . attr ( 'maxlength' ) ) this . addConstraint ( 'maxlength' , this . $element . attr ( 'maxlength' ) , undefined , true ) ;
// html5 types
var type = this . $element . attr ( 'type' ) ;
if ( 'undefined' === typeof type ) return this ;
// Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise
if ( 'number' === type ) {
return this . addConstraint ( 'type' , [ 'number' , {
step : this . $element . attr ( 'step' ) ,
base : this . $element . attr ( 'min' ) || this . $element . attr ( 'value' )
} ] , undefined , true ) ;
// Regular other HTML5 supported types
} else if ( /^(email|url|range)$/i . test ( type ) ) {
return this . addConstraint ( 'type' , type , undefined , true ) ;
}
return this ;
} ,
// Internal only.
// Field is required if have required constraint without `false` value
_isRequired : function _isRequired ( ) {
if ( 'undefined' === typeof this . constraintsByName . required ) return false ;
return false !== this . constraintsByName . required . requirements ;
} ,
// Internal only.
// Shortcut to trigger an event
_trigger : function _trigger ( eventName ) {
return this . trigger ( 'field:' + eventName ) ;
} ,
// Internal only
// Handles whitespace in a value
// Use `data-parsley-whitespace="squish"` to auto squish input value
// Use `data-parsley-whitespace="trim"` to auto trim input value
_handleWhitespace : function _handleWhitespace ( value ) {
if ( true === this . options . trimValue ) ParsleyUtils _ _default . warnOnce ( 'data-parsley-trim-value="true" is deprecated, please use data-parsley-whitespace="trim"' ) ;
if ( 'squish' === this . options . whitespace ) value = value . replace ( /\s{2,}/g , ' ' ) ;
if ( 'trim' === this . options . whitespace || 'squish' === this . options . whitespace || true === this . options . trimValue ) value = ParsleyUtils _ _default . trimString ( value ) ;
return value ;
} ,
// Internal only.
// Returns the constraints, grouped by descending priority.
// The result is thus an array of arrays of constraints.
_getGroupedConstraints : function _getGroupedConstraints ( ) {
if ( false === this . options . priorityEnabled ) return [ this . constraints ] ;
var groupedConstraints = [ ] ;
var index = { } ;
// Create array unique of priorities
for ( var i = 0 ; i < this . constraints . length ; i ++ ) {
var p = this . constraints [ i ] . priority ;
if ( ! index [ p ] ) groupedConstraints . push ( index [ p ] = [ ] ) ;
index [ p ] . push ( this . constraints [ i ] ) ;
}
// Sort them by priority DESC
groupedConstraints . sort ( function ( a , b ) {
return b [ 0 ] . priority - a [ 0 ] . priority ;
} ) ;
return groupedConstraints ;
}
} ;
var parsley _field = ParsleyField ;
var ParsleyMultiple = function ParsleyMultiple ( ) {
this . _ _class _ _ = 'ParsleyFieldMultiple' ;
} ;
ParsleyMultiple . prototype = {
// Add new `$element` sibling for multiple field
addElement : function addElement ( $element ) {
this . $elements . push ( $element ) ;
return this ;
} ,
// See `ParsleyField.refreshConstraints()`
refreshConstraints : function refreshConstraints ( ) {
var fieldConstraints ;
this . constraints = [ ] ;
// Select multiple special treatment
if ( this . $element . is ( 'select' ) ) {
this . actualizeOptions ( ) . _bindConstraints ( ) ;
return this ;
}
// Gather all constraints for each input in the multiple group
for ( var i = 0 ; i < this . $elements . length ; i ++ ) {
// Check if element have not been dynamically removed since last binding
if ( ! $ ( 'html' ) . has ( this . $elements [ i ] ) . length ) {
this . $elements . splice ( i , 1 ) ;
continue ;
}
fieldConstraints = this . $elements [ i ] . data ( 'ParsleyFieldMultiple' ) . refreshConstraints ( ) . constraints ;
for ( var j = 0 ; j < fieldConstraints . length ; j ++ ) this . addConstraint ( fieldConstraints [ j ] . name , fieldConstraints [ j ] . requirements , fieldConstraints [ j ] . priority , fieldConstraints [ j ] . isDomConstraint ) ;
}
return this ;
} ,
// See `ParsleyField.getValue()`
getValue : function getValue ( ) {
// Value could be overriden in DOM
if ( 'function' === typeof this . options . value ) return this . options . value ( this ) ; else if ( 'undefined' !== typeof this . options . value ) return this . options . value ;
// Radio input case
if ( this . $element . is ( 'input[type=radio]' ) ) return this . _findRelated ( ) . filter ( ':checked' ) . val ( ) || '' ;
// checkbox input case
if ( this . $element . is ( 'input[type=checkbox]' ) ) {
var values = [ ] ;
this . _findRelated ( ) . filter ( ':checked' ) . each ( function ( ) {
values . push ( $ ( this ) . val ( ) ) ;
} ) ;
return values ;
}
// Select multiple case
if ( this . $element . is ( 'select' ) && null === this . $element . val ( ) ) return [ ] ;
// Default case that should never happen
return this . $element . val ( ) ;
} ,
_init : function _init ( ) {
this . $elements = [ this . $element ] ;
return this ;
}
} ;
var ParsleyFactory = function ParsleyFactory ( element , options , parsleyFormInstance ) {
this . $element = $ ( element ) ;
// If the element has already been bound, returns its saved Parsley instance
var savedparsleyFormInstance = this . $element . data ( 'Parsley' ) ;
if ( savedparsleyFormInstance ) {
// If the saved instance has been bound without a ParsleyForm parent and there is one given in this call, add it
if ( 'undefined' !== typeof parsleyFormInstance && savedparsleyFormInstance . parent === window . Parsley ) {
savedparsleyFormInstance . parent = parsleyFormInstance ;
savedparsleyFormInstance . _resetOptions ( savedparsleyFormInstance . options ) ;
}
return savedparsleyFormInstance ;
}
// Parsley must be instantiated with a DOM element or jQuery $element
if ( ! this . $element . length ) throw new Error ( 'You must bind Parsley on an existing element.' ) ;
if ( 'undefined' !== typeof parsleyFormInstance && 'ParsleyForm' !== parsleyFormInstance . _ _class _ _ ) throw new Error ( 'Parent instance must be a ParsleyForm instance' ) ;
this . parent = parsleyFormInstance || window . Parsley ;
return this . init ( options ) ;
} ;
ParsleyFactory . prototype = {
init : function init ( options ) {
this . _ _class _ _ = 'Parsley' ;
2016-05-04 15:40:49 +00:00
this . _ _version _ _ = '2.3.11' ;
2016-04-24 14:26:11 +00:00
this . _ _id _ _ = ParsleyUtils _ _default . generateID ( ) ;
// Pre-compute options
this . _resetOptions ( options ) ;
// A ParsleyForm instance is obviously a `<form>` element but also every node that is not an input and has the `data-parsley-validate` attribute
if ( this . $element . is ( 'form' ) || ParsleyUtils _ _default . checkAttr ( this . $element , this . options . namespace , 'validate' ) && ! this . $element . is ( this . options . inputs ) ) return this . bind ( 'parsleyForm' ) ;
// Every other element is bound as a `ParsleyField` or `ParsleyFieldMultiple`
return this . isMultiple ( ) ? this . handleMultiple ( ) : this . bind ( 'parsleyField' ) ;
} ,
isMultiple : function isMultiple ( ) {
return this . $element . is ( 'input[type=radio], input[type=checkbox]' ) || this . $element . is ( 'select' ) && 'undefined' !== typeof this . $element . attr ( 'multiple' ) ;
} ,
// Multiples fields are a real nightmare :(
// Maybe some refactoring would be appreciated here...
handleMultiple : function handleMultiple ( ) {
var _this12 = this ;
var name ;
var multiple ;
var parsleyMultipleInstance ;
// Handle multiple name
if ( this . options . multiple ) ; // We already have our 'multiple' identifier
else if ( 'undefined' !== typeof this . $element . attr ( 'name' ) && this . $element . attr ( 'name' ) . length ) this . options . multiple = name = this . $element . attr ( 'name' ) ; else if ( 'undefined' !== typeof this . $element . attr ( 'id' ) && this . $element . attr ( 'id' ) . length ) this . options . multiple = this . $element . attr ( 'id' ) ;
// Special select multiple input
if ( this . $element . is ( 'select' ) && 'undefined' !== typeof this . $element . attr ( 'multiple' ) ) {
this . options . multiple = this . options . multiple || this . _ _id _ _ ;
return this . bind ( 'parsleyFieldMultiple' ) ;
// Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it
} else if ( ! this . options . multiple ) {
ParsleyUtils _ _default . warn ( 'To be bound by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.' , this . $element ) ;
return this ;
}
// Remove special chars
this . options . multiple = this . options . multiple . replace ( /(:|\.|\[|\]|\{|\}|\$)/g , '' ) ;
// Add proper `data-parsley-multiple` to siblings if we have a valid multiple name
if ( 'undefined' !== typeof name ) {
$ ( 'input[name="' + name + '"]' ) . each ( function ( i , input ) {
if ( $ ( input ) . is ( 'input[type=radio], input[type=checkbox]' ) ) $ ( input ) . attr ( _this12 . options . namespace + 'multiple' , _this12 . options . multiple ) ;
} ) ;
}
// Check here if we don't already have a related multiple instance saved
var $previouslyRelated = this . _findRelated ( ) ;
for ( var i = 0 ; i < $previouslyRelated . length ; i ++ ) {
parsleyMultipleInstance = $ ( $previouslyRelated . get ( i ) ) . data ( 'Parsley' ) ;
if ( 'undefined' !== typeof parsleyMultipleInstance ) {
if ( ! this . $element . data ( 'ParsleyFieldMultiple' ) ) {
parsleyMultipleInstance . addElement ( this . $element ) ;
}
break ;
}
}
// Create a secret ParsleyField instance for every multiple field. It will be stored in `data('ParsleyFieldMultiple')`
// And will be useful later to access classic `ParsleyField` stuff while being in a `ParsleyFieldMultiple` instance
this . bind ( 'parsleyField' , true ) ;
return parsleyMultipleInstance || this . bind ( 'parsleyFieldMultiple' ) ;
} ,
// Return proper `ParsleyForm`, `ParsleyField` or `ParsleyFieldMultiple`
bind : function bind ( type , doNotStore ) {
var parsleyInstance ;
switch ( type ) {
case 'parsleyForm' :
parsleyInstance = $ . extend ( new ParsleyForm ( this . $element , this . domOptions , this . options ) , new ParsleyAbstract ( ) , window . ParsleyExtend ) . _bindFields ( ) ;
break ;
case 'parsleyField' :
parsleyInstance = $ . extend ( new parsley _field ( this . $element , this . domOptions , this . options , this . parent ) , new ParsleyAbstract ( ) , window . ParsleyExtend ) ;
break ;
case 'parsleyFieldMultiple' :
parsleyInstance = $ . extend ( new parsley _field ( this . $element , this . domOptions , this . options , this . parent ) , new ParsleyMultiple ( ) , new ParsleyAbstract ( ) , window . ParsleyExtend ) . _init ( ) ;
break ;
default :
throw new Error ( type + 'is not a supported Parsley type' ) ;
}
if ( this . options . multiple ) ParsleyUtils _ _default . setAttr ( this . $element , this . options . namespace , 'multiple' , this . options . multiple ) ;
if ( 'undefined' !== typeof doNotStore ) {
this . $element . data ( 'ParsleyFieldMultiple' , parsleyInstance ) ;
return parsleyInstance ;
}
// Store the freshly bound instance in a DOM element for later access using jQuery `data()`
this . $element . data ( 'Parsley' , parsleyInstance ) ;
// Tell the world we have a new ParsleyForm or ParsleyField instance!
parsleyInstance . _actualizeTriggers ( ) ;
parsleyInstance . _trigger ( 'init' ) ;
return parsleyInstance ;
}
} ;
var vernums = $ . fn . jquery . split ( '.' ) ;
if ( parseInt ( vernums [ 0 ] ) <= 1 && parseInt ( vernums [ 1 ] ) < 8 ) {
throw "The loaded version of jQuery is too old. Please upgrade to 1.8.x or better." ;
}
if ( ! vernums . forEach ) {
ParsleyUtils _ _default . warn ( 'Parsley requires ES5 to run properly. Please include https://github.com/es-shims/es5-shim' ) ;
}
// Inherit `on`, `off` & `trigger` to Parsley:
var Parsley = $ . extend ( new ParsleyAbstract ( ) , {
$element : $ ( document ) ,
actualizeOptions : null ,
_resetOptions : null ,
Factory : ParsleyFactory ,
2016-05-04 15:40:49 +00:00
version : '2.3.11'
2016-04-24 14:26:11 +00:00
} ) ;
// Supplement ParsleyField and Form with ParsleyAbstract
// This way, the constructors will have access to those methods
$ . extend ( parsley _field . prototype , ParsleyUI . Field , ParsleyAbstract . prototype ) ;
$ . extend ( ParsleyForm . prototype , ParsleyUI . Form , ParsleyAbstract . prototype ) ;
// Inherit actualizeOptions and _resetOptions:
$ . extend ( ParsleyFactory . prototype , ParsleyAbstract . prototype ) ;
// ### jQuery API
// `$('.elem').parsley(options)` or `$('.elem').psly(options)`
$ . fn . parsley = $ . fn . psly = function ( options ) {
if ( this . length > 1 ) {
var instances = [ ] ;
this . each ( function ( ) {
instances . push ( $ ( this ) . parsley ( options ) ) ;
} ) ;
return instances ;
}
// Return undefined if applied to non existing DOM element
if ( ! $ ( this ) . length ) {
ParsleyUtils _ _default . warn ( 'You must bind Parsley on an existing element.' ) ;
return ;
}
return new ParsleyFactory ( this , options ) ;
} ;
// ### ParsleyField and ParsleyForm extension
// Ensure the extension is now defined if it wasn't previously
if ( 'undefined' === typeof window . ParsleyExtend ) window . ParsleyExtend = { } ;
// ### Parsley config
// Inherit from ParsleyDefault, and copy over any existing values
Parsley . options = $ . extend ( ParsleyUtils _ _default . objectCreate ( ParsleyDefaults ) , window . ParsleyConfig ) ;
window . ParsleyConfig = Parsley . options ; // Old way of accessing global options
// ### Globals
window . Parsley = window . psly = Parsley ;
window . ParsleyUtils = ParsleyUtils _ _default ;
// ### Define methods that forward to the registry, and deprecate all access except through window.Parsley
var registry = window . Parsley . _validatorRegistry = new ParsleyValidatorRegistry ( window . ParsleyConfig . validators , window . ParsleyConfig . i18n ) ;
window . ParsleyValidator = { } ;
$ . each ( 'setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator' . split ( ' ' ) , function ( i , method ) {
window . Parsley [ method ] = $ . proxy ( registry , method ) ;
window . ParsleyValidator [ method ] = function ( ) {
var _window$Parsley ;
ParsleyUtils _ _default . warnOnce ( 'Accessing the method \'' + method + '\' through ParsleyValidator is deprecated. Simply call \'window.Parsley.' + method + '(...)\'' ) ;
return ( _window$Parsley = window . Parsley ) [ method ] . apply ( _window$Parsley , arguments ) ;
} ;
} ) ;
// ### ParsleyUI
// Deprecated global object
window . Parsley . UI = ParsleyUI ;
window . ParsleyUI = {
removeError : function removeError ( instance , name , doNotUpdateClass ) {
var updateClass = true !== doNotUpdateClass ;
ParsleyUtils _ _default . warnOnce ( 'Accessing ParsleyUI is deprecated. Call \'removeError\' on the instance directly. Please comment in issue 1073 as to your need to call this method.' ) ;
return instance . removeError ( name , { updateClass : updateClass } ) ;
} ,
getErrorsMessages : function getErrorsMessages ( instance ) {
ParsleyUtils _ _default . warnOnce ( 'Accessing ParsleyUI is deprecated. Call \'getErrorsMessages\' on the instance directly.' ) ;
return instance . getErrorsMessages ( ) ;
}
} ;
$ . each ( 'addError updateError' . split ( ' ' ) , function ( i , method ) {
window . ParsleyUI [ method ] = function ( instance , name , message , assert , doNotUpdateClass ) {
var updateClass = true !== doNotUpdateClass ;
ParsleyUtils _ _default . warnOnce ( 'Accessing ParsleyUI is deprecated. Call \'' + method + '\' on the instance directly. Please comment in issue 1073 as to your need to call this method.' ) ;
return instance [ method ] ( name , { message : message , assert : assert , updateClass : updateClass } ) ;
} ;
} ) ;
// ### PARSLEY auto-binding
// Prevent it by setting `ParsleyConfig.autoBind` to `false`
if ( false !== window . ParsleyConfig . autoBind ) {
$ ( function ( ) {
// Works only on `data-parsley-validate`.
if ( $ ( '[data-parsley-validate]' ) . length ) $ ( '[data-parsley-validate]' ) . parsley ( ) ;
} ) ;
}
var o = $ ( { } ) ;
var deprecated = function deprecated ( ) {
ParsleyUtils _ _default . warnOnce ( "Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley" ) ;
} ;
// Returns an event handler that calls `fn` with the arguments it expects
function adapt ( fn , context ) {
// Store to allow unbinding
if ( ! fn . parsleyAdaptedCallback ) {
fn . parsleyAdaptedCallback = function ( ) {
var args = Array . prototype . slice . call ( arguments , 0 ) ;
args . unshift ( this ) ;
fn . apply ( context || o , args ) ;
} ;
}
return fn . parsleyAdaptedCallback ;
}
var eventPrefix = 'parsley:' ;
// Converts 'parsley:form:validate' into 'form:validate'
function eventName ( name ) {
if ( name . lastIndexOf ( eventPrefix , 0 ) === 0 ) return name . substr ( eventPrefix . length ) ;
return name ;
}
// $.listen is deprecated. Use Parsley.on instead.
$ . listen = function ( name , callback ) {
var context ;
deprecated ( ) ;
if ( 'object' === typeof arguments [ 1 ] && 'function' === typeof arguments [ 2 ] ) {
context = arguments [ 1 ] ;
callback = arguments [ 2 ] ;
}
if ( 'function' !== typeof callback ) throw new Error ( 'Wrong parameters' ) ;
window . Parsley . on ( eventName ( name ) , adapt ( callback , context ) ) ;
} ;
$ . listenTo = function ( instance , name , fn ) {
deprecated ( ) ;
if ( ! ( instance instanceof parsley _field ) && ! ( instance instanceof ParsleyForm ) ) throw new Error ( 'Must give Parsley instance' ) ;
if ( 'string' !== typeof name || 'function' !== typeof fn ) throw new Error ( 'Wrong parameters' ) ;
instance . on ( eventName ( name ) , adapt ( fn ) ) ;
} ;
$ . unsubscribe = function ( name , fn ) {
deprecated ( ) ;
if ( 'string' !== typeof name || 'function' !== typeof fn ) throw new Error ( 'Wrong arguments' ) ;
window . Parsley . off ( eventName ( name ) , fn . parsleyAdaptedCallback ) ;
} ;
$ . unsubscribeTo = function ( instance , name ) {
deprecated ( ) ;
if ( ! ( instance instanceof parsley _field ) && ! ( instance instanceof ParsleyForm ) ) throw new Error ( 'Must give Parsley instance' ) ;
instance . off ( eventName ( name ) ) ;
} ;
$ . unsubscribeAll = function ( name ) {
deprecated ( ) ;
window . Parsley . off ( eventName ( name ) ) ;
$ ( 'form,input,textarea,select' ) . each ( function ( ) {
var instance = $ ( this ) . data ( 'Parsley' ) ;
if ( instance ) {
instance . off ( eventName ( name ) ) ;
}
} ) ;
} ;
// $.emit is deprecated. Use jQuery events instead.
$ . emit = function ( name , instance ) {
var _instance ;
deprecated ( ) ;
var instanceGiven = instance instanceof parsley _field || instance instanceof ParsleyForm ;
var args = Array . prototype . slice . call ( arguments , instanceGiven ? 2 : 1 ) ;
args . unshift ( eventName ( name ) ) ;
if ( ! instanceGiven ) {
instance = window . Parsley ;
}
( _instance = instance ) . trigger . apply ( _instance , _toConsumableArray ( args ) ) ;
} ;
var pubsub = { } ;
$ . extend ( true , Parsley , {
asyncValidators : {
'default' : {
fn : function fn ( xhr ) {
// By default, only status 2xx are deemed successful.
// Note: we use status instead of state() because responses with status 200
// but invalid messages (e.g. an empty body for content type set to JSON) will
// result in state() === 'rejected'.
return xhr . status >= 200 && xhr . status < 300 ;
} ,
url : false
} ,
reverse : {
fn : function fn ( xhr ) {
// If reverse option is set, a failing ajax request is considered successful
return xhr . status < 200 || xhr . status >= 300 ;
} ,
url : false
}
} ,
addAsyncValidator : function addAsyncValidator ( name , fn , url , options ) {
Parsley . asyncValidators [ name ] = {
fn : fn ,
url : url || false ,
options : options || { }
} ;
return this ;
}
} ) ;
Parsley . addValidator ( 'remote' , {
requirementType : {
'' : 'string' ,
'validator' : 'string' ,
'reverse' : 'boolean' ,
'options' : 'object'
} ,
validateString : function validateString ( value , url , options , instance ) {
var data = { } ;
var ajaxOptions ;
var csr ;
var validator = options . validator || ( true === options . reverse ? 'reverse' : 'default' ) ;
if ( 'undefined' === typeof Parsley . asyncValidators [ validator ] ) throw new Error ( 'Calling an undefined async validator: `' + validator + '`' ) ;
url = Parsley . asyncValidators [ validator ] . url || url ;
// Fill current value
if ( url . indexOf ( '{value}' ) > - 1 ) {
url = url . replace ( '{value}' , encodeURIComponent ( value ) ) ;
} else {
data [ instance . $element . attr ( 'name' ) || instance . $element . attr ( 'id' ) ] = value ;
}
// Merge options passed in from the function with the ones in the attribute
var remoteOptions = $ . extend ( true , options . options || { } , Parsley . asyncValidators [ validator ] . options ) ;
// All `$.ajax(options)` could be overridden or extended directly from DOM in `data-parsley-remote-options`
ajaxOptions = $ . extend ( true , { } , {
url : url ,
data : data ,
type : 'GET'
} , remoteOptions ) ;
// Generate store key based on ajax options
instance . trigger ( 'field:ajaxoptions' , instance , ajaxOptions ) ;
csr = $ . param ( ajaxOptions ) ;
// Initialise querry cache
if ( 'undefined' === typeof Parsley . _remoteCache ) Parsley . _remoteCache = { } ;
// Try to retrieve stored xhr
var xhr = Parsley . _remoteCache [ csr ] = Parsley . _remoteCache [ csr ] || $ . ajax ( ajaxOptions ) ;
var handleXhr = function handleXhr ( ) {
var result = Parsley . asyncValidators [ validator ] . fn . call ( instance , xhr , url , options ) ;
if ( ! result ) // Map falsy results to rejected promise
result = $ . Deferred ( ) . reject ( ) ;
return $ . when ( result ) ;
} ;
return xhr . then ( handleXhr , handleXhr ) ;
} ,
priority : - 1
} ) ;
Parsley . on ( 'form:submit' , function ( ) {
Parsley . _remoteCache = { } ;
} ) ;
window . ParsleyExtend . addAsyncValidator = function ( ) {
ParsleyUtils . warnOnce ( 'Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`' ) ;
return Parsley . addAsyncValidator . apply ( Parsley , arguments ) ;
} ;
// This is included with the Parsley library itself,
// thus there is no use in adding it to your project.
Parsley . addMessages ( 'en' , {
defaultMessage : "This value seems to be invalid." ,
type : {
email : "This value should be a valid email." ,
url : "This value should be a valid url." ,
number : "This value should be a valid number." ,
integer : "This value should be a valid integer." ,
digits : "This value should be digits." ,
alphanum : "This value should be alphanumeric."
} ,
notblank : "This value should not be blank." ,
required : "This value is required." ,
pattern : "This value seems to be invalid." ,
min : "This value should be greater than or equal to %s." ,
max : "This value should be lower than or equal to %s." ,
range : "This value should be between %s and %s." ,
minlength : "This value is too short. It should have %s characters or more." ,
maxlength : "This value is too long. It should have %s characters or fewer." ,
length : "This value length is invalid. It should be between %s and %s characters long." ,
mincheck : "You must select at least %s choices." ,
maxcheck : "You must select %s choices or fewer." ,
check : "You must select between %s and %s choices." ,
equalto : "This value should be the same."
} ) ;
Parsley . setLocale ( 'en' ) ;
/ * *
* inputevent - Alleviate browser bugs for input events
* https : //github.com/marcandre/inputevent
* @ version v0 . 0.3 - ( built Thu , Apr 14 th 2016 , 5 : 58 pm )
* @ author Marc - Andre Lafortune < github @ marc - andre . ca >
* @ license MIT
* /
function InputEvent ( ) {
var _this13 = this ;
var globals = window || global ;
// Slightly odd way construct our object. This way methods are force bound.
// Used to test for duplicate library.
$ . extend ( this , {
// For browsers that do not support isTrusted, assumes event is native.
isNativeEvent : function isNativeEvent ( evt ) {
return evt . originalEvent && evt . originalEvent . isTrusted !== false ;
} ,
fakeInputEvent : function fakeInputEvent ( evt ) {
if ( _this13 . isNativeEvent ( evt ) ) {
$ ( evt . target ) . trigger ( 'input' ) ;
}
} ,
misbehaves : function misbehaves ( evt ) {
if ( _this13 . isNativeEvent ( evt ) ) {
_this13 . behavesOk ( evt ) ;
$ ( document ) . on ( 'change.inputevent' , evt . data . selector , _this13 . fakeInputEvent ) ;
_this13 . fakeInputEvent ( evt ) ;
}
} ,
behavesOk : function behavesOk ( evt ) {
if ( _this13 . isNativeEvent ( evt ) ) {
$ ( document ) // Simply unbinds the testing handler
. off ( 'input.inputevent' , evt . data . selector , _this13 . behavesOk ) . off ( 'change.inputevent' , evt . data . selector , _this13 . misbehaves ) ;
}
} ,
// Bind the testing handlers
install : function install ( ) {
if ( globals . inputEventPatched ) {
return ;
}
globals . inputEventPatched = '0.0.3' ;
var _arr = [ 'select' , 'input[type="checkbox"]' , 'input[type="radio"]' , 'input[type="file"]' ] ;
for ( var _i = 0 ; _i < _arr . length ; _i ++ ) {
var selector = _arr [ _i ] ;
$ ( document ) . on ( 'input.inputevent' , selector , { selector : selector } , _this13 . behavesOk ) . on ( 'change.inputevent' , selector , { selector : selector } , _this13 . misbehaves ) ;
}
} ,
uninstall : function uninstall ( ) {
delete globals . inputEventPatched ;
$ ( document ) . off ( '.inputevent' ) ;
}
} ) ;
} ;
var inputevent = new InputEvent ( ) ;
inputevent . install ( ) ;
var parsley = Parsley ;
return parsley ;
} ) ;
//# sourceMappingURL=parsley.js.map