parsley-rails 2.0.7.0 → 2.4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -5
- data/lib/parsley-rails/version.rb +1 -1
- data/parsley-rails.gemspec +2 -2
- data/update.sh +3 -4
- data/vendor/assets/javascripts/parsley.i18n.al.js +29 -0
- data/vendor/assets/javascripts/parsley.i18n.ar.js +4 -8
- data/vendor/assets/javascripts/parsley.i18n.bg.js +4 -8
- data/vendor/assets/javascripts/parsley.i18n.ca.js +29 -0
- data/vendor/assets/javascripts/parsley.i18n.cs.extra.js +3 -3
- data/vendor/assets/javascripts/parsley.i18n.cs.js +6 -10
- data/vendor/assets/javascripts/parsley.i18n.da.js +4 -9
- data/vendor/assets/javascripts/parsley.i18n.de.extra.js +3 -3
- data/vendor/assets/javascripts/parsley.i18n.de.js +7 -8
- data/vendor/assets/javascripts/parsley.i18n.el.extra.js +14 -0
- data/vendor/assets/javascripts/parsley.i18n.el.js +29 -0
- data/vendor/assets/javascripts/parsley.i18n.en.extra.js +5 -4
- data/vendor/assets/javascripts/parsley.i18n.en.js +5 -8
- data/vendor/assets/javascripts/parsley.i18n.es.js +4 -6
- data/vendor/assets/javascripts/parsley.i18n.eu.js +29 -0
- data/vendor/assets/javascripts/parsley.i18n.fa.js +9 -13
- data/vendor/assets/javascripts/parsley.i18n.fi.extra.js +3 -3
- data/vendor/assets/javascripts/parsley.i18n.fi.js +5 -9
- data/vendor/assets/javascripts/parsley.i18n.fr.extra.js +5 -4
- data/vendor/assets/javascripts/parsley.i18n.fr.js +4 -8
- data/vendor/assets/javascripts/parsley.i18n.he.extra.js +3 -3
- data/vendor/assets/javascripts/parsley.i18n.he.js +4 -8
- data/vendor/assets/javascripts/parsley.i18n.hr.extra.js +14 -0
- data/vendor/assets/javascripts/parsley.i18n.hr.js +29 -0
- data/vendor/assets/javascripts/parsley.i18n.hu.extra.js +14 -0
- data/vendor/assets/javascripts/parsley.i18n.hu.js +30 -0
- data/vendor/assets/javascripts/parsley.i18n.id.extra.js +3 -3
- data/vendor/assets/javascripts/parsley.i18n.id.js +4 -8
- data/vendor/assets/javascripts/parsley.i18n.it.extra.js +3 -3
- data/vendor/assets/javascripts/parsley.i18n.it.js +4 -8
- data/vendor/assets/javascripts/parsley.i18n.ja.js +4 -8
- data/vendor/assets/javascripts/parsley.i18n.ko.js +5 -9
- data/vendor/assets/javascripts/parsley.i18n.lt.js +29 -0
- data/vendor/assets/javascripts/parsley.i18n.lv.extra.js +14 -0
- data/vendor/assets/javascripts/parsley.i18n.lv.js +29 -0
- data/vendor/assets/javascripts/{parsley.i18n.ms_MY.extra.js → parsley.i18n.ms.extra.js} +4 -4
- data/vendor/assets/javascripts/{parsley.i18n.ms_MY.js → parsley.i18n.ms.js} +4 -8
- data/vendor/assets/javascripts/parsley.i18n.nl.extra.js +3 -3
- data/vendor/assets/javascripts/parsley.i18n.nl.js +4 -8
- data/vendor/assets/javascripts/parsley.i18n.no.js +29 -0
- data/vendor/assets/javascripts/parsley.i18n.pl.js +19 -23
- data/vendor/assets/javascripts/parsley.i18n.pt-br.js +4 -8
- data/vendor/assets/javascripts/parsley.i18n.pt-pt.js +29 -0
- data/vendor/assets/javascripts/parsley.i18n.ro.extra.js +14 -0
- data/vendor/assets/javascripts/parsley.i18n.ro.js +29 -0
- data/vendor/assets/javascripts/parsley.i18n.ru.extra.js +3 -3
- data/vendor/assets/javascripts/parsley.i18n.ru.js +4 -13
- data/vendor/assets/javascripts/parsley.i18n.sl.extra.js +14 -0
- data/vendor/assets/javascripts/parsley.i18n.sl.js +30 -0
- data/vendor/assets/javascripts/parsley.i18n.sq.js +29 -0
- data/vendor/assets/javascripts/parsley.i18n.sv.extra.js +3 -3
- data/vendor/assets/javascripts/parsley.i18n.sv.js +4 -8
- data/vendor/assets/javascripts/parsley.i18n.th.js +4 -8
- data/vendor/assets/javascripts/parsley.i18n.tr.js +22 -26
- data/vendor/assets/javascripts/parsley.i18n.uk.extra.js +9 -0
- data/vendor/assets/javascripts/parsley.i18n.uk.js +29 -0
- data/vendor/assets/javascripts/parsley.i18n.zh_cn.extra.js +3 -3
- data/vendor/assets/javascripts/parsley.i18n.zh_cn.js +4 -8
- data/vendor/assets/javascripts/parsley.i18n.zh_tw.js +16 -20
- data/vendor/assets/javascripts/parsley.js +1970 -1673
- data/vendor/assets/javascripts/parsley.min.js +18 -0
- metadata +27 -6
- data/vendor/assets/javascripts/parsley.remote.js +0 -2347
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
// Validation errors messages for Parsley
|
2
|
+
// Load this after Parsley
|
3
3
|
|
4
|
-
|
4
|
+
Parsley.addMessages('zh-cn', {
|
5
5
|
dateiso: "请输入正确格式的日期 (YYYY-MM-DD)."
|
6
6
|
});
|
@@ -1,9 +1,7 @@
|
|
1
|
-
//
|
2
|
-
|
3
|
-
window.ParsleyConfig.i18n = window.ParsleyConfig.i18n || {};
|
1
|
+
// Validation errors messages for Parsley
|
2
|
+
// Load this after Parsley
|
4
3
|
|
5
|
-
|
6
|
-
window.ParsleyConfig.i18n.zh_cn = $.extend(window.ParsleyConfig.i18n.zh_cn || {}, {
|
4
|
+
Parsley.addMessages('zh-cn', {
|
7
5
|
defaultMessage: "不正确的值",
|
8
6
|
type: {
|
9
7
|
email: "请输入一个有效的电子邮箱地址",
|
@@ -28,6 +26,4 @@ window.ParsleyConfig.i18n.zh_cn = $.extend(window.ParsleyConfig.i18n.zh_cn || {}
|
|
28
26
|
equalto: "输入值不同"
|
29
27
|
});
|
30
28
|
|
31
|
-
|
32
|
-
if ('undefined' !== typeof window.ParsleyValidator)
|
33
|
-
window.ParsleyValidator.addCatalog('zh_cn', window.ParsleyConfig.i18n.zh_cn, true);
|
29
|
+
Parsley.setLocale('zh-cn');
|
@@ -1,33 +1,29 @@
|
|
1
|
-
//
|
2
|
-
|
3
|
-
window.ParsleyConfig.i18n = window.ParsleyConfig.i18n || {};
|
1
|
+
// Validation errors messages for Parsley
|
2
|
+
// Load this after Parsley
|
4
3
|
|
5
|
-
|
6
|
-
window.ParsleyConfig.i18n.zh_tw = $.extend(window.ParsleyConfig.i18n.zh_tw || {}, {
|
4
|
+
Parsley.addMessages('zh-tw', {
|
7
5
|
defaultMessage: "這個值似乎是無效的。",
|
8
6
|
type: {
|
9
|
-
email: "
|
7
|
+
email: "請輸入一個正確的電子郵件地址。",
|
10
8
|
url: "請輸入一個有效的網址。",
|
11
|
-
number: "
|
12
|
-
integer: "
|
13
|
-
digits: "
|
14
|
-
alphanum: "
|
9
|
+
number: "請輸入一個數字。",
|
10
|
+
integer: "請輸入一個整數。",
|
11
|
+
digits: "這個欄位只接受數字。",
|
12
|
+
alphanum: "這個欄位只接受英文字母或是數字。"
|
15
13
|
},
|
16
|
-
notblank: "
|
17
|
-
required: "
|
14
|
+
notblank: "這個欄位不能為空白。",
|
15
|
+
required: "這個欄位必須填寫。",
|
18
16
|
pattern: "這個值似乎是無效的。",
|
19
17
|
min: "輸入的值應該大於或等於 %s",
|
20
18
|
max: "輸入的值應該小於或等於 %s",
|
21
|
-
range: "
|
22
|
-
minlength: "
|
23
|
-
maxlength: "
|
24
|
-
length: "字元長度應該在 %s 和 %s",
|
19
|
+
range: "輸入的值應該在 %s 和 %s 之間。",
|
20
|
+
minlength: "輸入的值至少要有 %s 個字元。",
|
21
|
+
maxlength: "輸入的值最多可以有 %s 個字元。",
|
22
|
+
length: "字元長度應該在 %s 和 %s 之間。",
|
25
23
|
mincheck: "你至少要選擇 %s 個項目。",
|
26
24
|
maxcheck: "你最多可選擇 %s 個項目。",
|
27
25
|
check: "你必須選擇 %s 到 %s 個項目。",
|
28
|
-
equalto: "
|
26
|
+
equalto: "輸入值不同。"
|
29
27
|
});
|
30
28
|
|
31
|
-
|
32
|
-
if ('undefined' !== typeof window.ParsleyValidator)
|
33
|
-
window.ParsleyValidator.addCatalog('zh_tw', window.ParsleyConfig.i18n.zh_tw, true);
|
29
|
+
Parsley.setLocale('zh-tw');
|
@@ -1,2083 +1,2380 @@
|
|
1
1
|
/*!
|
2
|
-
*
|
2
|
+
* Parsley.js
|
3
|
+
* Version 2.4.4 - built Thu, Aug 4th 2016, 9:54 pm
|
4
|
+
* http://parsleyjs.org
|
3
5
|
* Guillaume Potier - <guillaume@wisembly.com>
|
4
|
-
*
|
6
|
+
* Marc-Andre Lafortune - <petroselinum@marc-andre.ca>
|
5
7
|
* MIT Licensed
|
6
|
-
*
|
7
8
|
*/
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
var
|
9
|
+
|
10
|
+
// The source code below is generated by babel as
|
11
|
+
// Parsley is written in ECMAScript 6
|
12
|
+
//
|
13
|
+
var _slice = Array.prototype.slice;
|
14
|
+
|
15
|
+
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); } }
|
16
|
+
|
17
|
+
(function (global, factory) {
|
18
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) : typeof define === 'function' && define.amd ? define(['jquery'], factory) : global.parsley = factory(global.jQuery);
|
19
|
+
})(this, function ($) {
|
20
|
+
'use strict';
|
21
|
+
|
22
|
+
var globalID = 1;
|
23
|
+
var pastWarnings = {};
|
24
|
+
|
25
|
+
var ParsleyUtils__ParsleyUtils = {
|
22
26
|
// Parsley DOM-API
|
23
27
|
// returns object from dom attributes and values
|
24
|
-
|
25
|
-
|
26
|
-
var
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
attribute = $element[0].attributes[i];
|
35
|
-
if ('undefined' !== typeof attribute && null !== attribute && (!msie || msie >= 8 || attribute.specified) && regex.test(attribute.name)) {
|
36
|
-
if ('undefined' !== typeof checkAttr && new RegExp(checkAttr + '$', 'i').test(attribute.name))
|
37
|
-
return true;
|
38
|
-
obj[this.camelize(attribute.name.replace(namespace, ''))] = this.deserializeValue(attribute.value);
|
28
|
+
attr: function attr($element, namespace, obj) {
|
29
|
+
var i;
|
30
|
+
var attribute;
|
31
|
+
var attributes;
|
32
|
+
var regex = new RegExp('^' + namespace, 'i');
|
33
|
+
|
34
|
+
if ('undefined' === typeof obj) obj = {};else {
|
35
|
+
// Clear all own properties. This won't affect prototype's values
|
36
|
+
for (i in obj) {
|
37
|
+
if (obj.hasOwnProperty(i)) delete obj[i];
|
39
38
|
}
|
40
39
|
}
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
$element[0].
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
while (this.isObject(obj) || this.isArray(obj)) {
|
52
|
-
obj = obj[paths[i++]];
|
53
|
-
if (i === paths.length)
|
54
|
-
return obj;
|
40
|
+
|
41
|
+
if ('undefined' === typeof $element || 'undefined' === typeof $element[0]) return obj;
|
42
|
+
|
43
|
+
attributes = $element[0].attributes;
|
44
|
+
for (i = attributes.length; i--;) {
|
45
|
+
attribute = attributes[i];
|
46
|
+
|
47
|
+
if (attribute && attribute.specified && regex.test(attribute.name)) {
|
48
|
+
obj[this.camelize(attribute.name.slice(namespace.length))] = this.deserializeValue(attribute.value);
|
49
|
+
}
|
55
50
|
}
|
56
|
-
|
51
|
+
|
52
|
+
return obj;
|
57
53
|
},
|
58
|
-
|
59
|
-
|
54
|
+
|
55
|
+
checkAttr: function checkAttr($element, namespace, _checkAttr) {
|
56
|
+
return $element.is('[' + namespace + _checkAttr + ']');
|
60
57
|
},
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
return Object.prototype.toString.call(mixed) === '[object Array]';
|
58
|
+
|
59
|
+
setAttr: function setAttr($element, namespace, attr, value) {
|
60
|
+
$element[0].setAttribute(this.dasherize(namespace + attr), String(value));
|
65
61
|
},
|
66
|
-
|
67
|
-
|
68
|
-
return
|
62
|
+
|
63
|
+
generateID: function generateID() {
|
64
|
+
return '' + globalID++;
|
69
65
|
},
|
66
|
+
|
67
|
+
/** Third party functions **/
|
70
68
|
// Zepto deserialize function
|
71
|
-
deserializeValue: function (value) {
|
69
|
+
deserializeValue: function deserializeValue(value) {
|
72
70
|
var num;
|
71
|
+
|
73
72
|
try {
|
74
|
-
return value ?
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
!isNaN(num = Number(value)) ? num :
|
79
|
-
/^[\[\{]/.test(value) ? $.parseJSON(value) :
|
80
|
-
value)
|
81
|
-
: value;
|
82
|
-
} catch (e) { return value; }
|
73
|
+
return value ? value == "true" || (value == "false" ? false : value == "null" ? null : !isNaN(num = Number(value)) ? num : /^[\[\{]/.test(value) ? $.parseJSON(value) : value) : value;
|
74
|
+
} catch (e) {
|
75
|
+
return value;
|
76
|
+
}
|
83
77
|
},
|
78
|
+
|
84
79
|
// Zepto camelize function
|
85
|
-
camelize: function (str) {
|
86
|
-
return str.replace(/-+(.)?/g, function(match, chr) {
|
80
|
+
camelize: function camelize(str) {
|
81
|
+
return str.replace(/-+(.)?/g, function (match, chr) {
|
87
82
|
return chr ? chr.toUpperCase() : '';
|
88
83
|
});
|
89
84
|
},
|
85
|
+
|
90
86
|
// Zepto dasherize function
|
91
|
-
dasherize: function (str) {
|
92
|
-
return str.replace(/::/g, '/')
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
87
|
+
dasherize: function dasherize(str) {
|
88
|
+
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();
|
89
|
+
},
|
90
|
+
|
91
|
+
warn: function warn() {
|
92
|
+
var _window$console;
|
93
|
+
|
94
|
+
if (window.console && 'function' === typeof window.console.warn) (_window$console = window.console).warn.apply(_window$console, arguments);
|
95
|
+
},
|
96
|
+
|
97
|
+
warnOnce: function warnOnce(msg) {
|
98
|
+
if (!pastWarnings[msg]) {
|
99
|
+
pastWarnings[msg] = true;
|
100
|
+
this.warn.apply(this, arguments);
|
101
|
+
}
|
102
|
+
},
|
103
|
+
|
104
|
+
_resetWarnings: function _resetWarnings() {
|
105
|
+
pastWarnings = {};
|
106
|
+
},
|
107
|
+
|
108
|
+
trimString: function trimString(string) {
|
109
|
+
return string.replace(/^\s+|\s+$/g, '');
|
110
|
+
},
|
111
|
+
|
112
|
+
namespaceEvents: function namespaceEvents(events, namespace) {
|
113
|
+
events = this.trimString(events || '').split(/\s+/);
|
114
|
+
if (!events[0]) return '';
|
115
|
+
return $.map(events, function (evt) {
|
116
|
+
return evt + '.' + namespace;
|
117
|
+
}).join(' ');
|
118
|
+
},
|
119
|
+
|
120
|
+
difference: function difference(array, remove) {
|
121
|
+
// This is O(N^2), should be optimized
|
122
|
+
var result = [];
|
123
|
+
$.each(array, function (_, elem) {
|
124
|
+
if (remove.indexOf(elem) == -1) result.push(elem);
|
125
|
+
});
|
126
|
+
return result;
|
127
|
+
},
|
128
|
+
|
129
|
+
// Alter-ego to native Promise.all, but for jQuery
|
130
|
+
all: function all(promises) {
|
131
|
+
// jQuery treats $.when() and $.when(singlePromise) differently; let's avoid that and add spurious elements
|
132
|
+
return $.when.apply($, _toConsumableArray(promises).concat([42, 42]));
|
133
|
+
},
|
134
|
+
|
135
|
+
// Object.create polyfill, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill
|
136
|
+
objectCreate: Object.create || (function () {
|
137
|
+
var Object = function Object() {};
|
138
|
+
return function (prototype) {
|
139
|
+
if (arguments.length > 1) {
|
140
|
+
throw Error('Second argument not supported');
|
141
|
+
}
|
142
|
+
if (typeof prototype != 'object') {
|
143
|
+
throw TypeError('Argument must be an object');
|
144
|
+
}
|
145
|
+
Object.prototype = prototype;
|
146
|
+
var result = new Object();
|
147
|
+
Object.prototype = null;
|
148
|
+
return result;
|
149
|
+
};
|
150
|
+
})(),
|
151
|
+
|
152
|
+
_SubmitSelector: 'input[type="submit"], button:submit'
|
108
153
|
};
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
//
|
154
|
+
|
155
|
+
var ParsleyUtils__default = ParsleyUtils__ParsleyUtils;
|
156
|
+
|
157
|
+
// All these options could be overriden and specified directly in DOM using
|
158
|
+
// `data-parsley-` default DOM-API
|
159
|
+
// eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"`
|
160
|
+
// eg: `data-parsley-stop-on-first-failing-constraint="false"`
|
161
|
+
|
113
162
|
var ParsleyDefaults = {
|
114
163
|
// ### General
|
164
|
+
|
115
165
|
// Default data-namespace for DOM API
|
116
166
|
namespace: 'data-parsley-',
|
167
|
+
|
117
168
|
// Supported inputs by default
|
118
169
|
inputs: 'input, textarea, select',
|
170
|
+
|
119
171
|
// Excluded inputs by default
|
120
172
|
excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden]',
|
173
|
+
|
121
174
|
// Stop validating field on highest priority failing constraint
|
122
175
|
priorityEnabled: true,
|
176
|
+
|
177
|
+
// ### Field only
|
178
|
+
|
179
|
+
// identifier used to group together inputs (e.g. radio buttons...)
|
180
|
+
multiple: null,
|
181
|
+
|
182
|
+
// identifier (or array of identifiers) used to validate only a select group of inputs
|
183
|
+
group: null,
|
184
|
+
|
123
185
|
// ### UI
|
124
186
|
// Enable\Disable error messages
|
125
187
|
uiEnabled: true,
|
188
|
+
|
126
189
|
// Key events threshold before validation
|
127
190
|
validationThreshold: 3,
|
128
|
-
|
191
|
+
|
192
|
+
// Focused field on form validation error. 'first'|'last'|'none'
|
129
193
|
focus: 'first',
|
130
|
-
|
194
|
+
|
195
|
+
// event(s) that will trigger validation before first failure. eg: `input`...
|
131
196
|
trigger: false,
|
197
|
+
|
198
|
+
// event(s) that will trigger validation after first failure.
|
199
|
+
triggerAfterFailure: 'input',
|
200
|
+
|
132
201
|
// Class that would be added on every failing validation Parsley field
|
133
202
|
errorClass: 'parsley-error',
|
203
|
+
|
134
204
|
// Same for success validation
|
135
205
|
successClass: 'parsley-success',
|
206
|
+
|
136
207
|
// Return the `$element` that will receive these above success or error classes
|
137
208
|
// Could also be (and given directly from DOM) a valid selector like `'#div'`
|
138
|
-
classHandler: function (ParsleyField) {},
|
209
|
+
classHandler: function classHandler(ParsleyField) {},
|
210
|
+
|
139
211
|
// Return the `$element` where errors will be appended
|
140
212
|
// Could also be (and given directly from DOM) a valid selector like `'#div'`
|
141
|
-
errorsContainer: function (ParsleyField) {},
|
213
|
+
errorsContainer: function errorsContainer(ParsleyField) {},
|
214
|
+
|
142
215
|
// ul elem that would receive errors' list
|
143
216
|
errorsWrapper: '<ul class="parsley-errors-list"></ul>',
|
217
|
+
|
144
218
|
// li elem that would receive error message
|
145
219
|
errorTemplate: '<li></li>'
|
146
220
|
};
|
147
221
|
|
148
|
-
var ParsleyAbstract = function() {
|
222
|
+
var ParsleyAbstract = function ParsleyAbstract() {
|
223
|
+
this.__id__ = ParsleyUtils__default.generateID();
|
224
|
+
};
|
225
|
+
|
149
226
|
ParsleyAbstract.prototype = {
|
150
|
-
asyncSupport:
|
151
|
-
|
152
|
-
|
227
|
+
asyncSupport: true, // Deprecated
|
228
|
+
|
229
|
+
_pipeAccordingToValidationResult: function _pipeAccordingToValidationResult() {
|
230
|
+
var _this = this;
|
231
|
+
|
232
|
+
var pipe = function pipe() {
|
233
|
+
var r = $.Deferred();
|
234
|
+
if (true !== _this.validationResult) r.reject();
|
235
|
+
return r.resolve().promise();
|
236
|
+
};
|
237
|
+
return [pipe, pipe];
|
238
|
+
},
|
239
|
+
|
240
|
+
actualizeOptions: function actualizeOptions() {
|
241
|
+
ParsleyUtils__default.attr(this.$element, this.options.namespace, this.domOptions);
|
242
|
+
if (this.parent && this.parent.actualizeOptions) this.parent.actualizeOptions();
|
153
243
|
return this;
|
154
244
|
},
|
155
|
-
|
156
|
-
|
157
|
-
|
245
|
+
|
246
|
+
_resetOptions: function _resetOptions(initOptions) {
|
247
|
+
this.domOptions = ParsleyUtils__default.objectCreate(this.parent.options);
|
248
|
+
this.options = ParsleyUtils__default.objectCreate(this.domOptions);
|
249
|
+
// Shallow copy of ownProperties of initOptions:
|
250
|
+
for (var i in initOptions) {
|
251
|
+
if (initOptions.hasOwnProperty(i)) this.options[i] = initOptions[i];
|
252
|
+
}
|
253
|
+
this.actualizeOptions();
|
254
|
+
},
|
255
|
+
|
256
|
+
_listeners: null,
|
257
|
+
|
258
|
+
// Register a callback for the given event name
|
259
|
+
// Callback is called with context as the first argument and the `this`
|
260
|
+
// The context is the current parsley instance, or window.Parsley if global
|
261
|
+
// A return value of `false` will interrupt the calls
|
262
|
+
on: function on(name, fn) {
|
263
|
+
this._listeners = this._listeners || {};
|
264
|
+
var queue = this._listeners[name] = this._listeners[name] || [];
|
265
|
+
queue.push(fn);
|
266
|
+
|
267
|
+
return this;
|
158
268
|
},
|
159
|
-
|
160
|
-
//
|
161
|
-
|
162
|
-
subscribe: function (name, fn) {
|
269
|
+
|
270
|
+
// Deprecated. Use `on` instead
|
271
|
+
subscribe: function subscribe(name, fn) {
|
163
272
|
$.listenTo(this, name.toLowerCase(), fn);
|
273
|
+
},
|
274
|
+
|
275
|
+
// Unregister a callback (or all if none is given) for the given event name
|
276
|
+
off: function off(name, fn) {
|
277
|
+
var queue = this._listeners && this._listeners[name];
|
278
|
+
if (queue) {
|
279
|
+
if (!fn) {
|
280
|
+
delete this._listeners[name];
|
281
|
+
} else {
|
282
|
+
for (var i = queue.length; i--;) if (queue[i] === fn) queue.splice(i, 1);
|
283
|
+
}
|
284
|
+
}
|
164
285
|
return this;
|
165
286
|
},
|
166
|
-
|
167
|
-
|
287
|
+
|
288
|
+
// Deprecated. Use `off`
|
289
|
+
unsubscribe: function unsubscribe(name, fn) {
|
168
290
|
$.unsubscribeTo(this, name.toLowerCase());
|
169
|
-
return this;
|
170
291
|
},
|
292
|
+
|
293
|
+
// Trigger an event of the given name
|
294
|
+
// A return value of `false` interrupts the callback chain
|
295
|
+
// Returns false if execution was interrupted
|
296
|
+
trigger: function trigger(name, target, extraArg) {
|
297
|
+
target = target || this;
|
298
|
+
var queue = this._listeners && this._listeners[name];
|
299
|
+
var result;
|
300
|
+
var parentResult;
|
301
|
+
if (queue) {
|
302
|
+
for (var i = queue.length; i--;) {
|
303
|
+
result = queue[i].call(target, target, extraArg);
|
304
|
+
if (result === false) return result;
|
305
|
+
}
|
306
|
+
}
|
307
|
+
if (this.parent) {
|
308
|
+
return this.parent.trigger(name, target, extraArg);
|
309
|
+
}
|
310
|
+
return true;
|
311
|
+
},
|
312
|
+
|
171
313
|
// Reset UI
|
172
|
-
reset: function () {
|
314
|
+
reset: function reset() {
|
173
315
|
// Field case: just emit a reset event for UI
|
174
|
-
if ('ParsleyForm' !== this.__class__)
|
175
|
-
|
316
|
+
if ('ParsleyForm' !== this.__class__) {
|
317
|
+
this._resetUI();
|
318
|
+
return this._trigger('reset');
|
319
|
+
}
|
320
|
+
|
176
321
|
// Form case: emit a reset event for each field
|
177
|
-
for (var i = 0; i < this.fields.length; i++)
|
178
|
-
|
179
|
-
|
322
|
+
for (var i = 0; i < this.fields.length; i++) this.fields[i].reset();
|
323
|
+
|
324
|
+
this._trigger('reset');
|
180
325
|
},
|
326
|
+
|
181
327
|
// Destroy Parsley instance (+ UI)
|
182
|
-
destroy: function () {
|
328
|
+
destroy: function destroy() {
|
183
329
|
// Field case: emit destroy event to clean UI and then destroy stored instance
|
330
|
+
this._destroyUI();
|
184
331
|
if ('ParsleyForm' !== this.__class__) {
|
185
332
|
this.$element.removeData('Parsley');
|
186
333
|
this.$element.removeData('ParsleyFieldMultiple');
|
187
|
-
|
334
|
+
this._trigger('destroy');
|
335
|
+
|
188
336
|
return;
|
189
337
|
}
|
338
|
+
|
190
339
|
// Form case: destroy all its fields and then destroy stored instance
|
191
|
-
for (var i = 0; i < this.fields.length; i++)
|
192
|
-
|
340
|
+
for (var i = 0; i < this.fields.length; i++) this.fields[i].destroy();
|
341
|
+
|
193
342
|
this.$element.removeData('Parsley');
|
194
|
-
|
343
|
+
this._trigger('destroy');
|
344
|
+
},
|
345
|
+
|
346
|
+
asyncIsValid: function asyncIsValid(group, force) {
|
347
|
+
ParsleyUtils__default.warnOnce("asyncIsValid is deprecated; please use whenValid instead");
|
348
|
+
return this.whenValid({ group: group, force: force });
|
349
|
+
},
|
350
|
+
|
351
|
+
_findRelated: function _findRelated() {
|
352
|
+
return this.options.multiple ? this.parent.$element.find('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]') : this.$element;
|
195
353
|
}
|
196
354
|
};
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
* MIT Licensed
|
202
|
-
*
|
203
|
-
*/
|
204
|
-
var Validator = ( function ( ) {
|
205
|
-
var exports = {};
|
206
|
-
/**
|
207
|
-
* Validator
|
208
|
-
*/
|
209
|
-
var Validator = function ( options ) {
|
210
|
-
this.__class__ = 'Validator';
|
211
|
-
this.__version__ = '1.0.1';
|
212
|
-
this.options = options || {};
|
213
|
-
this.bindingKey = this.options.bindingKey || '_validatorjsConstraint';
|
214
|
-
};
|
215
|
-
Validator.prototype = {
|
216
|
-
constructor: Validator,
|
217
|
-
/*
|
218
|
-
* Validate string: validate( string, Assert, string ) || validate( string, [ Assert, Assert ], [ string, string ] )
|
219
|
-
* Validate object: validate( object, Constraint, string ) || validate( object, Constraint, [ string, string ] )
|
220
|
-
* Validate binded object: validate( object, string ) || validate( object, [ string, string ] )
|
221
|
-
*/
|
222
|
-
validate: function ( objectOrString, AssertsOrConstraintOrGroup, group ) {
|
223
|
-
if ( 'string' !== typeof objectOrString && 'object' !== typeof objectOrString )
|
224
|
-
throw new Error( 'You must validate an object or a string' );
|
225
|
-
// string / array validation
|
226
|
-
if ( 'string' === typeof objectOrString || _isArray(objectOrString) )
|
227
|
-
return this._validateString( objectOrString, AssertsOrConstraintOrGroup, group );
|
228
|
-
// binded object validation
|
229
|
-
if ( this.isBinded( objectOrString ) )
|
230
|
-
return this._validateBindedObject( objectOrString, AssertsOrConstraintOrGroup );
|
231
|
-
// regular object validation
|
232
|
-
return this._validateObject( objectOrString, AssertsOrConstraintOrGroup, group );
|
233
|
-
},
|
234
|
-
bind: function ( object, constraint ) {
|
235
|
-
if ( 'object' !== typeof object )
|
236
|
-
throw new Error( 'Must bind a Constraint to an object' );
|
237
|
-
object[ this.bindingKey ] = new Constraint( constraint );
|
238
|
-
return this;
|
355
|
+
|
356
|
+
var requirementConverters = {
|
357
|
+
string: function string(_string) {
|
358
|
+
return _string;
|
239
359
|
},
|
240
|
-
|
241
|
-
if ( '
|
242
|
-
|
243
|
-
delete object[ this.bindingKey ];
|
244
|
-
return this;
|
360
|
+
integer: function integer(string) {
|
361
|
+
if (isNaN(string)) throw 'Requirement is not an integer: "' + string + '"';
|
362
|
+
return parseInt(string, 10);
|
245
363
|
},
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
assert = [ assert ];
|
256
|
-
for ( var i = 0; i < assert.length; i++ ) {
|
257
|
-
if ( ! ( assert[ i ] instanceof Assert) )
|
258
|
-
throw new Error( 'You must give an Assert or an Asserts array to validate a string' );
|
259
|
-
result = assert[ i ].check( string, group );
|
260
|
-
if ( result instanceof Violation )
|
261
|
-
failures.push( result );
|
262
|
-
}
|
263
|
-
return failures.length ? failures : true;
|
364
|
+
number: function number(string) {
|
365
|
+
if (isNaN(string)) throw 'Requirement is not a number: "' + string + '"';
|
366
|
+
return parseFloat(string);
|
367
|
+
},
|
368
|
+
reference: function reference(string) {
|
369
|
+
// Unused for now
|
370
|
+
var result = $(string);
|
371
|
+
if (result.length === 0) throw 'No such reference: "' + string + '"';
|
372
|
+
return result;
|
264
373
|
},
|
265
|
-
|
266
|
-
|
267
|
-
throw new Error( 'You must give a constraint to validate an object' );
|
268
|
-
if ( constraint instanceof Constraint )
|
269
|
-
return constraint.check( object, group );
|
270
|
-
return new Constraint( constraint ).check( object, group );
|
374
|
+
boolean: function boolean(string) {
|
375
|
+
return string !== 'false';
|
271
376
|
},
|
272
|
-
|
273
|
-
return
|
377
|
+
object: function object(string) {
|
378
|
+
return ParsleyUtils__default.deserializeValue(string);
|
379
|
+
},
|
380
|
+
regexp: function regexp(_regexp) {
|
381
|
+
var flags = '';
|
382
|
+
|
383
|
+
// Test if RegExp is literal, if not, nothing to be done, otherwise, we need to isolate flags and pattern
|
384
|
+
if (/^\/.*\/(?:[gimy]*)$/.test(_regexp)) {
|
385
|
+
// Replace the regexp literal string with the first match group: ([gimy]*)
|
386
|
+
// If no flag is present, this will be a blank string
|
387
|
+
flags = _regexp.replace(/.*\/([gimy]*)$/, '$1');
|
388
|
+
// Again, replace the regexp literal string with the first match group:
|
389
|
+
// everything excluding the opening and closing slashes and the flags
|
390
|
+
_regexp = _regexp.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');
|
391
|
+
} else {
|
392
|
+
// Anchor regexp:
|
393
|
+
_regexp = '^' + _regexp + '$';
|
394
|
+
}
|
395
|
+
return new RegExp(_regexp, flags);
|
274
396
|
}
|
275
397
|
};
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
398
|
+
|
399
|
+
var convertArrayRequirement = function convertArrayRequirement(string, length) {
|
400
|
+
var m = string.match(/^\s*\[(.*)\]\s*$/);
|
401
|
+
if (!m) throw 'Requirement is not an array: "' + string + '"';
|
402
|
+
var values = m[1].split(',').map(ParsleyUtils__default.trimString);
|
403
|
+
if (values.length !== length) throw 'Requirement has ' + values.length + ' values when ' + length + ' are needed';
|
404
|
+
return values;
|
281
405
|
};
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
406
|
+
|
407
|
+
var convertRequirement = function convertRequirement(requirementType, string) {
|
408
|
+
var converter = requirementConverters[requirementType || 'string'];
|
409
|
+
if (!converter) throw 'Unknown requirement specification: "' + requirementType + '"';
|
410
|
+
return converter(string);
|
411
|
+
};
|
412
|
+
|
413
|
+
var convertExtraOptionRequirement = function convertExtraOptionRequirement(requirementSpec, string, extraOptionReader) {
|
414
|
+
var main = null;
|
415
|
+
var extra = {};
|
416
|
+
for (var key in requirementSpec) {
|
417
|
+
if (key) {
|
418
|
+
var value = extraOptionReader(key);
|
419
|
+
if ('string' === typeof value) value = convertRequirement(requirementSpec[key], value);
|
420
|
+
extra[key] = value;
|
421
|
+
} else {
|
422
|
+
main = convertRequirement(requirementSpec[key], string);
|
294
423
|
}
|
295
424
|
}
|
425
|
+
return [main, extra];
|
296
426
|
};
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
427
|
+
|
428
|
+
// A Validator needs to implement the methods `validate` and `parseRequirements`
|
429
|
+
|
430
|
+
var ParsleyValidator = function ParsleyValidator(spec) {
|
431
|
+
$.extend(true, this, spec);
|
432
|
+
};
|
433
|
+
|
434
|
+
ParsleyValidator.prototype = {
|
435
|
+
// Returns `true` iff the given `value` is valid according the given requirements.
|
436
|
+
validate: function validate(value, requirementFirstArg) {
|
437
|
+
if (this.fn) {
|
438
|
+
// Legacy style validator
|
439
|
+
|
440
|
+
if (arguments.length > 3) // If more args then value, requirement, instance...
|
441
|
+
requirementFirstArg = [].slice.call(arguments, 1, -1); // Skip first arg (value) and last (instance), combining the rest
|
442
|
+
return this.fn.call(this, value, requirementFirstArg);
|
443
|
+
}
|
444
|
+
|
445
|
+
if ($.isArray(value)) {
|
446
|
+
if (!this.validateMultiple) throw 'Validator `' + this.name + '` does not handle multiple values';
|
447
|
+
return this.validateMultiple.apply(this, arguments);
|
448
|
+
} else {
|
449
|
+
if (this.validateNumber) {
|
450
|
+
if (isNaN(value)) return false;
|
451
|
+
arguments[0] = parseFloat(arguments[0]);
|
452
|
+
return this.validateNumber.apply(this, arguments);
|
314
453
|
}
|
315
|
-
|
316
|
-
|
317
|
-
// we trigger here a HaveProperty Assert violation to have uniform Violation object in the end
|
318
|
-
new Assert().HaveProperty( property ).validate( object );
|
319
|
-
}
|
320
|
-
result = this._check( property, object[ property ], group );
|
321
|
-
// check returned an array of Violations or an object mapping Violations
|
322
|
-
if ( ( _isArray( result ) && result.length > 0 ) || ( !_isArray( result ) && !_isEmptyObject( result ) ) ) {
|
323
|
-
failures[ property ] = result;
|
324
|
-
}
|
325
|
-
} catch ( violation ) {
|
326
|
-
failures[ property ] = violation;
|
454
|
+
if (this.validateString) {
|
455
|
+
return this.validateString.apply(this, arguments);
|
327
456
|
}
|
457
|
+
throw 'Validator `' + this.name + '` only handles multiple values';
|
328
458
|
}
|
329
|
-
return _isEmptyObject(failures) ? true : failures;
|
330
459
|
},
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
460
|
+
|
461
|
+
// Parses `requirements` into an array of arguments,
|
462
|
+
// according to `this.requirementType`
|
463
|
+
parseRequirements: function parseRequirements(requirements, extraOptionReader) {
|
464
|
+
if ('string' !== typeof requirements) {
|
465
|
+
// Assume requirement already parsed
|
466
|
+
// but make sure we return an array
|
467
|
+
return $.isArray(requirements) ? requirements : [requirements];
|
335
468
|
}
|
336
|
-
|
337
|
-
|
338
|
-
|
469
|
+
var type = this.requirementType;
|
470
|
+
if ($.isArray(type)) {
|
471
|
+
var values = convertArrayRequirement(requirements, type.length);
|
472
|
+
for (var i = 0; i < values.length; i++) values[i] = convertRequirement(type[i], values[i]);
|
473
|
+
return values;
|
474
|
+
} else if ($.isPlainObject(type)) {
|
475
|
+
return convertExtraOptionRequirement(type, requirements, extraOptionReader);
|
476
|
+
} else {
|
477
|
+
return [convertRequirement(type, requirements)];
|
339
478
|
}
|
340
|
-
throw new Error( 'Should give an Assert, an Asserts array, a Constraint', object );
|
341
|
-
},
|
342
|
-
has: function ( node, nodes ) {
|
343
|
-
nodes = 'undefined' !== typeof nodes ? nodes : this.nodes;
|
344
|
-
return 'undefined' !== typeof nodes[ node ];
|
345
479
|
},
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
for ( var i in this.nodes )
|
352
|
-
if ( i !== node )
|
353
|
-
_nodes[ i ] = this.nodes[ i ];
|
354
|
-
this.nodes = _nodes;
|
355
|
-
return this;
|
356
|
-
},
|
357
|
-
_bootstrap: function ( data ) {
|
358
|
-
if ( data instanceof Constraint )
|
359
|
-
return this.nodes = data.nodes;
|
360
|
-
for ( var node in data )
|
361
|
-
this.add( node, data[ node ] );
|
362
|
-
},
|
363
|
-
_check: function ( node, value, group ) {
|
364
|
-
// Assert
|
365
|
-
if ( this.nodes[ node ] instanceof Assert )
|
366
|
-
return this._checkAsserts( value, [ this.nodes[ node ] ], group );
|
367
|
-
// Asserts
|
368
|
-
if ( _isArray( this.nodes[ node ] ) )
|
369
|
-
return this._checkAsserts( value, this.nodes[ node ], group );
|
370
|
-
// Constraint -> check api
|
371
|
-
if ( this.nodes[ node ] instanceof Constraint )
|
372
|
-
return this.nodes[ node ].check( value, group );
|
373
|
-
throw new Error( 'Invalid node', this.nodes[ node ] );
|
374
|
-
},
|
375
|
-
_checkAsserts: function ( value, asserts, group ) {
|
376
|
-
var result, failures = [];
|
377
|
-
for ( var i = 0; i < asserts.length; i++ ) {
|
378
|
-
result = asserts[ i ].check( value, group );
|
379
|
-
if ( 'undefined' !== typeof result && true !== result )
|
380
|
-
failures.push( result );
|
381
|
-
// Some asserts (Collection for example) could return an object
|
382
|
-
// if ( result && ! ( result instanceof Violation ) )
|
383
|
-
// return result;
|
384
|
-
//
|
385
|
-
// // Vast assert majority return Violation
|
386
|
-
// if ( result instanceof Violation )
|
387
|
-
// failures.push( result );
|
388
|
-
}
|
389
|
-
return failures;
|
390
|
-
}
|
480
|
+
// Defaults:
|
481
|
+
requirementType: 'string',
|
482
|
+
|
483
|
+
priority: 2
|
484
|
+
|
391
485
|
};
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
this.
|
400
|
-
this.value = value;
|
401
|
-
if ( 'undefined' !== typeof violation )
|
402
|
-
this.violation = violation;
|
486
|
+
|
487
|
+
var ParsleyValidatorRegistry = function ParsleyValidatorRegistry(validators, catalog) {
|
488
|
+
this.__class__ = 'ParsleyValidatorRegistry';
|
489
|
+
|
490
|
+
// Default Parsley locale is en
|
491
|
+
this.locale = 'en';
|
492
|
+
|
493
|
+
this.init(validators || {}, catalog || {});
|
403
494
|
};
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
}
|
495
|
+
|
496
|
+
var typeRegexes = {
|
497
|
+
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,
|
498
|
+
|
499
|
+
// Follow https://www.w3.org/TR/html5/infrastructure.html#floating-point-numbers
|
500
|
+
number: /^-?(\d*\.)?\d+(e[-+]?\d+)?$/i,
|
501
|
+
|
502
|
+
integer: /^-?\d+$/,
|
503
|
+
|
504
|
+
digits: /^\d+$/,
|
505
|
+
|
506
|
+
alphanum: /^\w+$/i,
|
507
|
+
|
508
|
+
url: new RegExp("^" +
|
509
|
+
// protocol identifier
|
510
|
+
"(?:(?:https?|ftp)://)?" + // ** mod: make scheme optional
|
511
|
+
// user:pass authentication
|
512
|
+
"(?:\\S+(?::\\S*)?@)?" + "(?:" +
|
513
|
+
// IP address exclusion
|
514
|
+
// private & local networks
|
515
|
+
// "(?!(?:10|127)(?:\\.\\d{1,3}){3})" + // ** mod: allow local networks
|
516
|
+
// "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" + // ** mod: allow local networks
|
517
|
+
// "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" + // ** mod: allow local networks
|
518
|
+
// IP address dotted notation octets
|
519
|
+
// excludes loopback network 0.0.0.0
|
520
|
+
// excludes reserved space >= 224.0.0.0
|
521
|
+
// excludes network & broacast addresses
|
522
|
+
// (first & last IP address of each class)
|
523
|
+
"(?:[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]))" + "|" +
|
524
|
+
// host name
|
525
|
+
'(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)' +
|
526
|
+
// domain name
|
527
|
+
'(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*' +
|
528
|
+
// TLD identifier
|
529
|
+
'(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))' + ")" +
|
530
|
+
// port number
|
531
|
+
"(?::\\d{2,5})?" +
|
532
|
+
// resource path
|
533
|
+
"(?:/\\S*)?" + "$", 'i')
|
425
534
|
};
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
var
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
535
|
+
typeRegexes.range = typeRegexes.number;
|
536
|
+
|
537
|
+
// See http://stackoverflow.com/a/10454560/8279
|
538
|
+
var decimalPlaces = function decimalPlaces(num) {
|
539
|
+
var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
|
540
|
+
if (!match) {
|
541
|
+
return 0;
|
542
|
+
}
|
543
|
+
return Math.max(0,
|
544
|
+
// Number of digits right of decimal point.
|
545
|
+
(match[1] ? match[1].length : 0) - (
|
546
|
+
// Adjust for scientific notation.
|
547
|
+
match[2] ? +match[2] : 0));
|
435
548
|
};
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
if ( !this.requiresValidation( group ) )
|
447
|
-
return;
|
448
|
-
try {
|
449
|
-
return this.validate( value, group );
|
450
|
-
} catch ( violation ) {
|
451
|
-
return violation;
|
452
|
-
}
|
453
|
-
},
|
454
|
-
hasGroup: function ( group ) {
|
455
|
-
if ( _isArray( group ) )
|
456
|
-
return this.hasOneOf( group );
|
457
|
-
// All Asserts respond to "Any" group
|
458
|
-
if ( 'Any' === group )
|
459
|
-
return true;
|
460
|
-
// Asserts with no group also respond to "Default" group. Else return false
|
461
|
-
if ( !this.hasGroups() )
|
462
|
-
return 'Default' === group;
|
463
|
-
return -1 !== this.groups.indexOf( group );
|
464
|
-
},
|
465
|
-
hasOneOf: function ( groups ) {
|
466
|
-
for ( var i = 0; i < groups.length; i++ )
|
467
|
-
if ( this.hasGroup( groups[ i ] ) )
|
468
|
-
return true;
|
469
|
-
return false;
|
470
|
-
},
|
471
|
-
hasGroups: function () {
|
472
|
-
return this.groups.length > 0;
|
473
|
-
},
|
474
|
-
addGroup: function ( group ) {
|
475
|
-
if ( _isArray( group ) )
|
476
|
-
return this.addGroups( group );
|
477
|
-
if ( !this.hasGroup( group ) )
|
478
|
-
this.groups.push( group );
|
479
|
-
return this;
|
549
|
+
|
550
|
+
ParsleyValidatorRegistry.prototype = {
|
551
|
+
init: function init(validators, catalog) {
|
552
|
+
this.catalog = catalog;
|
553
|
+
// Copy prototype's validators:
|
554
|
+
this.validators = $.extend({}, this.validators);
|
555
|
+
|
556
|
+
for (var name in validators) this.addValidator(name, validators[name].fn, validators[name].priority);
|
557
|
+
|
558
|
+
window.Parsley.trigger('parsley:validator:init');
|
480
559
|
},
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
this.
|
560
|
+
|
561
|
+
// Set new messages locale if we have dictionary loaded in ParsleyConfig.i18n
|
562
|
+
setLocale: function setLocale(locale) {
|
563
|
+
if ('undefined' === typeof this.catalog[locale]) throw new Error(locale + ' is not available in the catalog');
|
564
|
+
|
565
|
+
this.locale = locale;
|
566
|
+
|
487
567
|
return this;
|
488
568
|
},
|
489
|
-
|
490
|
-
|
491
|
-
|
569
|
+
|
570
|
+
// Add a new messages catalog for a given locale. Set locale for this catalog if set === `true`
|
571
|
+
addCatalog: function addCatalog(locale, messages, set) {
|
572
|
+
if ('object' === typeof messages) this.catalog[locale] = messages;
|
573
|
+
|
574
|
+
if (true === set) return this.setLocale(locale);
|
575
|
+
|
492
576
|
return this;
|
493
577
|
},
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
this.
|
500
|
-
|
501
|
-
if ( 'undefined' === typeof object[ this.node ] )
|
502
|
-
throw new Violation( this, object, { value: this.node } );
|
503
|
-
return true;
|
504
|
-
};
|
578
|
+
|
579
|
+
// Add a specific message for a given constraint in a given locale
|
580
|
+
addMessage: function addMessage(locale, name, message) {
|
581
|
+
if ('undefined' === typeof this.catalog[locale]) this.catalog[locale] = {};
|
582
|
+
|
583
|
+
this.catalog[locale][name] = message;
|
584
|
+
|
505
585
|
return this;
|
506
586
|
},
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
if ( '' !== value.replace( /^\s+/g, '' ).replace( /\s+$/g, '' ) )
|
513
|
-
throw new Violation( this, value );
|
514
|
-
return true;
|
515
|
-
};
|
587
|
+
|
588
|
+
// Add messages for a given locale
|
589
|
+
addMessages: function addMessages(locale, nameMessageObject) {
|
590
|
+
for (var name in nameMessageObject) this.addMessage(locale, name, nameMessageObject[name]);
|
591
|
+
|
516
592
|
return this;
|
517
593
|
},
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
594
|
+
|
595
|
+
// Add a new validator
|
596
|
+
//
|
597
|
+
// addValidator('custom', {
|
598
|
+
// requirementType: ['integer', 'integer'],
|
599
|
+
// validateString: function(value, from, to) {},
|
600
|
+
// priority: 22,
|
601
|
+
// messages: {
|
602
|
+
// en: "Hey, that's no good",
|
603
|
+
// fr: "Aye aye, pas bon du tout",
|
604
|
+
// }
|
605
|
+
// })
|
606
|
+
//
|
607
|
+
// Old API was addValidator(name, function, priority)
|
608
|
+
//
|
609
|
+
addValidator: function addValidator(name, arg1, arg2) {
|
610
|
+
if (this.validators[name]) ParsleyUtils__default.warn('Validator "' + name + '" is already defined.');else if (ParsleyDefaults.hasOwnProperty(name)) {
|
611
|
+
ParsleyUtils__default.warn('"' + name + '" is a restricted keyword and is not a valid validator name.');
|
612
|
+
return;
|
613
|
+
}
|
614
|
+
return this._setValidator.apply(this, arguments);
|
535
615
|
},
|
536
|
-
|
537
|
-
|
538
|
-
if (
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
for ( var i = 0; i < list.length; i++ )
|
544
|
-
if ( value === list[ i ] )
|
545
|
-
return true;
|
546
|
-
throw new Violation( this, value, { choices: list } );
|
547
|
-
};
|
548
|
-
return this;
|
616
|
+
|
617
|
+
updateValidator: function updateValidator(name, arg1, arg2) {
|
618
|
+
if (!this.validators[name]) {
|
619
|
+
ParsleyUtils__default.warn('Validator "' + name + '" is not already defined.');
|
620
|
+
return this.addValidator.apply(this, arguments);
|
621
|
+
}
|
622
|
+
return this._setValidator.apply(this, arguments);
|
549
623
|
},
|
550
|
-
|
551
|
-
|
552
|
-
this.
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
throw new Violation( this, collection, { value: Validator.errorCode.must_be_an_array } );
|
557
|
-
for ( var i = 0; i < collection.length; i++ ) {
|
558
|
-
result = this.constraint ?
|
559
|
-
validator.validate( collection[ i ], this.constraint, groups ) :
|
560
|
-
validator.validate( collection[ i ], groups );
|
561
|
-
if ( !_isEmptyObject( result ) )
|
562
|
-
failures[ count ] = result;
|
563
|
-
count++;
|
564
|
-
}
|
565
|
-
return !_isEmptyObject( failures ) ? failures : true;
|
566
|
-
};
|
624
|
+
|
625
|
+
removeValidator: function removeValidator(name) {
|
626
|
+
if (!this.validators[name]) ParsleyUtils__default.warn('Validator "' + name + '" is not defined.');
|
627
|
+
|
628
|
+
delete this.validators[name];
|
629
|
+
|
567
630
|
return this;
|
568
631
|
},
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
632
|
+
|
633
|
+
_setValidator: function _setValidator(name, validator, priority) {
|
634
|
+
if ('object' !== typeof validator) {
|
635
|
+
// Old style validator, with `fn` and `priority`
|
636
|
+
validator = {
|
637
|
+
fn: validator,
|
638
|
+
priority: priority
|
639
|
+
};
|
640
|
+
}
|
641
|
+
if (!validator.validate) {
|
642
|
+
validator = new ParsleyValidator(validator);
|
643
|
+
}
|
644
|
+
this.validators[name] = validator;
|
645
|
+
|
646
|
+
for (var locale in validator.messages || {}) this.addMessage(locale, name, validator.messages[locale]);
|
647
|
+
|
582
648
|
return this;
|
583
649
|
},
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
return this;
|
650
|
+
|
651
|
+
getErrorMessage: function getErrorMessage(constraint) {
|
652
|
+
var message;
|
653
|
+
|
654
|
+
// Type constraints are a bit different, we have to match their requirements too to find right error message
|
655
|
+
if ('type' === constraint.name) {
|
656
|
+
var typeMessages = this.catalog[this.locale][constraint.name] || {};
|
657
|
+
message = typeMessages[constraint.requirements];
|
658
|
+
} else message = this.formatMessage(this.catalog[this.locale][constraint.name], constraint.requirements);
|
659
|
+
|
660
|
+
return message || this.catalog[this.locale].defaultMessage || this.catalog.en.defaultMessage;
|
595
661
|
},
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
};
|
607
|
-
return this;
|
662
|
+
|
663
|
+
// Kind of light `sprintf()` implementation
|
664
|
+
formatMessage: function formatMessage(string, parameters) {
|
665
|
+
if ('object' === typeof parameters) {
|
666
|
+
for (var i in parameters) string = this.formatMessage(string, parameters[i]);
|
667
|
+
|
668
|
+
return string;
|
669
|
+
}
|
670
|
+
|
671
|
+
return 'string' === typeof string ? string.replace(/%s/i, parameters) : '';
|
608
672
|
},
|
609
|
-
GreaterThan: function ( threshold ) {
|
610
|
-
this.__class__ = 'GreaterThan';
|
611
|
-
if ( 'undefined' === typeof threshold )
|
612
|
-
throw new Error( 'Should give a threshold value' );
|
613
|
-
this.threshold = threshold;
|
614
|
-
this.validate = function ( value ) {
|
615
|
-
if ( '' === value || isNaN( Number( value ) ) )
|
616
|
-
throw new Violation( this, value, { value: Validator.errorCode.must_be_a_number } );
|
617
|
-
if ( this.threshold >= value )
|
618
|
-
throw new Violation( this, value, { threshold: this.threshold } );
|
619
|
-
return true;
|
620
|
-
};
|
621
|
-
return this;
|
622
|
-
},
|
623
|
-
GreaterThanOrEqual: function ( threshold ) {
|
624
|
-
this.__class__ = 'GreaterThanOrEqual';
|
625
|
-
if ( 'undefined' === typeof threshold )
|
626
|
-
throw new Error( 'Should give a threshold value' );
|
627
|
-
this.threshold = threshold;
|
628
|
-
this.validate = function ( value ) {
|
629
|
-
if ( '' === value || isNaN( Number( value ) ) )
|
630
|
-
throw new Violation( this, value, { value: Validator.errorCode.must_be_a_number } );
|
631
|
-
if ( this.threshold > value )
|
632
|
-
throw new Violation( this, value, { threshold: this.threshold } );
|
633
|
-
return true;
|
634
|
-
};
|
635
|
-
return this;
|
636
|
-
},
|
637
|
-
InstanceOf: function ( classRef ) {
|
638
|
-
this.__class__ = 'InstanceOf';
|
639
|
-
if ( 'undefined' === typeof classRef )
|
640
|
-
throw new Error( 'InstanceOf must be instanciated with a value' );
|
641
|
-
this.classRef = classRef;
|
642
|
-
this.validate = function ( value ) {
|
643
|
-
if ( true !== (value instanceof this.classRef) )
|
644
|
-
throw new Violation( this, value, { classRef: this.classRef } );
|
645
|
-
return true;
|
646
|
-
};
|
647
|
-
return this;
|
648
|
-
},
|
649
|
-
Length: function ( boundaries ) {
|
650
|
-
this.__class__ = 'Length';
|
651
|
-
if ( !boundaries.min && !boundaries.max )
|
652
|
-
throw new Error( 'Lenth assert must be instanciated with a { min: x, max: y } object' );
|
653
|
-
this.min = boundaries.min;
|
654
|
-
this.max = boundaries.max;
|
655
|
-
this.validate = function ( value ) {
|
656
|
-
if ( 'string' !== typeof value && !_isArray( value ) )
|
657
|
-
throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string_or_array } );
|
658
|
-
if ( 'undefined' !== typeof this.min && this.min === this.max && value.length !== this.min )
|
659
|
-
throw new Violation( this, value, { min: this.min, max: this.max } );
|
660
|
-
if ( 'undefined' !== typeof this.max && value.length > this.max )
|
661
|
-
throw new Violation( this, value, { max: this.max } );
|
662
|
-
if ( 'undefined' !== typeof this.min && value.length < this.min )
|
663
|
-
throw new Violation( this, value, { min: this.min } );
|
664
|
-
return true;
|
665
|
-
};
|
666
|
-
return this;
|
667
|
-
},
|
668
|
-
LessThan: function ( threshold ) {
|
669
|
-
this.__class__ = 'LessThan';
|
670
|
-
if ( 'undefined' === typeof threshold )
|
671
|
-
throw new Error( 'Should give a threshold value' );
|
672
|
-
this.threshold = threshold;
|
673
|
-
this.validate = function ( value ) {
|
674
|
-
if ( '' === value || isNaN( Number( value ) ) )
|
675
|
-
throw new Violation( this, value, { value: Validator.errorCode.must_be_a_number } );
|
676
|
-
if ( this.threshold <= value )
|
677
|
-
throw new Violation( this, value, { threshold: this.threshold } );
|
678
|
-
return true;
|
679
|
-
};
|
680
|
-
return this;
|
681
|
-
},
|
682
|
-
LessThanOrEqual: function ( threshold ) {
|
683
|
-
this.__class__ = 'LessThanOrEqual';
|
684
|
-
if ( 'undefined' === typeof threshold )
|
685
|
-
throw new Error( 'Should give a threshold value' );
|
686
|
-
this.threshold = threshold;
|
687
|
-
this.validate = function ( value ) {
|
688
|
-
if ( '' === value || isNaN( Number( value ) ) )
|
689
|
-
throw new Violation( this, value, { value: Validator.errorCode.must_be_a_number } );
|
690
|
-
if ( this.threshold < value )
|
691
|
-
throw new Violation( this, value, { threshold: this.threshold } );
|
692
|
-
return true;
|
693
|
-
};
|
694
|
-
return this;
|
695
|
-
},
|
696
|
-
NotNull: function () {
|
697
|
-
this.__class__ = 'NotNull';
|
698
|
-
this.validate = function ( value ) {
|
699
|
-
if ( null === value || 'undefined' === typeof value )
|
700
|
-
throw new Violation( this, value );
|
701
|
-
return true;
|
702
|
-
};
|
703
|
-
return this;
|
704
|
-
},
|
705
|
-
NotBlank: function () {
|
706
|
-
this.__class__ = 'NotBlank';
|
707
|
-
this.validate = function ( value ) {
|
708
|
-
if ( 'string' !== typeof value )
|
709
|
-
throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string } );
|
710
|
-
if ( '' === value.replace( /^\s+/g, '' ).replace( /\s+$/g, '' ) )
|
711
|
-
throw new Violation( this, value );
|
712
|
-
return true;
|
713
|
-
};
|
714
|
-
return this;
|
715
|
-
},
|
716
|
-
Null: function () {
|
717
|
-
this.__class__ = 'Null';
|
718
|
-
this.validate = function ( value ) {
|
719
|
-
if ( null !== value )
|
720
|
-
throw new Violation( this, value );
|
721
|
-
return true;
|
722
|
-
};
|
723
|
-
return this;
|
724
|
-
},
|
725
|
-
Range: function ( min, max ) {
|
726
|
-
this.__class__ = 'Range';
|
727
|
-
if ( 'undefined' === typeof min || 'undefined' === typeof max )
|
728
|
-
throw new Error( 'Range assert expects min and max values' );
|
729
|
-
this.min = min;
|
730
|
-
this.max = max;
|
731
|
-
this.validate = function ( value ) {
|
732
|
-
try {
|
733
|
-
// validate strings and objects with their Length
|
734
|
-
if ( ( 'string' === typeof value && isNaN( Number( value ) ) ) || _isArray( value ) )
|
735
|
-
new Assert().Length( { min: this.min, max: this.max } ).validate( value );
|
736
|
-
// validate numbers with their value
|
737
|
-
else
|
738
|
-
new Assert().GreaterThanOrEqual( this.min ).validate( value ) && new Assert().LessThanOrEqual( this.max ).validate( value );
|
739
|
-
return true;
|
740
|
-
} catch ( violation ) {
|
741
|
-
throw new Violation( this, value, violation.violation );
|
742
|
-
}
|
743
|
-
return true;
|
744
|
-
};
|
745
|
-
return this;
|
746
|
-
},
|
747
|
-
Regexp: function ( regexp, flag ) {
|
748
|
-
this.__class__ = 'Regexp';
|
749
|
-
if ( 'undefined' === typeof regexp )
|
750
|
-
throw new Error( 'You must give a regexp' );
|
751
|
-
this.regexp = regexp;
|
752
|
-
this.flag = flag || '';
|
753
|
-
this.validate = function ( value ) {
|
754
|
-
if ( 'string' !== typeof value )
|
755
|
-
throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string } );
|
756
|
-
if ( !new RegExp( this.regexp, this.flag ).test( value ) )
|
757
|
-
throw new Violation( this, value, { regexp: this.regexp, flag: this.flag } );
|
758
|
-
return true;
|
759
|
-
};
|
760
|
-
return this;
|
761
|
-
},
|
762
|
-
Required: function () {
|
763
|
-
this.__class__ = 'Required';
|
764
|
-
this.validate = function ( value ) {
|
765
|
-
if ( 'undefined' === typeof value )
|
766
|
-
throw new Violation( this, value );
|
767
|
-
try {
|
768
|
-
if ( 'string' === typeof value )
|
769
|
-
new Assert().NotNull().validate( value ) && new Assert().NotBlank().validate( value );
|
770
|
-
else if ( true === _isArray( value ) )
|
771
|
-
new Assert().Length( { min: 1 } ).validate( value );
|
772
|
-
} catch ( violation ) {
|
773
|
-
throw new Violation( this, value );
|
774
|
-
}
|
775
|
-
return true;
|
776
|
-
};
|
777
|
-
return this;
|
778
|
-
},
|
779
|
-
// Unique() or Unique ( { key: foo } )
|
780
|
-
Unique: function ( object ) {
|
781
|
-
this.__class__ = 'Unique';
|
782
|
-
if ( 'object' === typeof object )
|
783
|
-
this.key = object.key;
|
784
|
-
this.validate = function ( array ) {
|
785
|
-
var value, store = [];
|
786
|
-
if ( !_isArray( array ) )
|
787
|
-
throw new Violation( this, array, { value: Validator.errorCode.must_be_an_array } );
|
788
|
-
for ( var i = 0; i < array.length; i++ ) {
|
789
|
-
value = 'object' === typeof array[ i ] ? array[ i ][ this.key ] : array[ i ];
|
790
|
-
if ( 'undefined' === typeof value )
|
791
|
-
continue;
|
792
|
-
if ( -1 !== store.indexOf( value ) )
|
793
|
-
throw new Violation( this, array, { value: value } );
|
794
|
-
store.push( value );
|
795
|
-
}
|
796
|
-
return true;
|
797
|
-
};
|
798
|
-
return this;
|
799
|
-
}
|
800
|
-
};
|
801
|
-
// expose to the world these awesome classes
|
802
|
-
exports.Assert = Assert;
|
803
|
-
exports.Validator = Validator;
|
804
|
-
exports.Violation = Violation;
|
805
|
-
exports.Constraint = Constraint;
|
806
|
-
/**
|
807
|
-
* Some useful object prototypes / functions here
|
808
|
-
*/
|
809
|
-
// IE8<= compatibility
|
810
|
-
// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf
|
811
|
-
if (!Array.prototype.indexOf)
|
812
|
-
Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
|
813
|
-
|
814
|
-
if (this === null) {
|
815
|
-
throw new TypeError();
|
816
|
-
}
|
817
|
-
var t = Object(this);
|
818
|
-
var len = t.length >>> 0;
|
819
|
-
if (len === 0) {
|
820
|
-
return -1;
|
821
|
-
}
|
822
|
-
var n = 0;
|
823
|
-
if (arguments.length > 1) {
|
824
|
-
n = Number(arguments[1]);
|
825
|
-
if (n != n) { // shortcut for verifying if it's NaN
|
826
|
-
n = 0;
|
827
|
-
} else if (n !== 0 && n != Infinity && n != -Infinity) {
|
828
|
-
n = (n > 0 || -1) * Math.floor(Math.abs(n));
|
829
|
-
}
|
830
|
-
}
|
831
|
-
if (n >= len) {
|
832
|
-
return -1;
|
833
|
-
}
|
834
|
-
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
|
835
|
-
for (; k < len; k++) {
|
836
|
-
if (k in t && t[k] === searchElement) {
|
837
|
-
return k;
|
838
|
-
}
|
839
|
-
}
|
840
|
-
return -1;
|
841
|
-
};
|
842
|
-
// Test if object is empty, useful for Constraint violations check
|
843
|
-
var _isEmptyObject = function ( obj ) {
|
844
|
-
for ( var property in obj )
|
845
|
-
return false;
|
846
|
-
return true;
|
847
|
-
};
|
848
|
-
var _isArray = function ( obj ) {
|
849
|
-
return Object.prototype.toString.call( obj ) === '[object Array]';
|
850
|
-
};
|
851
|
-
// AMD export
|
852
|
-
if ( typeof define === 'function' && define.amd ) {
|
853
|
-
define( 'vendors/validator.js/dist/validator',[],function() {
|
854
|
-
return exports;
|
855
|
-
} );
|
856
|
-
// commonjs export
|
857
|
-
} else if ( typeof module !== 'undefined' && module.exports ) {
|
858
|
-
module.exports = exports;
|
859
|
-
// browser
|
860
|
-
} else {
|
861
|
-
window[ 'undefined' !== typeof validatorjs_ns ? validatorjs_ns : 'Validator' ] = exports;
|
862
|
-
}
|
863
673
|
|
864
|
-
return exports;
|
865
|
-
} )( );
|
866
|
-
|
867
|
-
// This is needed for Browserify usage that requires Validator.js through module.exports
|
868
|
-
Validator = 'undefined' !== typeof Validator ? Validator : ('undefined' !== typeof module ? module.exports : null);
|
869
|
-
var ParsleyValidator = function (validators, catalog) {
|
870
|
-
this.__class__ = 'ParsleyValidator';
|
871
|
-
this.Validator = Validator;
|
872
|
-
// Default Parsley locale is en
|
873
|
-
this.locale = 'en';
|
874
|
-
this.init(validators || {}, catalog || {});
|
875
|
-
};
|
876
|
-
ParsleyValidator.prototype = {
|
877
|
-
init: function (validators, catalog) {
|
878
|
-
this.catalog = catalog;
|
879
|
-
for (var name in validators)
|
880
|
-
this.addValidator(name, validators[name].fn, validators[name].priority, validators[name].requirementsTransformer);
|
881
|
-
$.emit('parsley:validator:init');
|
882
|
-
},
|
883
|
-
// Set new messages locale if we have dictionary loaded in ParsleyConfig.i18n
|
884
|
-
setLocale: function (locale) {
|
885
|
-
if ('undefined' === typeof this.catalog[locale])
|
886
|
-
throw new Error(locale + ' is not available in the catalog');
|
887
|
-
this.locale = locale;
|
888
|
-
return this;
|
889
|
-
},
|
890
|
-
// Add a new messages catalog for a given locale. Set locale for this catalog if set === `true`
|
891
|
-
addCatalog: function (locale, messages, set) {
|
892
|
-
if ('object' === typeof messages)
|
893
|
-
this.catalog[locale] = messages;
|
894
|
-
if (true === set)
|
895
|
-
return this.setLocale(locale);
|
896
|
-
return this;
|
897
|
-
},
|
898
|
-
// Add a specific message for a given constraint in a given locale
|
899
|
-
addMessage: function (locale, name, message) {
|
900
|
-
if ('undefined' === typeof this.catalog[locale])
|
901
|
-
this.catalog[locale] = {};
|
902
|
-
this.catalog[locale][name.toLowerCase()] = message;
|
903
|
-
return this;
|
904
|
-
},
|
905
|
-
validate: function (value, constraints, priority) {
|
906
|
-
return new this.Validator.Validator().validate.apply(new Validator.Validator(), arguments);
|
907
|
-
},
|
908
|
-
// Add a new validator
|
909
|
-
addValidator: function (name, fn, priority, requirementsTransformer) {
|
910
|
-
this.validators[name.toLowerCase()] = function (requirements) {
|
911
|
-
return $.extend(new Validator.Assert().Callback(fn, requirements), {
|
912
|
-
priority: priority,
|
913
|
-
requirementsTransformer: requirementsTransformer
|
914
|
-
});
|
915
|
-
};
|
916
|
-
return this;
|
917
|
-
},
|
918
|
-
updateValidator: function (name, fn, priority, requirementsTransformer) {
|
919
|
-
return this.addValidator(name, fn, priority, requirementsTransformer);
|
920
|
-
},
|
921
|
-
removeValidator: function (name) {
|
922
|
-
delete this.validators[name];
|
923
|
-
return this;
|
924
|
-
},
|
925
|
-
getErrorMessage: function (constraint) {
|
926
|
-
var message;
|
927
|
-
// Type constraints are a bit different, we have to match their requirements too to find right error message
|
928
|
-
if ('type' === constraint.name)
|
929
|
-
message = this.catalog[this.locale][constraint.name][constraint.requirements];
|
930
|
-
else
|
931
|
-
message = this.formatMessage(this.catalog[this.locale][constraint.name], constraint.requirements);
|
932
|
-
return '' !== message ? message : this.catalog[this.locale].defaultMessage;
|
933
|
-
},
|
934
|
-
// Kind of light `sprintf()` implementation
|
935
|
-
formatMessage: function (string, parameters) {
|
936
|
-
if ('object' === typeof parameters) {
|
937
|
-
for (var i in parameters)
|
938
|
-
string = this.formatMessage(string, parameters[i]);
|
939
|
-
return string;
|
940
|
-
}
|
941
|
-
return 'string' === typeof string ? string.replace(new RegExp('%s', 'i'), parameters) : '';
|
942
|
-
},
|
943
674
|
// Here is the Parsley default validators list.
|
944
|
-
//
|
945
|
-
//
|
675
|
+
// A validator is an object with the following key values:
|
676
|
+
// - priority: an integer
|
677
|
+
// - requirement: 'string' (default), 'integer', 'number', 'regexp' or an Array of these
|
678
|
+
// - validateString, validateMultiple, validateNumber: functions returning `true`, `false` or a promise
|
679
|
+
// Alternatively, a validator can be a function that returns such an object
|
680
|
+
//
|
946
681
|
validators: {
|
947
|
-
notblank:
|
948
|
-
|
682
|
+
notblank: {
|
683
|
+
validateString: function validateString(value) {
|
684
|
+
return (/\S/.test(value)
|
685
|
+
);
|
686
|
+
},
|
687
|
+
priority: 2
|
949
688
|
},
|
950
|
-
required:
|
951
|
-
|
689
|
+
required: {
|
690
|
+
validateMultiple: function validateMultiple(values) {
|
691
|
+
return values.length > 0;
|
692
|
+
},
|
693
|
+
validateString: function validateString(value) {
|
694
|
+
return (/\S/.test(value)
|
695
|
+
);
|
696
|
+
},
|
697
|
+
priority: 512
|
952
698
|
},
|
953
|
-
type:
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
case 'integer':
|
965
|
-
assert = new Validator.Assert().Regexp('^-?\\d+$');
|
966
|
-
break;
|
967
|
-
case 'digits':
|
968
|
-
assert = new Validator.Assert().Regexp('^\\d+$');
|
969
|
-
break;
|
970
|
-
case 'alphanum':
|
971
|
-
assert = new Validator.Assert().Regexp('^\\w+$', 'i');
|
972
|
-
break;
|
973
|
-
case 'url':
|
974
|
-
assert = new Validator.Assert().Regexp('(https?:\\/\\/)?(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,24}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)', 'i');
|
975
|
-
break;
|
976
|
-
default:
|
699
|
+
type: {
|
700
|
+
validateString: function validateString(value, type) {
|
701
|
+
var _ref = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
|
702
|
+
|
703
|
+
var _ref$step = _ref.step;
|
704
|
+
var step = _ref$step === undefined ? '1' : _ref$step;
|
705
|
+
var _ref$base = _ref.base;
|
706
|
+
var base = _ref$base === undefined ? 0 : _ref$base;
|
707
|
+
|
708
|
+
var regex = typeRegexes[type];
|
709
|
+
if (!regex) {
|
977
710
|
throw new Error('validator type `' + type + '` is not supported');
|
978
|
-
|
979
|
-
|
711
|
+
}
|
712
|
+
if (!regex.test(value)) return false;
|
713
|
+
if ('number' === type) {
|
714
|
+
if (!/^any$/i.test(step || '')) {
|
715
|
+
var nb = Number(value);
|
716
|
+
var decimals = Math.max(decimalPlaces(step), decimalPlaces(base));
|
717
|
+
if (decimalPlaces(nb) > decimals) // Value can't have too many decimals
|
718
|
+
return false;
|
719
|
+
// Be careful of rounding errors by using integers.
|
720
|
+
var toInt = function toInt(f) {
|
721
|
+
return Math.round(f * Math.pow(10, decimals));
|
722
|
+
};
|
723
|
+
if ((toInt(nb) - toInt(base)) % toInt(step) != 0) return false;
|
724
|
+
}
|
725
|
+
}
|
726
|
+
return true;
|
727
|
+
},
|
728
|
+
requirementType: {
|
729
|
+
'': 'string',
|
730
|
+
step: 'string',
|
731
|
+
base: 'number'
|
732
|
+
},
|
733
|
+
priority: 256
|
980
734
|
},
|
981
|
-
pattern:
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
flags = regexp.replace(/.*\/([gimy]*)$/, '$1');
|
988
|
-
// Again, replace the regexp literal string with the first match group:
|
989
|
-
// everything excluding the opening and closing slashes and the flags
|
990
|
-
regexp = regexp.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');
|
991
|
-
}
|
992
|
-
return $.extend(new Validator.Assert().Regexp(regexp, flags), { priority: 64 });
|
735
|
+
pattern: {
|
736
|
+
validateString: function validateString(value, regexp) {
|
737
|
+
return regexp.test(value);
|
738
|
+
},
|
739
|
+
requirementType: 'regexp',
|
740
|
+
priority: 64
|
993
741
|
},
|
994
|
-
minlength:
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
});
|
742
|
+
minlength: {
|
743
|
+
validateString: function validateString(value, requirement) {
|
744
|
+
return value.length >= requirement;
|
745
|
+
},
|
746
|
+
requirementType: 'integer',
|
747
|
+
priority: 30
|
1001
748
|
},
|
1002
|
-
maxlength:
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
});
|
749
|
+
maxlength: {
|
750
|
+
validateString: function validateString(value, requirement) {
|
751
|
+
return value.length <= requirement;
|
752
|
+
},
|
753
|
+
requirementType: 'integer',
|
754
|
+
priority: 30
|
1009
755
|
},
|
1010
|
-
length:
|
1011
|
-
|
756
|
+
length: {
|
757
|
+
validateString: function validateString(value, min, max) {
|
758
|
+
return value.length >= min && value.length <= max;
|
759
|
+
},
|
760
|
+
requirementType: ['integer', 'integer'],
|
761
|
+
priority: 30
|
1012
762
|
},
|
1013
|
-
mincheck:
|
1014
|
-
|
763
|
+
mincheck: {
|
764
|
+
validateMultiple: function validateMultiple(values, requirement) {
|
765
|
+
return values.length >= requirement;
|
766
|
+
},
|
767
|
+
requirementType: 'integer',
|
768
|
+
priority: 30
|
1015
769
|
},
|
1016
|
-
maxcheck:
|
1017
|
-
|
770
|
+
maxcheck: {
|
771
|
+
validateMultiple: function validateMultiple(values, requirement) {
|
772
|
+
return values.length <= requirement;
|
773
|
+
},
|
774
|
+
requirementType: 'integer',
|
775
|
+
priority: 30
|
1018
776
|
},
|
1019
|
-
check:
|
1020
|
-
|
777
|
+
check: {
|
778
|
+
validateMultiple: function validateMultiple(values, min, max) {
|
779
|
+
return values.length >= min && values.length <= max;
|
780
|
+
},
|
781
|
+
requirementType: ['integer', 'integer'],
|
782
|
+
priority: 30
|
1021
783
|
},
|
1022
|
-
min:
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
});
|
784
|
+
min: {
|
785
|
+
validateNumber: function validateNumber(value, requirement) {
|
786
|
+
return value >= requirement;
|
787
|
+
},
|
788
|
+
requirementType: 'number',
|
789
|
+
priority: 30
|
1029
790
|
},
|
1030
|
-
max:
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
});
|
791
|
+
max: {
|
792
|
+
validateNumber: function validateNumber(value, requirement) {
|
793
|
+
return value <= requirement;
|
794
|
+
},
|
795
|
+
requirementType: 'number',
|
796
|
+
priority: 30
|
1037
797
|
},
|
1038
|
-
range:
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
return array;
|
1045
|
-
}
|
1046
|
-
});
|
798
|
+
range: {
|
799
|
+
validateNumber: function validateNumber(value, min, max) {
|
800
|
+
return value >= min && value <= max;
|
801
|
+
},
|
802
|
+
requirementType: ['number', 'number'],
|
803
|
+
priority: 30
|
1047
804
|
},
|
1048
|
-
equalto:
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
});
|
805
|
+
equalto: {
|
806
|
+
validateString: function validateString(value, refOrValue) {
|
807
|
+
var $reference = $(refOrValue);
|
808
|
+
if ($reference.length) return value === $reference.val();else return value === refOrValue;
|
809
|
+
},
|
810
|
+
priority: 256
|
1055
811
|
}
|
1056
812
|
}
|
1057
813
|
};
|
1058
814
|
|
1059
|
-
var ParsleyUI =
|
1060
|
-
|
815
|
+
var ParsleyUI = {};
|
816
|
+
|
817
|
+
var diffResults = function diffResults(newResult, oldResult, deep) {
|
818
|
+
var added = [];
|
819
|
+
var kept = [];
|
820
|
+
|
821
|
+
for (var i = 0; i < newResult.length; i++) {
|
822
|
+
var found = false;
|
823
|
+
|
824
|
+
for (var j = 0; j < oldResult.length; j++) if (newResult[i].assert.name === oldResult[j].assert.name) {
|
825
|
+
found = true;
|
826
|
+
break;
|
827
|
+
}
|
828
|
+
|
829
|
+
if (found) kept.push(newResult[i]);else added.push(newResult[i]);
|
830
|
+
}
|
831
|
+
|
832
|
+
return {
|
833
|
+
kept: kept,
|
834
|
+
added: added,
|
835
|
+
removed: !deep ? diffResults(oldResult, newResult, true).added : []
|
836
|
+
};
|
1061
837
|
};
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
838
|
+
|
839
|
+
ParsleyUI.Form = {
|
840
|
+
|
841
|
+
_actualizeTriggers: function _actualizeTriggers() {
|
842
|
+
var _this2 = this;
|
843
|
+
|
844
|
+
this.$element.on('submit.Parsley', function (evt) {
|
845
|
+
_this2.onSubmitValidate(evt);
|
846
|
+
});
|
847
|
+
this.$element.on('click.Parsley', ParsleyUtils__default._SubmitSelector, function (evt) {
|
848
|
+
_this2.onSubmitButton(evt);
|
849
|
+
});
|
850
|
+
|
851
|
+
// UI could be disabled
|
852
|
+
if (false === this.options.uiEnabled) return;
|
853
|
+
|
854
|
+
this.$element.attr('novalidate', '');
|
1072
855
|
},
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
856
|
+
|
857
|
+
focus: function focus() {
|
858
|
+
this._focusedField = null;
|
859
|
+
|
860
|
+
if (true === this.validationResult || 'none' === this.options.focus) return null;
|
861
|
+
|
862
|
+
for (var i = 0; i < this.fields.length; i++) {
|
863
|
+
var field = this.fields[i];
|
864
|
+
if (true !== field.validationResult && field.validationResult.length > 0 && 'undefined' === typeof field.options.noFocus) {
|
865
|
+
this._focusedField = field.$element;
|
866
|
+
if ('first' === this.options.focus) break;
|
867
|
+
}
|
868
|
+
}
|
869
|
+
|
870
|
+
if (null === this._focusedField) return null;
|
871
|
+
|
872
|
+
return this._focusedField.focus();
|
873
|
+
},
|
874
|
+
|
875
|
+
_destroyUI: function _destroyUI() {
|
876
|
+
// Reset all event listeners
|
877
|
+
this.$element.off('.Parsley');
|
878
|
+
}
|
879
|
+
|
880
|
+
};
|
881
|
+
|
882
|
+
ParsleyUI.Field = {
|
883
|
+
|
884
|
+
_reflowUI: function _reflowUI() {
|
885
|
+
this._buildUI();
|
886
|
+
|
887
|
+
// If this field doesn't have an active UI don't bother doing something
|
888
|
+
if (!this._ui) return;
|
889
|
+
|
1077
890
|
// Diff between two validation results
|
1078
|
-
var diff = this.
|
891
|
+
var diff = diffResults(this.validationResult, this._ui.lastValidationResult);
|
892
|
+
|
1079
893
|
// Then store current validation result for next reflow
|
1080
|
-
|
1081
|
-
|
1082
|
-
fieldInstance._ui.validatedOnce = true;
|
894
|
+
this._ui.lastValidationResult = this.validationResult;
|
895
|
+
|
1083
896
|
// Handle valid / invalid / none field class
|
1084
|
-
this.
|
897
|
+
this._manageStatusClass();
|
898
|
+
|
1085
899
|
// Add, remove, updated errors messages
|
1086
|
-
this.
|
900
|
+
this._manageErrorsMessages(diff);
|
901
|
+
|
1087
902
|
// Triggers impl
|
1088
|
-
this.
|
903
|
+
this._actualizeTriggers();
|
904
|
+
|
1089
905
|
// If field is not valid for the first time, bind keyup trigger to ease UX and quickly inform user
|
1090
|
-
if ((diff.kept.length || diff.added.length) &&
|
1091
|
-
this.
|
906
|
+
if ((diff.kept.length || diff.added.length) && !this._failedOnce) {
|
907
|
+
this._failedOnce = true;
|
908
|
+
this._actualizeTriggers();
|
909
|
+
}
|
1092
910
|
},
|
911
|
+
|
1093
912
|
// Returns an array of field's error message(s)
|
1094
|
-
getErrorsMessages: function (
|
913
|
+
getErrorsMessages: function getErrorsMessages() {
|
1095
914
|
// No error message, field is valid
|
1096
|
-
if (true ===
|
1097
|
-
|
915
|
+
if (true === this.validationResult) return [];
|
916
|
+
|
1098
917
|
var messages = [];
|
1099
|
-
|
1100
|
-
|
918
|
+
|
919
|
+
for (var i = 0; i < this.validationResult.length; i++) messages.push(this.validationResult[i].errorMessage || this._getErrorMessage(this.validationResult[i].assert));
|
920
|
+
|
1101
921
|
return messages;
|
1102
922
|
},
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
923
|
+
|
924
|
+
// It's a goal of Parsley that this method is no longer required [#1073]
|
925
|
+
addError: function addError(name) {
|
926
|
+
var _ref2 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
927
|
+
|
928
|
+
var message = _ref2.message;
|
929
|
+
var assert = _ref2.assert;
|
930
|
+
var _ref2$updateClass = _ref2.updateClass;
|
931
|
+
var updateClass = _ref2$updateClass === undefined ? true : _ref2$updateClass;
|
932
|
+
|
933
|
+
this._buildUI();
|
934
|
+
this._addError(name, { message: message, assert: assert });
|
935
|
+
|
936
|
+
if (updateClass) this._errorClass();
|
1110
937
|
},
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
938
|
+
|
939
|
+
// It's a goal of Parsley that this method is no longer required [#1073]
|
940
|
+
updateError: function updateError(name) {
|
941
|
+
var _ref3 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
942
|
+
|
943
|
+
var message = _ref3.message;
|
944
|
+
var assert = _ref3.assert;
|
945
|
+
var _ref3$updateClass = _ref3.updateClass;
|
946
|
+
var updateClass = _ref3$updateClass === undefined ? true : _ref3$updateClass;
|
947
|
+
|
948
|
+
this._buildUI();
|
949
|
+
this._updateError(name, { message: message, assert: assert });
|
950
|
+
|
951
|
+
if (updateClass) this._errorClass();
|
952
|
+
},
|
953
|
+
|
954
|
+
// It's a goal of Parsley that this method is no longer required [#1073]
|
955
|
+
removeError: function removeError(name) {
|
956
|
+
var _ref4 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
957
|
+
|
958
|
+
var _ref4$updateClass = _ref4.updateClass;
|
959
|
+
var updateClass = _ref4$updateClass === undefined ? true : _ref4$updateClass;
|
960
|
+
|
961
|
+
this._buildUI();
|
962
|
+
this._removeError(name);
|
963
|
+
|
964
|
+
// edge case possible here: remove a standard Parsley error that is still failing in this.validationResult
|
965
|
+
// but highly improbable cuz' manually removing a well Parsley handled error makes no sense.
|
966
|
+
if (updateClass) this._manageStatusClass();
|
967
|
+
},
|
968
|
+
|
969
|
+
_manageStatusClass: function _manageStatusClass() {
|
970
|
+
if (this.hasConstraints() && this.needsValidation() && true === this.validationResult) this._successClass();else if (this.validationResult.length > 0) this._errorClass();else this._resetClass();
|
971
|
+
},
|
972
|
+
|
973
|
+
_manageErrorsMessages: function _manageErrorsMessages(diff) {
|
974
|
+
if ('undefined' !== typeof this.options.errorsMessagesDisabled) return;
|
975
|
+
|
1114
976
|
// Case where we have errorMessage option that configure an unique field error message, regardless failing validators
|
1115
|
-
if ('undefined' !== typeof
|
1116
|
-
if (
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
);
|
1123
|
-
return fieldInstance._ui.$errorsWrapper
|
1124
|
-
.addClass('filled')
|
1125
|
-
.find('.parsley-custom-error-message')
|
1126
|
-
.html(fieldInstance.options.errorMessage);
|
977
|
+
if ('undefined' !== typeof this.options.errorMessage) {
|
978
|
+
if (diff.added.length || diff.kept.length) {
|
979
|
+
this._insertErrorWrapper();
|
980
|
+
|
981
|
+
if (0 === this._ui.$errorsWrapper.find('.parsley-custom-error-message').length) this._ui.$errorsWrapper.append($(this.options.errorTemplate).addClass('parsley-custom-error-message'));
|
982
|
+
|
983
|
+
return this._ui.$errorsWrapper.addClass('filled').find('.parsley-custom-error-message').html(this.options.errorMessage);
|
1127
984
|
}
|
1128
|
-
|
1129
|
-
|
1130
|
-
.find('.parsley-custom-error-message')
|
1131
|
-
.remove();
|
985
|
+
|
986
|
+
return this._ui.$errorsWrapper.removeClass('filled').find('.parsley-custom-error-message').remove();
|
1132
987
|
}
|
988
|
+
|
1133
989
|
// Show, hide, update failing constraints messages
|
1134
|
-
for (var i = 0; i < diff.removed.length; i++)
|
1135
|
-
|
1136
|
-
for (i = 0; i < diff.added.length; i++)
|
1137
|
-
|
1138
|
-
for (i = 0; i < diff.kept.length; i++)
|
1139
|
-
this.updateError(fieldInstance, diff.kept[i].assert.name, undefined, diff.kept[i].assert, true);
|
1140
|
-
},
|
1141
|
-
// TODO: strange API here, intuitive for manual usage with addError(pslyInstance, 'foo', 'bar')
|
1142
|
-
// but a little bit complex for above internal usage, with forced undefined parameter...
|
1143
|
-
addError: function (fieldInstance, name, message, assert, doNotUpdateClass) {
|
1144
|
-
fieldInstance._ui.$errorsWrapper
|
1145
|
-
.addClass('filled')
|
1146
|
-
.append(
|
1147
|
-
$(fieldInstance.options.errorTemplate)
|
1148
|
-
.addClass('parsley-' + name)
|
1149
|
-
.html(message || this._getErrorMessage(fieldInstance, assert))
|
1150
|
-
);
|
1151
|
-
if (true !== doNotUpdateClass)
|
1152
|
-
this._errorClass(fieldInstance);
|
1153
|
-
},
|
1154
|
-
// Same as above
|
1155
|
-
updateError: function (fieldInstance, name, message, assert, doNotUpdateClass) {
|
1156
|
-
fieldInstance._ui.$errorsWrapper
|
1157
|
-
.addClass('filled')
|
1158
|
-
.find('.parsley-' + name)
|
1159
|
-
.html(message || this._getErrorMessage(fieldInstance, assert));
|
1160
|
-
if (true !== doNotUpdateClass)
|
1161
|
-
this._errorClass(fieldInstance);
|
1162
|
-
},
|
1163
|
-
// Same as above twice
|
1164
|
-
removeError: function (fieldInstance, name, doNotUpdateClass) {
|
1165
|
-
fieldInstance._ui.$errorsWrapper
|
1166
|
-
.removeClass('filled')
|
1167
|
-
.find('.parsley-' + name)
|
1168
|
-
.remove();
|
1169
|
-
// edge case possible here: remove a standard Parsley error that is still failing in fieldInstance.validationResult
|
1170
|
-
// but highly improbable cuz' manually removing a well Parsley handled error makes no sense.
|
1171
|
-
if (true !== doNotUpdateClass)
|
1172
|
-
this.manageStatusClass(fieldInstance);
|
1173
|
-
},
|
1174
|
-
focus: function (formInstance) {
|
1175
|
-
if (true === formInstance.validationResult || 'none' === formInstance.options.focus)
|
1176
|
-
return formInstance._focusedField = null;
|
1177
|
-
formInstance._focusedField = null;
|
1178
|
-
for (var i = 0; i < formInstance.fields.length; i++)
|
1179
|
-
if (true !== formInstance.fields[i].validationResult && formInstance.fields[i].validationResult.length > 0 && 'undefined' === typeof formInstance.fields[i].options.noFocus) {
|
1180
|
-
if ('first' === formInstance.options.focus) {
|
1181
|
-
formInstance._focusedField = formInstance.fields[i].$element;
|
1182
|
-
return formInstance._focusedField.focus();
|
1183
|
-
}
|
1184
|
-
formInstance._focusedField = formInstance.fields[i].$element;
|
1185
|
-
}
|
1186
|
-
if (null === formInstance._focusedField)
|
1187
|
-
return null;
|
1188
|
-
return formInstance._focusedField.focus();
|
990
|
+
for (var i = 0; i < diff.removed.length; i++) this._removeError(diff.removed[i].assert.name);
|
991
|
+
|
992
|
+
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 });
|
993
|
+
|
994
|
+
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 });
|
1189
995
|
},
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
var
|
1198
|
-
added = [],
|
1199
|
-
kept = [];
|
1200
|
-
for (var i = 0; i < newResult.length; i++) {
|
1201
|
-
var found = false;
|
1202
|
-
for (var j = 0; j < oldResult.length; j++)
|
1203
|
-
if (newResult[i].assert.name === oldResult[j].assert.name) {
|
1204
|
-
found = true;
|
1205
|
-
break;
|
1206
|
-
}
|
1207
|
-
if (found)
|
1208
|
-
kept.push(newResult[i]);
|
1209
|
-
else
|
1210
|
-
added.push(newResult[i]);
|
1211
|
-
}
|
1212
|
-
return {
|
1213
|
-
kept: kept,
|
1214
|
-
added: added,
|
1215
|
-
removed: !deep ? this._diff(oldResult, newResult, true).added : []
|
1216
|
-
};
|
996
|
+
|
997
|
+
_addError: function _addError(name, _ref5) {
|
998
|
+
var message = _ref5.message;
|
999
|
+
var assert = _ref5.assert;
|
1000
|
+
|
1001
|
+
this._insertErrorWrapper();
|
1002
|
+
this._ui.$errorsWrapper.addClass('filled').append($(this.options.errorTemplate).addClass('parsley-' + name).html(message || this._getErrorMessage(assert)));
|
1217
1003
|
},
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1004
|
+
|
1005
|
+
_updateError: function _updateError(name, _ref6) {
|
1006
|
+
var message = _ref6.message;
|
1007
|
+
var assert = _ref6.assert;
|
1008
|
+
|
1009
|
+
this._ui.$errorsWrapper.addClass('filled').find('.parsley-' + name).html(message || this._getErrorMessage(assert));
|
1224
1010
|
},
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1011
|
+
|
1012
|
+
_removeError: function _removeError(name) {
|
1013
|
+
this._ui.$errorsWrapper.removeClass('filled').find('.parsley-' + name).remove();
|
1014
|
+
},
|
1015
|
+
|
1016
|
+
_getErrorMessage: function _getErrorMessage(constraint) {
|
1017
|
+
var customConstraintErrorMessage = constraint.name + 'Message';
|
1018
|
+
|
1019
|
+
if ('undefined' !== typeof this.options[customConstraintErrorMessage]) return window.Parsley.formatMessage(this.options[customConstraintErrorMessage], constraint.requirements);
|
1020
|
+
|
1021
|
+
return window.Parsley.getErrorMessage(constraint);
|
1022
|
+
},
|
1023
|
+
|
1024
|
+
_buildUI: function _buildUI() {
|
1025
|
+
// UI could be already built or disabled
|
1026
|
+
if (this._ui || false === this.options.uiEnabled) return;
|
1027
|
+
|
1028
|
+
var _ui = {};
|
1029
|
+
|
1231
1030
|
// Give field its Parsley id in DOM
|
1232
|
-
|
1233
|
-
|
1031
|
+
this.$element.attr(this.options.namespace + 'id', this.__id__);
|
1032
|
+
|
1033
|
+
/** Generate important UI elements and store them in this **/
|
1234
1034
|
// $errorClassHandler is the $element that woul have parsley-error and parsley-success classes
|
1235
|
-
_ui.$errorClassHandler = this._manageClassHandler(
|
1035
|
+
_ui.$errorClassHandler = this._manageClassHandler();
|
1036
|
+
|
1236
1037
|
// $errorsWrapper is a div that would contain the various field errors, it will be appended into $errorsContainer
|
1237
|
-
_ui.errorsWrapperId = 'parsley-id-' + (
|
1238
|
-
_ui.$errorsWrapper = $(
|
1038
|
+
_ui.errorsWrapperId = 'parsley-id-' + (this.options.multiple ? 'multiple-' + this.options.multiple : this.__id__);
|
1039
|
+
_ui.$errorsWrapper = $(this.options.errorsWrapper).attr('id', _ui.errorsWrapperId);
|
1040
|
+
|
1239
1041
|
// ValidationResult UI storage to detect what have changed bwt two validations, and update DOM accordingly
|
1240
1042
|
_ui.lastValidationResult = [];
|
1241
|
-
_ui.validatedOnce = false;
|
1242
1043
|
_ui.validationInformationVisible = false;
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
if( !fieldInstance.$element.is(fieldInstance.options.excluded) ) {
|
1247
|
-
/** Mess with DOM now **/
|
1248
|
-
this._insertErrorWrapper(fieldInstance);
|
1249
|
-
}
|
1250
|
-
// Bind triggers first time
|
1251
|
-
this.actualizeTriggers(fieldInstance);
|
1044
|
+
|
1045
|
+
// Store it in this for later
|
1046
|
+
this._ui = _ui;
|
1252
1047
|
},
|
1048
|
+
|
1253
1049
|
// Determine which element will have `parsley-error` and `parsley-success` classes
|
1254
|
-
_manageClassHandler: function (
|
1050
|
+
_manageClassHandler: function _manageClassHandler() {
|
1255
1051
|
// An element selector could be passed through DOM with `data-parsley-class-handler=#foo`
|
1256
|
-
if ('string' === typeof
|
1257
|
-
|
1052
|
+
if ('string' === typeof this.options.classHandler && $(this.options.classHandler).length) return $(this.options.classHandler);
|
1053
|
+
|
1258
1054
|
// Class handled could also be determined by function given in Parsley options
|
1259
|
-
var $handler =
|
1055
|
+
var $handler = this.options.classHandler.call(this, this);
|
1056
|
+
|
1260
1057
|
// If this function returned a valid existing DOM element, go for it
|
1261
|
-
if ('undefined' !== typeof $handler && $handler.length)
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1058
|
+
if ('undefined' !== typeof $handler && $handler.length) return $handler;
|
1059
|
+
|
1060
|
+
return this._inputHolder();
|
1061
|
+
},
|
1062
|
+
|
1063
|
+
_inputHolder: function _inputHolder() {
|
1064
|
+
// if simple element (input, texatrea, select...) it will perfectly host the classes and precede the error container
|
1065
|
+
if (!this.options.multiple || this.$element.is('select')) return this.$element;
|
1066
|
+
|
1266
1067
|
// But if multiple element (radio, checkbox), that would be their parent
|
1267
|
-
return
|
1068
|
+
return this.$element.parent();
|
1268
1069
|
},
|
1269
|
-
|
1070
|
+
|
1071
|
+
_insertErrorWrapper: function _insertErrorWrapper() {
|
1270
1072
|
var $errorsContainer;
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1276
|
-
|
1277
|
-
else if ('function' === typeof
|
1278
|
-
|
1279
|
-
if ('undefined' !== typeof $errorsContainer && $errorsContainer.length)
|
1280
|
-
|
1281
|
-
return
|
1282
|
-
},
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
1073
|
+
|
1074
|
+
// Nothing to do if already inserted
|
1075
|
+
if (0 !== this._ui.$errorsWrapper.parent().length) return this._ui.$errorsWrapper.parent();
|
1076
|
+
|
1077
|
+
if ('string' === typeof this.options.errorsContainer) {
|
1078
|
+
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');
|
1079
|
+
} else if ('function' === typeof this.options.errorsContainer) $errorsContainer = this.options.errorsContainer.call(this, this);
|
1080
|
+
|
1081
|
+
if ('undefined' !== typeof $errorsContainer && $errorsContainer.length) return $errorsContainer.append(this._ui.$errorsWrapper);
|
1082
|
+
|
1083
|
+
return this._inputHolder().after(this._ui.$errorsWrapper);
|
1084
|
+
},
|
1085
|
+
|
1086
|
+
_actualizeTriggers: function _actualizeTriggers() {
|
1087
|
+
var _this3 = this;
|
1088
|
+
|
1089
|
+
var $toBind = this._findRelated();
|
1090
|
+
var trigger;
|
1091
|
+
|
1092
|
+
// Remove Parsley events already bound on this field
|
1288
1093
|
$toBind.off('.Parsley');
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1297
|
-
|
1298
|
-
|
1299
|
-
|
1300
|
-
// Called through $.proxy with fieldInstance. `this` context is ParsleyField
|
1301
|
-
eventValidate: function(event) {
|
1302
|
-
// For keyup, keypress, keydown... events that could be a little bit obstrusive
|
1094
|
+
if (this._failedOnce) $toBind.on(ParsleyUtils__default.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), function () {
|
1095
|
+
_this3.validate();
|
1096
|
+
});else if (trigger = ParsleyUtils__default.namespaceEvents(this.options.trigger, 'Parsley')) {
|
1097
|
+
$toBind.on(trigger, function (event) {
|
1098
|
+
_this3._eventValidate(event);
|
1099
|
+
});
|
1100
|
+
}
|
1101
|
+
},
|
1102
|
+
|
1103
|
+
_eventValidate: function _eventValidate(event) {
|
1104
|
+
// For keyup, keypress, keydown, input... events that could be a little bit obstrusive
|
1303
1105
|
// do not validate if val length < min threshold on first validation. Once field have been validated once and info
|
1304
1106
|
// about success or failure have been displayed, always validate with this trigger to reflect every yalidation change.
|
1305
|
-
if (
|
1306
|
-
|
1307
|
-
return;
|
1308
|
-
this._ui.validatedOnce = true;
|
1107
|
+
if (/key|input/.test(event.type)) if (!(this._ui && this._ui.validationInformationVisible) && this.getValue().length <= this.options.validationThreshold) return;
|
1108
|
+
|
1309
1109
|
this.validate();
|
1310
1110
|
},
|
1311
|
-
|
1312
|
-
|
1313
|
-
// Radio and checkboxes fields must bind every field multiple
|
1314
|
-
if (fieldInstance.options.multiple)
|
1315
|
-
$('[' + fieldInstance.options.namespace + 'multiple="' + fieldInstance.options.multiple + '"]').each(function () {
|
1316
|
-
if (!new RegExp('change', 'i').test($(this).parsley().options.trigger || ''))
|
1317
|
-
return $(this).on('change.ParsleyFailedOnce', false, $.proxy(fieldInstance.validate, fieldInstance));
|
1318
|
-
});
|
1319
|
-
// Select case
|
1320
|
-
if (fieldInstance.$element.is('select'))
|
1321
|
-
if (!new RegExp('change', 'i').test(fieldInstance.options.trigger || ''))
|
1322
|
-
return fieldInstance.$element.on('change.ParsleyFailedOnce', false, $.proxy(fieldInstance.validate, fieldInstance));
|
1323
|
-
// All other inputs fields
|
1324
|
-
if (!new RegExp('keyup', 'i').test(fieldInstance.options.trigger || ''))
|
1325
|
-
return fieldInstance.$element.on('keyup.ParsleyFailedOnce', false, $.proxy(fieldInstance.validate, fieldInstance));
|
1326
|
-
},
|
1327
|
-
reset: function (parsleyInstance) {
|
1111
|
+
|
1112
|
+
_resetUI: function _resetUI() {
|
1328
1113
|
// Reset all event listeners
|
1329
|
-
|
1330
|
-
|
1114
|
+
this._failedOnce = false;
|
1115
|
+
this._actualizeTriggers();
|
1116
|
+
|
1331
1117
|
// Nothing to do if UI never initialized for this field
|
1332
|
-
if ('undefined' === typeof
|
1333
|
-
|
1334
|
-
if ('ParsleyForm' === parsleyInstance.__class__)
|
1335
|
-
return;
|
1118
|
+
if ('undefined' === typeof this._ui) return;
|
1119
|
+
|
1336
1120
|
// Reset all errors' li
|
1337
|
-
|
1338
|
-
|
1339
|
-
.children()
|
1340
|
-
.remove();
|
1121
|
+
this._ui.$errorsWrapper.removeClass('filled').children().remove();
|
1122
|
+
|
1341
1123
|
// Reset validation class
|
1342
|
-
this._resetClass(
|
1124
|
+
this._resetClass();
|
1125
|
+
|
1343
1126
|
// Reset validation flags and last validation result
|
1344
|
-
|
1345
|
-
|
1346
|
-
parsleyInstance._ui.validationInformationVisible = false;
|
1127
|
+
this._ui.lastValidationResult = [];
|
1128
|
+
this._ui.validationInformationVisible = false;
|
1347
1129
|
},
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1352
|
-
if ('undefined' !== typeof
|
1353
|
-
|
1354
|
-
delete
|
1355
|
-
},
|
1356
|
-
_successClass: function (fieldInstance) {
|
1357
|
-
fieldInstance._ui.validationInformationVisible = true;
|
1358
|
-
fieldInstance._ui.$errorClassHandler.removeClass(fieldInstance.options.errorClass).addClass(fieldInstance.options.successClass);
|
1359
|
-
},
|
1360
|
-
_errorClass: function (fieldInstance) {
|
1361
|
-
fieldInstance._ui.validationInformationVisible = true;
|
1362
|
-
fieldInstance._ui.$errorClassHandler.removeClass(fieldInstance.options.successClass).addClass(fieldInstance.options.errorClass);
|
1130
|
+
|
1131
|
+
_destroyUI: function _destroyUI() {
|
1132
|
+
this._resetUI();
|
1133
|
+
|
1134
|
+
if ('undefined' !== typeof this._ui) this._ui.$errorsWrapper.remove();
|
1135
|
+
|
1136
|
+
delete this._ui;
|
1363
1137
|
},
|
1364
|
-
_resetClass: function (fieldInstance) {
|
1365
|
-
fieldInstance._ui.$errorClassHandler.removeClass(fieldInstance.options.successClass).removeClass(fieldInstance.options.errorClass);
|
1366
|
-
}
|
1367
|
-
};
|
1368
1138
|
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
ParsleyOptionsFactory.prototype = {
|
1377
|
-
get: function (parsleyInstance) {
|
1378
|
-
if ('undefined' === typeof parsleyInstance.__class__)
|
1379
|
-
throw new Error('Parsley Instance expected');
|
1380
|
-
switch (parsleyInstance.__class__) {
|
1381
|
-
case 'Parsley':
|
1382
|
-
return this.staticOptions;
|
1383
|
-
case 'ParsleyForm':
|
1384
|
-
return this.getFormOptions(parsleyInstance);
|
1385
|
-
case 'ParsleyField':
|
1386
|
-
case 'ParsleyFieldMultiple':
|
1387
|
-
return this.getFieldOptions(parsleyInstance);
|
1388
|
-
default:
|
1389
|
-
throw new Error('Instance ' + parsleyInstance.__class__ + ' is not supported');
|
1390
|
-
}
|
1139
|
+
_successClass: function _successClass() {
|
1140
|
+
this._ui.validationInformationVisible = true;
|
1141
|
+
this._ui.$errorClassHandler.removeClass(this.options.errorClass).addClass(this.options.successClass);
|
1142
|
+
},
|
1143
|
+
_errorClass: function _errorClass() {
|
1144
|
+
this._ui.validationInformationVisible = true;
|
1145
|
+
this._ui.$errorClassHandler.removeClass(this.options.successClass).addClass(this.options.errorClass);
|
1391
1146
|
},
|
1392
|
-
|
1393
|
-
this.
|
1394
|
-
// not deep extend, since formOptions is a 1 level deep object
|
1395
|
-
return $.extend({}, this.staticOptions, this.formOptions);
|
1396
|
-
},
|
1397
|
-
getFieldOptions: function (fieldInstance) {
|
1398
|
-
this.fieldOptions = ParsleyUtils.attr(fieldInstance.$element, this.staticOptions.namespace);
|
1399
|
-
if (null === this.formOptions && 'undefined' !== typeof fieldInstance.parent)
|
1400
|
-
this.formOptions = this.getFormOptions(fieldInstance.parent);
|
1401
|
-
// not deep extend, since formOptions and fieldOptions is a 1 level deep object
|
1402
|
-
return $.extend({}, this.staticOptions, this.formOptions, this.fieldOptions);
|
1147
|
+
_resetClass: function _resetClass() {
|
1148
|
+
this._ui.$errorClassHandler.removeClass(this.options.successClass).removeClass(this.options.errorClass);
|
1403
1149
|
}
|
1404
1150
|
};
|
1405
1151
|
|
1406
|
-
var ParsleyForm = function (element,
|
1152
|
+
var ParsleyForm = function ParsleyForm(element, domOptions, options) {
|
1407
1153
|
this.__class__ = 'ParsleyForm';
|
1408
|
-
|
1409
|
-
if ('OptionsFactory' !== ParsleyUtils.get(OptionsFactory, '__class__'))
|
1410
|
-
throw new Error('You must give an OptionsFactory instance');
|
1411
|
-
this.OptionsFactory = OptionsFactory;
|
1154
|
+
|
1412
1155
|
this.$element = $(element);
|
1156
|
+
this.domOptions = domOptions;
|
1157
|
+
this.options = options;
|
1158
|
+
this.parent = window.Parsley;
|
1159
|
+
|
1160
|
+
this.fields = [];
|
1413
1161
|
this.validationResult = null;
|
1414
|
-
this.options = this.OptionsFactory.get(this);
|
1415
1162
|
};
|
1163
|
+
|
1164
|
+
var ParsleyForm__statusMapping = { pending: null, resolved: true, rejected: false };
|
1165
|
+
|
1416
1166
|
ParsleyForm.prototype = {
|
1417
|
-
onSubmitValidate: function (event) {
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1167
|
+
onSubmitValidate: function onSubmitValidate(event) {
|
1168
|
+
var _this4 = this;
|
1169
|
+
|
1170
|
+
// This is a Parsley generated submit event, do not validate, do not prevent, simply exit and keep normal behavior
|
1171
|
+
if (true === event.parsley) return;
|
1172
|
+
|
1173
|
+
// If we didn't come here through a submit button, use the first one in the form
|
1174
|
+
var $submitSource = this._$submitSource || this.$element.find(ParsleyUtils__default._SubmitSelector).first();
|
1175
|
+
this._$submitSource = null;
|
1176
|
+
this.$element.find('.parsley-synthetic-submit-button').prop('disabled', true);
|
1177
|
+
if ($submitSource.is('[formnovalidate]')) return;
|
1178
|
+
|
1179
|
+
var promise = this.whenValidate({ event: event });
|
1180
|
+
|
1181
|
+
if ('resolved' === promise.state() && false !== this._trigger('submit')) {
|
1182
|
+
// All good, let event go through. We make this distinction because browsers
|
1183
|
+
// differ in their handling of `submit` being called from inside a submit event [#1047]
|
1184
|
+
} else {
|
1185
|
+
// Rejected or pending: cancel this submit
|
1186
|
+
event.stopImmediatePropagation();
|
1187
|
+
event.preventDefault();
|
1188
|
+
if ('pending' === promise.state()) promise.done(function () {
|
1189
|
+
_this4._submit($submitSource);
|
1190
|
+
});
|
1191
|
+
}
|
1192
|
+
},
|
1193
|
+
|
1194
|
+
onSubmitButton: function onSubmitButton(event) {
|
1195
|
+
this._$submitSource = $(event.currentTarget);
|
1196
|
+
},
|
1197
|
+
// internal
|
1198
|
+
// _submit submits the form, this time without going through the validations.
|
1199
|
+
// Care must be taken to "fake" the actual submit button being clicked.
|
1200
|
+
_submit: function _submit($submitSource) {
|
1201
|
+
if (false === this._trigger('submit')) return;
|
1202
|
+
// Add submit button's data
|
1203
|
+
if ($submitSource) {
|
1204
|
+
var $synthetic = this.$element.find('.parsley-synthetic-submit-button').prop('disabled', false);
|
1205
|
+
if (0 === $synthetic.length) $synthetic = $('<input class="parsley-synthetic-submit-button" type="hidden">').appendTo(this.$element);
|
1206
|
+
$synthetic.attr({
|
1207
|
+
name: $submitSource.attr('name'),
|
1208
|
+
value: $submitSource.attr('value')
|
1209
|
+
});
|
1423
1210
|
}
|
1424
|
-
|
1211
|
+
|
1212
|
+
this.$element.trigger($.extend($.Event('submit'), { parsley: true }));
|
1425
1213
|
},
|
1426
|
-
|
1427
|
-
|
1214
|
+
|
1215
|
+
// Performs validation on fields while triggering events.
|
1216
|
+
// @returns `true` if all validations succeeds, `false`
|
1217
|
+
// if a failure is immediately detected, or `null`
|
1218
|
+
// if dependant on a promise.
|
1219
|
+
// Consider using `whenValidate` instead.
|
1220
|
+
validate: function validate(options) {
|
1221
|
+
if (arguments.length >= 1 && !$.isPlainObject(options)) {
|
1222
|
+
ParsleyUtils__default.warnOnce('Calling validate on a parsley form without passing arguments as an object is deprecated.');
|
1223
|
+
|
1224
|
+
var _arguments = _slice.call(arguments);
|
1225
|
+
|
1226
|
+
var group = _arguments[0];
|
1227
|
+
var force = _arguments[1];
|
1228
|
+
var event = _arguments[2];
|
1229
|
+
|
1230
|
+
options = { group: group, force: force, event: event };
|
1231
|
+
}
|
1232
|
+
return ParsleyForm__statusMapping[this.whenValidate(options).state()];
|
1233
|
+
},
|
1234
|
+
|
1235
|
+
whenValidate: function whenValidate() {
|
1236
|
+
var _ParsleyUtils__default$all$done$fail$always,
|
1237
|
+
_this5 = this;
|
1238
|
+
|
1239
|
+
var _ref7 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
1240
|
+
|
1241
|
+
var group = _ref7.group;
|
1242
|
+
var force = _ref7.force;
|
1243
|
+
var event = _ref7.event;
|
1244
|
+
|
1428
1245
|
this.submitEvent = event;
|
1246
|
+
if (event) {
|
1247
|
+
this.submitEvent = $.extend({}, event, { preventDefault: function preventDefault() {
|
1248
|
+
ParsleyUtils__default.warnOnce("Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`");
|
1249
|
+
_this5.validationResult = false;
|
1250
|
+
} });
|
1251
|
+
}
|
1429
1252
|
this.validationResult = true;
|
1430
|
-
|
1431
|
-
|
1253
|
+
|
1254
|
+
// fire validate event to eventually modify things before every validation
|
1255
|
+
this._trigger('validate');
|
1256
|
+
|
1432
1257
|
// Refresh form DOM options and form's fields that could have changed
|
1433
1258
|
this._refreshFields();
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1259
|
+
|
1260
|
+
var promises = this._withoutReactualizingFormOptions(function () {
|
1261
|
+
return $.map(_this5.fields, function (field) {
|
1262
|
+
return field.whenValidate({ force: force, group: group });
|
1263
|
+
});
|
1264
|
+
});
|
1265
|
+
|
1266
|
+
return (_ParsleyUtils__default$all$done$fail$always = ParsleyUtils__default.all(promises).done(function () {
|
1267
|
+
_this5._trigger('success');
|
1268
|
+
}).fail(function () {
|
1269
|
+
_this5.validationResult = false;
|
1270
|
+
_this5.focus();
|
1271
|
+
_this5._trigger('error');
|
1272
|
+
}).always(function () {
|
1273
|
+
_this5._trigger('validated');
|
1274
|
+
})).pipe.apply(_ParsleyUtils__default$all$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
|
1446
1275
|
},
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1276
|
+
|
1277
|
+
// Iterate over refreshed fields, and stop on first failure.
|
1278
|
+
// Returns `true` if all fields are valid, `false` if a failure is detected
|
1279
|
+
// or `null` if the result depends on an unresolved promise.
|
1280
|
+
// Prefer using `whenValid` instead.
|
1281
|
+
isValid: function isValid(options) {
|
1282
|
+
if (arguments.length >= 1 && !$.isPlainObject(options)) {
|
1283
|
+
ParsleyUtils__default.warnOnce('Calling isValid on a parsley form without passing arguments as an object is deprecated.');
|
1284
|
+
|
1285
|
+
var _arguments2 = _slice.call(arguments);
|
1286
|
+
|
1287
|
+
var group = _arguments2[0];
|
1288
|
+
var force = _arguments2[1];
|
1289
|
+
|
1290
|
+
options = { group: group, force: force };
|
1456
1291
|
}
|
1457
|
-
return
|
1292
|
+
return ParsleyForm__statusMapping[this.whenValid(options).state()];
|
1458
1293
|
},
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1294
|
+
|
1295
|
+
// Iterate over refreshed fields and validate them.
|
1296
|
+
// Returns a promise.
|
1297
|
+
// A validation that immediately fails will interrupt the validations.
|
1298
|
+
whenValid: function whenValid() {
|
1299
|
+
var _this6 = this;
|
1300
|
+
|
1301
|
+
var _ref8 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
1302
|
+
|
1303
|
+
var group = _ref8.group;
|
1304
|
+
var force = _ref8.force;
|
1305
|
+
|
1306
|
+
this._refreshFields();
|
1307
|
+
|
1308
|
+
var promises = this._withoutReactualizingFormOptions(function () {
|
1309
|
+
return $.map(_this6.fields, function (field) {
|
1310
|
+
return field.whenValid({ group: group, force: force });
|
1311
|
+
});
|
1312
|
+
});
|
1313
|
+
return ParsleyUtils__default.all(promises);
|
1463
1314
|
},
|
1464
|
-
|
1315
|
+
|
1316
|
+
_refreshFields: function _refreshFields() {
|
1465
1317
|
return this.actualizeOptions()._bindFields();
|
1466
1318
|
},
|
1467
|
-
|
1468
|
-
|
1319
|
+
|
1320
|
+
_bindFields: function _bindFields() {
|
1321
|
+
var _this7 = this;
|
1322
|
+
|
1323
|
+
var oldFields = this.fields;
|
1324
|
+
|
1469
1325
|
this.fields = [];
|
1470
1326
|
this.fieldsMappedById = {};
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1327
|
+
|
1328
|
+
this._withoutReactualizingFormOptions(function () {
|
1329
|
+
_this7.$element.find(_this7.options.inputs).not(_this7.options.excluded).each(function (_, element) {
|
1330
|
+
var fieldInstance = new window.Parsley.Factory(element, {}, _this7);
|
1331
|
+
|
1332
|
+
// Only add valid and not excluded `ParsleyField` and `ParsleyFieldMultiple` children
|
1333
|
+
if (('ParsleyField' === fieldInstance.__class__ || 'ParsleyFieldMultiple' === fieldInstance.__class__) && true !== fieldInstance.options.excluded) if ('undefined' === typeof _this7.fieldsMappedById[fieldInstance.__class__ + '-' + fieldInstance.__id__]) {
|
1334
|
+
_this7.fieldsMappedById[fieldInstance.__class__ + '-' + fieldInstance.__id__] = fieldInstance;
|
1335
|
+
_this7.fields.push(fieldInstance);
|
1478
1336
|
}
|
1337
|
+
});
|
1338
|
+
|
1339
|
+
$.each(ParsleyUtils__default.difference(oldFields, _this7.fields), function (_, field) {
|
1340
|
+
field._trigger('reset');
|
1341
|
+
});
|
1479
1342
|
});
|
1480
1343
|
return this;
|
1344
|
+
},
|
1345
|
+
|
1346
|
+
// Internal only.
|
1347
|
+
// Looping on a form's fields to do validation or similar
|
1348
|
+
// will trigger reactualizing options on all of them, which
|
1349
|
+
// in turn will reactualize the form's options.
|
1350
|
+
// To avoid calling actualizeOptions so many times on the form
|
1351
|
+
// for nothing, _withoutReactualizingFormOptions temporarily disables
|
1352
|
+
// the method actualizeOptions on this form while `fn` is called.
|
1353
|
+
_withoutReactualizingFormOptions: function _withoutReactualizingFormOptions(fn) {
|
1354
|
+
var oldActualizeOptions = this.actualizeOptions;
|
1355
|
+
this.actualizeOptions = function () {
|
1356
|
+
return this;
|
1357
|
+
};
|
1358
|
+
var result = fn();
|
1359
|
+
this.actualizeOptions = oldActualizeOptions;
|
1360
|
+
return result;
|
1361
|
+
},
|
1362
|
+
|
1363
|
+
// Internal only.
|
1364
|
+
// Shortcut to trigger an event
|
1365
|
+
// Returns true iff event is not interrupted and default not prevented.
|
1366
|
+
_trigger: function _trigger(eventName) {
|
1367
|
+
return this.trigger('form:' + eventName);
|
1481
1368
|
}
|
1369
|
+
|
1482
1370
|
};
|
1483
1371
|
|
1484
|
-
var ConstraintFactory = function (parsleyField, name, requirements, priority, isDomConstraint) {
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
var getPriority = function () {
|
1493
|
-
if ('undefined' !== typeof parsleyField.options[name + 'Priority'])
|
1494
|
-
return parsleyField.options[name + 'Priority'];
|
1495
|
-
return ParsleyUtils.get(assert, 'priority') || 2;
|
1496
|
-
};
|
1497
|
-
priority = priority || getPriority();
|
1498
|
-
// If validator have a requirementsTransformer, execute it
|
1499
|
-
if ('function' === typeof assert.requirementsTransformer) {
|
1500
|
-
requirements = assert.requirementsTransformer();
|
1501
|
-
// rebuild assert with new requirements
|
1502
|
-
assert = window.ParsleyValidator.validators[name](requirements);
|
1503
|
-
}
|
1504
|
-
return $.extend(assert, {
|
1372
|
+
var ConstraintFactory = function ConstraintFactory(parsleyField, name, requirements, priority, isDomConstraint) {
|
1373
|
+
if (!/ParsleyField/.test(parsleyField.__class__)) throw new Error('ParsleyField or ParsleyFieldMultiple instance expected');
|
1374
|
+
|
1375
|
+
var validatorSpec = window.Parsley._validatorRegistry.validators[name];
|
1376
|
+
var validator = new ParsleyValidator(validatorSpec);
|
1377
|
+
|
1378
|
+
$.extend(this, {
|
1379
|
+
validator: validator,
|
1505
1380
|
name: name,
|
1506
1381
|
requirements: requirements,
|
1507
|
-
priority: priority,
|
1508
|
-
|
1509
|
-
isDomConstraint: isDomConstraint || ParsleyUtils.attr(parsleyField.$element, parsleyField.options.namespace, name)
|
1382
|
+
priority: priority || parsleyField.options[name + 'Priority'] || validator.priority,
|
1383
|
+
isDomConstraint: true === isDomConstraint
|
1510
1384
|
});
|
1385
|
+
this._parseRequirements(parsleyField.options);
|
1386
|
+
};
|
1387
|
+
|
1388
|
+
var capitalize = function capitalize(str) {
|
1389
|
+
var cap = str[0].toUpperCase();
|
1390
|
+
return cap + str.slice(1);
|
1391
|
+
};
|
1392
|
+
|
1393
|
+
ConstraintFactory.prototype = {
|
1394
|
+
validate: function validate(value, instance) {
|
1395
|
+
var _validator;
|
1396
|
+
|
1397
|
+
return (_validator = this.validator).validate.apply(_validator, [value].concat(_toConsumableArray(this.requirementList), [instance]));
|
1398
|
+
},
|
1399
|
+
|
1400
|
+
_parseRequirements: function _parseRequirements(options) {
|
1401
|
+
var _this8 = this;
|
1402
|
+
|
1403
|
+
this.requirementList = this.validator.parseRequirements(this.requirements, function (key) {
|
1404
|
+
return options[_this8.name + capitalize(key)];
|
1405
|
+
});
|
1406
|
+
}
|
1511
1407
|
};
|
1512
1408
|
|
1513
|
-
var ParsleyField = function (field,
|
1409
|
+
var ParsleyField = function ParsleyField(field, domOptions, options, parsleyFormInstance) {
|
1514
1410
|
this.__class__ = 'ParsleyField';
|
1515
|
-
|
1411
|
+
|
1516
1412
|
this.$element = $(field);
|
1517
|
-
|
1413
|
+
|
1414
|
+
// Set parent if we have one
|
1518
1415
|
if ('undefined' !== typeof parsleyFormInstance) {
|
1519
1416
|
this.parent = parsleyFormInstance;
|
1520
|
-
this.OptionsFactory = this.parent.OptionsFactory;
|
1521
|
-
this.options = this.OptionsFactory.get(this);
|
1522
|
-
// Else, take the `Parsley` one
|
1523
|
-
} else {
|
1524
|
-
this.OptionsFactory = OptionsFactory;
|
1525
|
-
this.options = this.OptionsFactory.get(this);
|
1526
1417
|
}
|
1418
|
+
|
1419
|
+
this.options = options;
|
1420
|
+
this.domOptions = domOptions;
|
1421
|
+
|
1527
1422
|
// Initialize some properties
|
1528
1423
|
this.constraints = [];
|
1529
1424
|
this.constraintsByName = {};
|
1530
|
-
this.validationResult =
|
1425
|
+
this.validationResult = true;
|
1426
|
+
|
1531
1427
|
// Bind constraints
|
1532
1428
|
this._bindConstraints();
|
1533
1429
|
};
|
1430
|
+
|
1431
|
+
var parsley_field__statusMapping = { pending: null, resolved: true, rejected: false };
|
1432
|
+
|
1534
1433
|
ParsleyField.prototype = {
|
1535
1434
|
// # Public API
|
1536
|
-
// Validate field and
|
1537
|
-
// @returns
|
1538
|
-
//
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1435
|
+
// Validate field and trigger some events for mainly `ParsleyUI`
|
1436
|
+
// @returns `true`, an array of the validators that failed, or
|
1437
|
+
// `null` if validation is not finished. Prefer using whenValidate
|
1438
|
+
validate: function validate(options) {
|
1439
|
+
if (arguments.length >= 1 && !$.isPlainObject(options)) {
|
1440
|
+
ParsleyUtils__default.warnOnce('Calling validate on a parsley field without passing arguments as an object is deprecated.');
|
1441
|
+
options = { options: options };
|
1442
|
+
}
|
1443
|
+
var promise = this.whenValidate(options);
|
1444
|
+
if (!promise) // If excluded with `group` option
|
1445
|
+
return true;
|
1446
|
+
switch (promise.state()) {
|
1447
|
+
case 'pending':
|
1448
|
+
return null;
|
1449
|
+
case 'resolved':
|
1450
|
+
return true;
|
1451
|
+
case 'rejected':
|
1452
|
+
return this.validationResult;
|
1453
|
+
}
|
1454
|
+
},
|
1455
|
+
|
1456
|
+
// Validate field and trigger some events for mainly `ParsleyUI`
|
1457
|
+
// @returns a promise that succeeds only when all validations do
|
1458
|
+
// or `undefined` if field is not in the given `group`.
|
1459
|
+
whenValidate: function whenValidate() {
|
1460
|
+
var _whenValid$always$done$fail$always,
|
1461
|
+
_this9 = this;
|
1462
|
+
|
1463
|
+
var _ref9 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
1464
|
+
|
1465
|
+
var force = _ref9.force;
|
1466
|
+
var group = _ref9.group;
|
1467
|
+
|
1468
|
+
// do not validate a field if not the same as given validation group
|
1469
|
+
this.refreshConstraints();
|
1470
|
+
if (group && !this._isInGroup(group)) return;
|
1471
|
+
|
1542
1472
|
this.value = this.getValue();
|
1473
|
+
|
1543
1474
|
// Field Validate event. `this.value` could be altered for custom needs
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
this.
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1475
|
+
this._trigger('validate');
|
1476
|
+
|
1477
|
+
return (_whenValid$always$done$fail$always = this.whenValid({ force: force, value: this.value, _refreshed: true }).always(function () {
|
1478
|
+
_this9._reflowUI();
|
1479
|
+
}).done(function () {
|
1480
|
+
_this9._trigger('success');
|
1481
|
+
}).fail(function () {
|
1482
|
+
_this9._trigger('error');
|
1483
|
+
}).always(function () {
|
1484
|
+
_this9._trigger('validated');
|
1485
|
+
})).pipe.apply(_whenValid$always$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
|
1486
|
+
},
|
1487
|
+
|
1488
|
+
hasConstraints: function hasConstraints() {
|
1489
|
+
return 0 !== this.constraints.length;
|
1490
|
+
},
|
1491
|
+
|
1492
|
+
// An empty optional field does not need validation
|
1493
|
+
needsValidation: function needsValidation(value) {
|
1494
|
+
if ('undefined' === typeof value) value = this.getValue();
|
1495
|
+
|
1496
|
+
// If a field is empty and not required, it is valid
|
1563
1497
|
// Except if `data-parsley-validate-if-empty` explicitely added, useful for some custom validators
|
1564
|
-
if (!value.length && !this._isRequired() && 'undefined' === typeof this.options.validateIfEmpty
|
1565
|
-
|
1566
|
-
// If we want to validate field against all constraints, just call Validator and let it do the job
|
1567
|
-
if (false === this.options.priorityEnabled)
|
1568
|
-
return true === (this.validationResult = this.validateThroughValidator(value, this.constraints, 'Any'));
|
1569
|
-
// Else, iterate over priorities one by one, and validate related asserts one by one
|
1570
|
-
for (var i = 0; i < priorities.length; i++)
|
1571
|
-
if (true !== (this.validationResult = this.validateThroughValidator(value, this.constraints, priorities[i])))
|
1572
|
-
return false;
|
1498
|
+
if (!value.length && !this._isRequired() && 'undefined' === typeof this.options.validateIfEmpty) return false;
|
1499
|
+
|
1573
1500
|
return true;
|
1574
1501
|
},
|
1502
|
+
|
1503
|
+
_isInGroup: function _isInGroup(group) {
|
1504
|
+
if ($.isArray(this.options.group)) return -1 !== $.inArray(group, this.options.group);
|
1505
|
+
return this.options.group === group;
|
1506
|
+
},
|
1507
|
+
|
1508
|
+
// Just validate field. Do not trigger any event.
|
1509
|
+
// Returns `true` iff all constraints pass, `false` if there are failures,
|
1510
|
+
// or `null` if the result can not be determined yet (depends on a promise)
|
1511
|
+
// See also `whenValid`.
|
1512
|
+
isValid: function isValid(options) {
|
1513
|
+
if (arguments.length >= 1 && !$.isPlainObject(options)) {
|
1514
|
+
ParsleyUtils__default.warnOnce('Calling isValid on a parsley field without passing arguments as an object is deprecated.');
|
1515
|
+
|
1516
|
+
var _arguments3 = _slice.call(arguments);
|
1517
|
+
|
1518
|
+
var force = _arguments3[0];
|
1519
|
+
var value = _arguments3[1];
|
1520
|
+
|
1521
|
+
options = { force: force, value: value };
|
1522
|
+
}
|
1523
|
+
var promise = this.whenValid(options);
|
1524
|
+
if (!promise) // Excluded via `group`
|
1525
|
+
return true;
|
1526
|
+
return parsley_field__statusMapping[promise.state()];
|
1527
|
+
},
|
1528
|
+
|
1529
|
+
// Just validate field. Do not trigger any event.
|
1530
|
+
// @returns a promise that succeeds only when all validations do
|
1531
|
+
// or `undefined` if the field is not in the given `group`.
|
1532
|
+
// The argument `force` will force validation of empty fields.
|
1533
|
+
// If a `value` is given, it will be validated instead of the value of the input.
|
1534
|
+
whenValid: function whenValid() {
|
1535
|
+
var _this10 = this;
|
1536
|
+
|
1537
|
+
var _ref10 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
1538
|
+
|
1539
|
+
var _ref10$force = _ref10.force;
|
1540
|
+
var force = _ref10$force === undefined ? false : _ref10$force;
|
1541
|
+
var value = _ref10.value;
|
1542
|
+
var group = _ref10.group;
|
1543
|
+
var _refreshed = _ref10._refreshed;
|
1544
|
+
|
1545
|
+
// Recompute options and rebind constraints to have latest changes
|
1546
|
+
if (!_refreshed) this.refreshConstraints();
|
1547
|
+
// do not validate a field if not the same as given validation group
|
1548
|
+
if (group && !this._isInGroup(group)) return;
|
1549
|
+
|
1550
|
+
this.validationResult = true;
|
1551
|
+
|
1552
|
+
// A field without constraint is valid
|
1553
|
+
if (!this.hasConstraints()) return $.when();
|
1554
|
+
|
1555
|
+
// Value could be passed as argument, needed to add more power to 'field:validate'
|
1556
|
+
if ('undefined' === typeof value || null === value) value = this.getValue();
|
1557
|
+
|
1558
|
+
if (!this.needsValidation(value) && true !== force) return $.when();
|
1559
|
+
|
1560
|
+
var groupedConstraints = this._getGroupedConstraints();
|
1561
|
+
var promises = [];
|
1562
|
+
$.each(groupedConstraints, function (_, constraints) {
|
1563
|
+
// Process one group of constraints at a time, we validate the constraints
|
1564
|
+
// and combine the promises together.
|
1565
|
+
var promise = ParsleyUtils__default.all($.map(constraints, function (constraint) {
|
1566
|
+
return _this10._validateConstraint(value, constraint);
|
1567
|
+
}));
|
1568
|
+
promises.push(promise);
|
1569
|
+
if (promise.state() === 'rejected') return false; // Interrupt processing if a group has already failed
|
1570
|
+
});
|
1571
|
+
return ParsleyUtils__default.all(promises);
|
1572
|
+
},
|
1573
|
+
|
1574
|
+
// @returns a promise
|
1575
|
+
_validateConstraint: function _validateConstraint(value, constraint) {
|
1576
|
+
var _this11 = this;
|
1577
|
+
|
1578
|
+
var result = constraint.validate(value, this);
|
1579
|
+
// Map false to a failed promise
|
1580
|
+
if (false === result) result = $.Deferred().reject();
|
1581
|
+
// Make sure we return a promise and that we record failures
|
1582
|
+
return ParsleyUtils__default.all([result]).fail(function (errorMessage) {
|
1583
|
+
if (!(_this11.validationResult instanceof Array)) _this11.validationResult = [];
|
1584
|
+
_this11.validationResult.push({
|
1585
|
+
assert: constraint,
|
1586
|
+
errorMessage: 'string' === typeof errorMessage && errorMessage
|
1587
|
+
});
|
1588
|
+
});
|
1589
|
+
},
|
1590
|
+
|
1575
1591
|
// @returns Parsley field computed value that could be overrided or configured in DOM
|
1576
|
-
getValue: function () {
|
1592
|
+
getValue: function getValue() {
|
1577
1593
|
var value;
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
value = this.$element.val();
|
1594
|
+
|
1595
|
+
// Value could be overriden in DOM or with explicit options
|
1596
|
+
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();
|
1597
|
+
|
1583
1598
|
// Handle wrong DOM or configurations
|
1584
|
-
if ('undefined' === typeof value || null === value)
|
1585
|
-
|
1586
|
-
|
1587
|
-
if (true === this.options.trimValue)
|
1588
|
-
return value.replace(/^\s+|\s+$/g, '');
|
1589
|
-
return value;
|
1599
|
+
if ('undefined' === typeof value || null === value) return '';
|
1600
|
+
|
1601
|
+
return this._handleWhitespace(value);
|
1590
1602
|
},
|
1603
|
+
|
1591
1604
|
// Actualize options that could have change since previous validation
|
1592
1605
|
// Re-bind accordingly constraints (could be some new, removed or updated)
|
1593
|
-
refreshConstraints: function () {
|
1606
|
+
refreshConstraints: function refreshConstraints() {
|
1594
1607
|
return this.actualizeOptions()._bindConstraints();
|
1595
1608
|
},
|
1609
|
+
|
1596
1610
|
/**
|
1597
1611
|
* Add a new constraint to a field
|
1598
1612
|
*
|
1599
|
-
* @method addConstraint
|
1600
1613
|
* @param {String} name
|
1601
1614
|
* @param {Mixed} requirements optional
|
1602
1615
|
* @param {Number} priority optional
|
1603
1616
|
* @param {Boolean} isDomConstraint optional
|
1604
1617
|
*/
|
1605
|
-
addConstraint: function (name, requirements, priority, isDomConstraint) {
|
1606
|
-
|
1607
|
-
if (
|
1618
|
+
addConstraint: function addConstraint(name, requirements, priority, isDomConstraint) {
|
1619
|
+
|
1620
|
+
if (window.Parsley._validatorRegistry.validators[name]) {
|
1608
1621
|
var constraint = new ConstraintFactory(this, name, requirements, priority, isDomConstraint);
|
1622
|
+
|
1609
1623
|
// if constraint already exist, delete it and push new version
|
1610
|
-
if ('undefined' !== this.constraintsByName[constraint.name])
|
1611
|
-
|
1624
|
+
if ('undefined' !== this.constraintsByName[constraint.name]) this.removeConstraint(constraint.name);
|
1625
|
+
|
1612
1626
|
this.constraints.push(constraint);
|
1613
1627
|
this.constraintsByName[constraint.name] = constraint;
|
1614
1628
|
}
|
1629
|
+
|
1615
1630
|
return this;
|
1616
1631
|
},
|
1632
|
+
|
1617
1633
|
// Remove a constraint
|
1618
|
-
removeConstraint: function (name) {
|
1619
|
-
for (var i = 0; i < this.constraints.length; i++)
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
}
|
1634
|
+
removeConstraint: function removeConstraint(name) {
|
1635
|
+
for (var i = 0; i < this.constraints.length; i++) if (name === this.constraints[i].name) {
|
1636
|
+
this.constraints.splice(i, 1);
|
1637
|
+
break;
|
1638
|
+
}
|
1624
1639
|
delete this.constraintsByName[name];
|
1625
1640
|
return this;
|
1626
1641
|
},
|
1642
|
+
|
1627
1643
|
// Update a constraint (Remove + re-add)
|
1628
|
-
updateConstraint: function (name, parameters, priority) {
|
1629
|
-
return this.removeConstraint(name)
|
1630
|
-
.addConstraint(name, parameters, priority);
|
1644
|
+
updateConstraint: function updateConstraint(name, parameters, priority) {
|
1645
|
+
return this.removeConstraint(name).addConstraint(name, parameters, priority);
|
1631
1646
|
},
|
1647
|
+
|
1632
1648
|
// # Internals
|
1649
|
+
|
1633
1650
|
// Internal only.
|
1634
1651
|
// Bind constraints from config + options + DOM
|
1635
|
-
_bindConstraints: function () {
|
1636
|
-
var constraints = []
|
1652
|
+
_bindConstraints: function _bindConstraints() {
|
1653
|
+
var constraints = [];
|
1654
|
+
var constraintsByName = {};
|
1655
|
+
|
1637
1656
|
// clean all existing DOM constraints to only keep javascript user constraints
|
1638
|
-
for (var i = 0; i < this.constraints.length; i++)
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1642
|
-
|
1657
|
+
for (var i = 0; i < this.constraints.length; i++) if (false === this.constraints[i].isDomConstraint) {
|
1658
|
+
constraints.push(this.constraints[i]);
|
1659
|
+
constraintsByName[this.constraints[i].name] = this.constraints[i];
|
1660
|
+
}
|
1661
|
+
|
1643
1662
|
this.constraints = constraints;
|
1644
1663
|
this.constraintsByName = constraintsByName;
|
1664
|
+
|
1645
1665
|
// then re-add Parsley DOM-API constraints
|
1646
|
-
for (var name in this.options)
|
1647
|
-
|
1666
|
+
for (var name in this.options) this.addConstraint(name, this.options[name], undefined, true);
|
1667
|
+
|
1648
1668
|
// finally, bind special HTML5 constraints
|
1649
1669
|
return this._bindHtml5Constraints();
|
1650
1670
|
},
|
1671
|
+
|
1651
1672
|
// Internal only.
|
1652
1673
|
// Bind specific HTML5 constraints to be HTML5 compliant
|
1653
|
-
_bindHtml5Constraints: function () {
|
1674
|
+
_bindHtml5Constraints: function _bindHtml5Constraints() {
|
1654
1675
|
// html5 required
|
1655
|
-
if (this.$element.hasClass('required') || this.$element.attr('required'))
|
1656
|
-
|
1676
|
+
if (this.$element.hasClass('required') || this.$element.attr('required')) this.addConstraint('required', true, undefined, true);
|
1677
|
+
|
1657
1678
|
// html5 pattern
|
1658
|
-
if ('string' === typeof this.$element.attr('pattern'))
|
1659
|
-
|
1679
|
+
if ('string' === typeof this.$element.attr('pattern')) this.addConstraint('pattern', this.$element.attr('pattern'), undefined, true);
|
1680
|
+
|
1660
1681
|
// range
|
1661
|
-
if ('undefined' !== typeof this.$element.attr('min') && 'undefined' !== typeof this.$element.attr('max'))
|
1662
|
-
|
1682
|
+
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);
|
1683
|
+
|
1663
1684
|
// HTML5 min
|
1664
|
-
else if ('undefined' !== typeof this.$element.attr('min'))
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1685
|
+
else if ('undefined' !== typeof this.$element.attr('min')) this.addConstraint('min', this.$element.attr('min'), undefined, true);
|
1686
|
+
|
1687
|
+
// HTML5 max
|
1688
|
+
else if ('undefined' !== typeof this.$element.attr('max')) this.addConstraint('max', this.$element.attr('max'), undefined, true);
|
1689
|
+
|
1670
1690
|
// length
|
1671
|
-
if ('undefined' !== typeof this.$element.attr('minlength') && 'undefined' !== typeof this.$element.attr('maxlength'))
|
1672
|
-
|
1691
|
+
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);
|
1692
|
+
|
1673
1693
|
// HTML5 minlength
|
1674
|
-
else if ('undefined' !== typeof this.$element.attr('minlength'))
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
1678
|
-
this.addConstraint('maxlength', this.$element.attr('maxlength'), undefined, true);
|
1694
|
+
else if ('undefined' !== typeof this.$element.attr('minlength')) this.addConstraint('minlength', this.$element.attr('minlength'), undefined, true);
|
1695
|
+
|
1696
|
+
// HTML5 maxlength
|
1697
|
+
else if ('undefined' !== typeof this.$element.attr('maxlength')) this.addConstraint('maxlength', this.$element.attr('maxlength'), undefined, true);
|
1679
1698
|
|
1680
1699
|
// html5 types
|
1681
1700
|
var type = this.$element.attr('type');
|
1682
|
-
|
1683
|
-
|
1701
|
+
|
1702
|
+
if ('undefined' === typeof type) return this;
|
1703
|
+
|
1684
1704
|
// Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise
|
1685
1705
|
if ('number' === type) {
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1706
|
+
return this.addConstraint('type', ['number', {
|
1707
|
+
step: this.$element.attr('step'),
|
1708
|
+
base: this.$element.attr('min') || this.$element.attr('value')
|
1709
|
+
}], undefined, true);
|
1710
|
+
// Regular other HTML5 supported types
|
1711
|
+
} else if (/^(email|url|range)$/i.test(type)) {
|
1712
|
+
return this.addConstraint('type', type, undefined, true);
|
1690
1713
|
}
|
1691
|
-
// Regular other HTML5 supported types
|
1692
|
-
} else if (new RegExp(type, 'i').test('email url range')) {
|
1693
|
-
return this.addConstraint('type', type, undefined, true);
|
1694
|
-
}
|
1695
1714
|
return this;
|
1696
1715
|
},
|
1716
|
+
|
1697
1717
|
// Internal only.
|
1698
1718
|
// Field is required if have required constraint without `false` value
|
1699
|
-
_isRequired: function () {
|
1700
|
-
if ('undefined' === typeof this.constraintsByName.required)
|
1701
|
-
|
1719
|
+
_isRequired: function _isRequired() {
|
1720
|
+
if ('undefined' === typeof this.constraintsByName.required) return false;
|
1721
|
+
|
1702
1722
|
return false !== this.constraintsByName.required.requirements;
|
1703
1723
|
},
|
1724
|
+
|
1725
|
+
// Internal only.
|
1726
|
+
// Shortcut to trigger an event
|
1727
|
+
_trigger: function _trigger(eventName) {
|
1728
|
+
return this.trigger('field:' + eventName);
|
1729
|
+
},
|
1730
|
+
|
1731
|
+
// Internal only
|
1732
|
+
// Handles whitespace in a value
|
1733
|
+
// Use `data-parsley-whitespace="squish"` to auto squish input value
|
1734
|
+
// Use `data-parsley-whitespace="trim"` to auto trim input value
|
1735
|
+
_handleWhitespace: function _handleWhitespace(value) {
|
1736
|
+
if (true === this.options.trimValue) ParsleyUtils__default.warnOnce('data-parsley-trim-value="true" is deprecated, please use data-parsley-whitespace="trim"');
|
1737
|
+
|
1738
|
+
if ('squish' === this.options.whitespace) value = value.replace(/\s{2,}/g, ' ');
|
1739
|
+
|
1740
|
+
if ('trim' === this.options.whitespace || 'squish' === this.options.whitespace || true === this.options.trimValue) value = ParsleyUtils__default.trimString(value);
|
1741
|
+
|
1742
|
+
return value;
|
1743
|
+
},
|
1744
|
+
|
1704
1745
|
// Internal only.
|
1705
|
-
//
|
1706
|
-
|
1707
|
-
|
1746
|
+
// Returns the constraints, grouped by descending priority.
|
1747
|
+
// The result is thus an array of arrays of constraints.
|
1748
|
+
_getGroupedConstraints: function _getGroupedConstraints() {
|
1749
|
+
if (false === this.options.priorityEnabled) return [this.constraints];
|
1750
|
+
|
1751
|
+
var groupedConstraints = [];
|
1752
|
+
var index = {};
|
1753
|
+
|
1708
1754
|
// Create array unique of priorities
|
1709
|
-
for (var i = 0; i < this.constraints.length; i++)
|
1710
|
-
|
1711
|
-
|
1755
|
+
for (var i = 0; i < this.constraints.length; i++) {
|
1756
|
+
var p = this.constraints[i].priority;
|
1757
|
+
if (!index[p]) groupedConstraints.push(index[p] = []);
|
1758
|
+
index[p].push(this.constraints[i]);
|
1759
|
+
}
|
1712
1760
|
// Sort them by priority DESC
|
1713
|
-
|
1714
|
-
|
1761
|
+
groupedConstraints.sort(function (a, b) {
|
1762
|
+
return b[0].priority - a[0].priority;
|
1763
|
+
});
|
1764
|
+
|
1765
|
+
return groupedConstraints;
|
1715
1766
|
}
|
1767
|
+
|
1716
1768
|
};
|
1717
1769
|
|
1718
|
-
var
|
1770
|
+
var parsley_field = ParsleyField;
|
1771
|
+
|
1772
|
+
var ParsleyMultiple = function ParsleyMultiple() {
|
1719
1773
|
this.__class__ = 'ParsleyFieldMultiple';
|
1720
1774
|
};
|
1775
|
+
|
1721
1776
|
ParsleyMultiple.prototype = {
|
1722
1777
|
// Add new `$element` sibling for multiple field
|
1723
|
-
addElement: function ($element) {
|
1778
|
+
addElement: function addElement($element) {
|
1724
1779
|
this.$elements.push($element);
|
1780
|
+
|
1725
1781
|
return this;
|
1726
1782
|
},
|
1783
|
+
|
1727
1784
|
// See `ParsleyField.refreshConstraints()`
|
1728
|
-
refreshConstraints: function () {
|
1785
|
+
refreshConstraints: function refreshConstraints() {
|
1729
1786
|
var fieldConstraints;
|
1787
|
+
|
1730
1788
|
this.constraints = [];
|
1789
|
+
|
1731
1790
|
// Select multiple special treatment
|
1732
1791
|
if (this.$element.is('select')) {
|
1733
1792
|
this.actualizeOptions()._bindConstraints();
|
1793
|
+
|
1734
1794
|
return this;
|
1735
1795
|
}
|
1796
|
+
|
1736
1797
|
// Gather all constraints for each input in the multiple group
|
1737
1798
|
for (var i = 0; i < this.$elements.length; i++) {
|
1799
|
+
|
1738
1800
|
// Check if element have not been dynamically removed since last binding
|
1739
1801
|
if (!$('html').has(this.$elements[i]).length) {
|
1740
1802
|
this.$elements.splice(i, 1);
|
1741
1803
|
continue;
|
1742
1804
|
}
|
1805
|
+
|
1743
1806
|
fieldConstraints = this.$elements[i].data('ParsleyFieldMultiple').refreshConstraints().constraints;
|
1744
|
-
|
1745
|
-
|
1807
|
+
|
1808
|
+
for (var j = 0; j < fieldConstraints.length; j++) this.addConstraint(fieldConstraints[j].name, fieldConstraints[j].requirements, fieldConstraints[j].priority, fieldConstraints[j].isDomConstraint);
|
1746
1809
|
}
|
1810
|
+
|
1747
1811
|
return this;
|
1748
1812
|
},
|
1813
|
+
|
1749
1814
|
// See `ParsleyField.getValue()`
|
1750
|
-
getValue: function () {
|
1815
|
+
getValue: function getValue() {
|
1751
1816
|
// Value could be overriden in DOM
|
1752
|
-
if ('undefined' !== typeof this.options.value)
|
1753
|
-
|
1817
|
+
if ('function' === typeof this.options.value) return this.options.value(this);else if ('undefined' !== typeof this.options.value) return this.options.value;
|
1818
|
+
|
1754
1819
|
// Radio input case
|
1755
|
-
if (this.$element.is('input[type=radio]'))
|
1756
|
-
|
1820
|
+
if (this.$element.is('input[type=radio]')) return this._findRelated().filter(':checked').val() || '';
|
1821
|
+
|
1757
1822
|
// checkbox input case
|
1758
1823
|
if (this.$element.is('input[type=checkbox]')) {
|
1759
1824
|
var values = [];
|
1760
|
-
|
1825
|
+
|
1826
|
+
this._findRelated().filter(':checked').each(function () {
|
1761
1827
|
values.push($(this).val());
|
1762
1828
|
});
|
1763
|
-
|
1829
|
+
|
1830
|
+
return values;
|
1764
1831
|
}
|
1832
|
+
|
1765
1833
|
// Select multiple case
|
1766
|
-
if (this.$element.is('select') && null === this.$element.val())
|
1767
|
-
|
1834
|
+
if (this.$element.is('select') && null === this.$element.val()) return [];
|
1835
|
+
|
1768
1836
|
// Default case that should never happen
|
1769
1837
|
return this.$element.val();
|
1770
1838
|
},
|
1771
|
-
|
1839
|
+
|
1840
|
+
_init: function _init() {
|
1772
1841
|
this.$elements = [this.$element];
|
1773
|
-
|
1842
|
+
|
1774
1843
|
return this;
|
1775
1844
|
}
|
1776
1845
|
};
|
1777
1846
|
|
1778
|
-
var
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1786
|
-
|
1787
|
-
|
1788
|
-
|
1789
|
-
return subscribed[name].push({ fn: arguments[2], ctxt: arguments[1] });
|
1790
|
-
throw new Error('Wrong parameters');
|
1791
|
-
};
|
1792
|
-
$.listenTo = function (instance, name, fn) {
|
1793
|
-
if ('undefined' === typeof subscribed[name])
|
1794
|
-
subscribed[name] = [];
|
1795
|
-
if (!(instance instanceof ParsleyField) && !(instance instanceof ParsleyForm))
|
1796
|
-
throw new Error('Must give Parsley instance');
|
1797
|
-
if ('string' !== typeof name || 'function' !== typeof fn)
|
1798
|
-
throw new Error('Wrong parameters');
|
1799
|
-
subscribed[name].push({ instance: instance, fn: fn });
|
1800
|
-
};
|
1801
|
-
$.unsubscribe = function (name, fn) {
|
1802
|
-
if ('undefined' === typeof subscribed[name])
|
1803
|
-
return;
|
1804
|
-
if ('string' !== typeof name || 'function' !== typeof fn)
|
1805
|
-
throw new Error('Wrong arguments');
|
1806
|
-
for (var i = 0; i < subscribed[name].length; i++)
|
1807
|
-
if (subscribed[name][i].fn === fn)
|
1808
|
-
return subscribed[name].splice(i, 1);
|
1809
|
-
};
|
1810
|
-
$.unsubscribeTo = function (instance, name) {
|
1811
|
-
if ('undefined' === typeof subscribed[name])
|
1812
|
-
return;
|
1813
|
-
if (!(instance instanceof ParsleyField) && !(instance instanceof ParsleyForm))
|
1814
|
-
throw new Error('Must give Parsley instance');
|
1815
|
-
for (var i = 0; i < subscribed[name].length; i++)
|
1816
|
-
if ('undefined' !== typeof subscribed[name][i].instance && subscribed[name][i].instance.__id__ === instance.__id__)
|
1817
|
-
return subscribed[name].splice(i, 1);
|
1818
|
-
};
|
1819
|
-
$.unsubscribeAll = function (name) {
|
1820
|
-
if ('undefined' === typeof subscribed[name])
|
1821
|
-
return;
|
1822
|
-
delete subscribed[name];
|
1823
|
-
};
|
1824
|
-
// $.emit(name [, arguments...]);
|
1825
|
-
// $.emit(name, instance [, arguments...]);
|
1826
|
-
$.emit = function (name, instance) {
|
1827
|
-
if ('undefined' === typeof subscribed[name])
|
1828
|
-
return;
|
1829
|
-
// loop through registered callbacks for this event
|
1830
|
-
for (var i = 0; i < subscribed[name].length; i++) {
|
1831
|
-
// if instance is not registered, simple emit
|
1832
|
-
if ('undefined' === typeof subscribed[name][i].instance) {
|
1833
|
-
subscribed[name][i].fn.apply('undefined' !== typeof subscribed[name][i].ctxt ? subscribed[name][i].ctxt : o, Array.prototype.slice.call(arguments, 1));
|
1834
|
-
continue;
|
1847
|
+
var ParsleyFactory = function ParsleyFactory(element, options, parsleyFormInstance) {
|
1848
|
+
this.$element = $(element);
|
1849
|
+
|
1850
|
+
// If the element has already been bound, returns its saved Parsley instance
|
1851
|
+
var savedparsleyFormInstance = this.$element.data('Parsley');
|
1852
|
+
if (savedparsleyFormInstance) {
|
1853
|
+
|
1854
|
+
// If the saved instance has been bound without a ParsleyForm parent and there is one given in this call, add it
|
1855
|
+
if ('undefined' !== typeof parsleyFormInstance && savedparsleyFormInstance.parent === window.Parsley) {
|
1856
|
+
savedparsleyFormInstance.parent = parsleyFormInstance;
|
1857
|
+
savedparsleyFormInstance._resetOptions(savedparsleyFormInstance.options);
|
1835
1858
|
}
|
1836
|
-
|
1837
|
-
if (
|
1838
|
-
|
1839
|
-
// if instance is registered and same id, emit
|
1840
|
-
if (subscribed[name][i].instance.__id__ === instance.__id__) {
|
1841
|
-
subscribed[name][i].fn.apply(o, Array.prototype.slice.call(arguments, 1));
|
1842
|
-
continue;
|
1859
|
+
|
1860
|
+
if ('object' === typeof options) {
|
1861
|
+
$.extend(savedparsleyFormInstance.options, options);
|
1843
1862
|
}
|
1844
|
-
|
1845
|
-
|
1846
|
-
for (var j = 0; j < subscribed[name][i].instance.fields.length; j++)
|
1847
|
-
if (subscribed[name][i].instance.fields[j].__id__ === instance.__id__) {
|
1848
|
-
subscribed[name][i].fn.apply(o, Array.prototype.slice.call(arguments, 1));
|
1849
|
-
continue;
|
1850
|
-
}
|
1863
|
+
|
1864
|
+
return savedparsleyFormInstance;
|
1851
1865
|
}
|
1852
|
-
|
1853
|
-
$.subscribed = function () { return subscribed; };
|
1854
|
-
|
1855
|
-
// ParsleyConfig definition if not already set
|
1856
|
-
window.ParsleyConfig = window.ParsleyConfig || {};
|
1857
|
-
window.ParsleyConfig.i18n = window.ParsleyConfig.i18n || {};
|
1858
|
-
// Define then the messages
|
1859
|
-
window.ParsleyConfig.i18n.en = $.extend(window.ParsleyConfig.i18n.en || {}, {
|
1860
|
-
defaultMessage: "This value seems to be invalid.",
|
1861
|
-
type: {
|
1862
|
-
email: "This value should be a valid email.",
|
1863
|
-
url: "This value should be a valid url.",
|
1864
|
-
number: "This value should be a valid number.",
|
1865
|
-
integer: "This value should be a valid integer.",
|
1866
|
-
digits: "This value should be digits.",
|
1867
|
-
alphanum: "This value should be alphanumeric."
|
1868
|
-
},
|
1869
|
-
notblank: "This value should not be blank.",
|
1870
|
-
required: "This value is required.",
|
1871
|
-
pattern: "This value seems to be invalid.",
|
1872
|
-
min: "This value should be greater than or equal to %s.",
|
1873
|
-
max: "This value should be lower than or equal to %s.",
|
1874
|
-
range: "This value should be between %s and %s.",
|
1875
|
-
minlength: "This value is too short. It should have %s characters or more.",
|
1876
|
-
maxlength: "This value is too long. It should have %s characters or fewer.",
|
1877
|
-
length: "This value length is invalid. It should be between %s and %s characters long.",
|
1878
|
-
mincheck: "You must select at least %s choices.",
|
1879
|
-
maxcheck: "You must select %s choices or fewer.",
|
1880
|
-
check: "You must select between %s and %s choices.",
|
1881
|
-
equalto: "This value should be the same."
|
1882
|
-
});
|
1883
|
-
// If file is loaded after Parsley main file, auto-load locale
|
1884
|
-
if ('undefined' !== typeof window.ParsleyValidator)
|
1885
|
-
window.ParsleyValidator.addCatalog('en', window.ParsleyConfig.i18n.en, true);
|
1886
|
-
|
1887
|
-
// Parsley.js 2.0.6
|
1888
|
-
// http://parsleyjs.org
|
1889
|
-
// (c) 20012-2014 Guillaume Potier, Wisembly
|
1890
|
-
// Parsley may be freely distributed under the MIT license.
|
1891
|
-
|
1892
|
-
// ### Parsley factory
|
1893
|
-
var Parsley = function (element, options, parsleyFormInstance) {
|
1894
|
-
this.__class__ = 'Parsley';
|
1895
|
-
this.__version__ = '2.0.6';
|
1896
|
-
this.__id__ = ParsleyUtils.hash(4);
|
1866
|
+
|
1897
1867
|
// Parsley must be instantiated with a DOM element or jQuery $element
|
1898
|
-
if ('
|
1899
|
-
|
1900
|
-
if ('undefined' !== typeof parsleyFormInstance && 'ParsleyForm' !== parsleyFormInstance.__class__)
|
1901
|
-
|
1902
|
-
|
1868
|
+
if (!this.$element.length) throw new Error('You must bind Parsley on an existing element.');
|
1869
|
+
|
1870
|
+
if ('undefined' !== typeof parsleyFormInstance && 'ParsleyForm' !== parsleyFormInstance.__class__) throw new Error('Parent instance must be a ParsleyForm instance');
|
1871
|
+
|
1872
|
+
this.parent = parsleyFormInstance || window.Parsley;
|
1873
|
+
return this.init(options);
|
1903
1874
|
};
|
1904
|
-
|
1905
|
-
|
1906
|
-
|
1907
|
-
|
1908
|
-
this
|
1909
|
-
|
1910
|
-
|
1911
|
-
|
1912
|
-
|
1913
|
-
|
1914
|
-
|
1915
|
-
|
1916
|
-
|
1917
|
-
//
|
1918
|
-
this.
|
1919
|
-
this.options = this.OptionsFactory.get(this);
|
1920
|
-
// A ParsleyForm instance is obviously a `<form>` elem but also every node that is not an input and have `data-parsley-validate` attribute
|
1921
|
-
if (this.$element.is('form') || (ParsleyUtils.attr(this.$element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)))
|
1922
|
-
return this.bind('parsleyForm');
|
1923
|
-
// Every other supported element and not excluded element is binded as a `ParsleyField` or `ParsleyFieldMultiple`
|
1924
|
-
else if (this.$element.is(this.options.inputs) && !this.$element.is(this.options.excluded))
|
1925
|
-
return this.isMultiple() ? this.handleMultiple(parsleyFormInstance) : this.bind('parsleyField', parsleyFormInstance);
|
1926
|
-
return this;
|
1875
|
+
|
1876
|
+
ParsleyFactory.prototype = {
|
1877
|
+
init: function init(options) {
|
1878
|
+
this.__class__ = 'Parsley';
|
1879
|
+
this.__version__ = '2.4.4';
|
1880
|
+
this.__id__ = ParsleyUtils__default.generateID();
|
1881
|
+
|
1882
|
+
// Pre-compute options
|
1883
|
+
this._resetOptions(options);
|
1884
|
+
|
1885
|
+
// A ParsleyForm instance is obviously a `<form>` element but also every node that is not an input and has the `data-parsley-validate` attribute
|
1886
|
+
if (this.$element.is('form') || ParsleyUtils__default.checkAttr(this.$element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)) return this.bind('parsleyForm');
|
1887
|
+
|
1888
|
+
// Every other element is bound as a `ParsleyField` or `ParsleyFieldMultiple`
|
1889
|
+
return this.isMultiple() ? this.handleMultiple() : this.bind('parsleyField');
|
1927
1890
|
},
|
1928
|
-
|
1929
|
-
|
1891
|
+
|
1892
|
+
isMultiple: function isMultiple() {
|
1893
|
+
return this.$element.is('input[type=radio], input[type=checkbox]') || this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple');
|
1930
1894
|
},
|
1895
|
+
|
1931
1896
|
// Multiples fields are a real nightmare :(
|
1932
|
-
// Maybe some
|
1933
|
-
handleMultiple: function (
|
1934
|
-
var
|
1935
|
-
|
1936
|
-
|
1937
|
-
|
1938
|
-
|
1939
|
-
|
1940
|
-
this.options = $.extend(this.options, parsleyFormInstance ? parsleyFormInstance.OptionsFactory.get(parsleyFormInstance) : {}, ParsleyUtils.attr(this.$element, this.options.namespace));
|
1897
|
+
// Maybe some refactoring would be appreciated here...
|
1898
|
+
handleMultiple: function handleMultiple() {
|
1899
|
+
var _this12 = this;
|
1900
|
+
|
1901
|
+
var name;
|
1902
|
+
var multiple;
|
1903
|
+
var parsleyMultipleInstance;
|
1904
|
+
|
1941
1905
|
// Handle multiple name
|
1942
|
-
if (this.options.multiple)
|
1943
|
-
|
1944
|
-
|
1945
|
-
multiple = name = this.$element.attr('name');
|
1946
|
-
else if ('undefined' !== typeof this.$element.attr('id') && this.$element.attr('id').length)
|
1947
|
-
multiple = this.$element.attr('id');
|
1906
|
+
if (this.options.multiple) ; // We already have our 'multiple' identifier
|
1907
|
+
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');
|
1908
|
+
|
1948
1909
|
// Special select multiple input
|
1949
1910
|
if (this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple')) {
|
1950
|
-
|
1951
|
-
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1955
|
-
|
1956
|
-
|
1911
|
+
this.options.multiple = this.options.multiple || this.__id__;
|
1912
|
+
return this.bind('parsleyFieldMultiple');
|
1913
|
+
|
1914
|
+
// Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it
|
1915
|
+
} else if (!this.options.multiple) {
|
1916
|
+
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);
|
1917
|
+
return this;
|
1918
|
+
}
|
1919
|
+
|
1957
1920
|
// Remove special chars
|
1958
|
-
multiple = multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g, '');
|
1921
|
+
this.options.multiple = this.options.multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g, '');
|
1922
|
+
|
1959
1923
|
// Add proper `data-parsley-multiple` to siblings if we have a valid multiple name
|
1960
1924
|
if ('undefined' !== typeof name) {
|
1961
|
-
$('input[name="' + name + '"]').each(function () {
|
1962
|
-
if ($(
|
1963
|
-
$(this).attr(that.options.namespace + 'multiple', multiple);
|
1925
|
+
$('input[name="' + name + '"]').each(function (i, input) {
|
1926
|
+
if ($(input).is('input[type=radio], input[type=checkbox]')) $(input).attr(_this12.options.namespace + 'multiple', _this12.options.multiple);
|
1964
1927
|
});
|
1965
1928
|
}
|
1929
|
+
|
1966
1930
|
// Check here if we don't already have a related multiple instance saved
|
1967
|
-
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
|
1973
|
-
|
1974
|
-
}
|
1975
|
-
break;
|
1931
|
+
var $previouslyRelated = this._findRelated();
|
1932
|
+
for (var i = 0; i < $previouslyRelated.length; i++) {
|
1933
|
+
parsleyMultipleInstance = $($previouslyRelated.get(i)).data('Parsley');
|
1934
|
+
if ('undefined' !== typeof parsleyMultipleInstance) {
|
1935
|
+
|
1936
|
+
if (!this.$element.data('ParsleyFieldMultiple')) {
|
1937
|
+
parsleyMultipleInstance.addElement(this.$element);
|
1976
1938
|
}
|
1939
|
+
|
1940
|
+
break;
|
1977
1941
|
}
|
1978
1942
|
}
|
1979
|
-
|
1980
|
-
//
|
1981
|
-
|
1982
|
-
|
1983
|
-
|
1984
|
-
|
1985
|
-
getNamespace: function (options) {
|
1986
|
-
// `data-parsley-namespace=<namespace>`
|
1987
|
-
if ('undefined' !== typeof this.$element.data('parsleyNamespace'))
|
1988
|
-
return this.$element.data('parsleyNamespace');
|
1989
|
-
if ('undefined' !== typeof ParsleyUtils.get(options, 'namespace'))
|
1990
|
-
return options.namespace;
|
1991
|
-
if ('undefined' !== typeof ParsleyUtils.get(window, 'ParsleyConfig.namespace'))
|
1992
|
-
return window.ParsleyConfig.namespace;
|
1993
|
-
return ParsleyDefaults.namespace;
|
1943
|
+
|
1944
|
+
// Create a secret ParsleyField instance for every multiple field. It will be stored in `data('ParsleyFieldMultiple')`
|
1945
|
+
// And will be useful later to access classic `ParsleyField` stuff while being in a `ParsleyFieldMultiple` instance
|
1946
|
+
this.bind('parsleyField', true);
|
1947
|
+
|
1948
|
+
return parsleyMultipleInstance || this.bind('parsleyFieldMultiple');
|
1994
1949
|
},
|
1950
|
+
|
1995
1951
|
// Return proper `ParsleyForm`, `ParsleyField` or `ParsleyFieldMultiple`
|
1996
|
-
bind: function (type,
|
1952
|
+
bind: function bind(type, doNotStore) {
|
1997
1953
|
var parsleyInstance;
|
1954
|
+
|
1998
1955
|
switch (type) {
|
1999
1956
|
case 'parsleyForm':
|
2000
|
-
parsleyInstance = $.extend(
|
2001
|
-
new ParsleyForm(this.$element, this.OptionsFactory),
|
2002
|
-
new ParsleyAbstract(),
|
2003
|
-
window.ParsleyExtend
|
2004
|
-
)._bindFields();
|
1957
|
+
parsleyInstance = $.extend(new ParsleyForm(this.$element, this.domOptions, this.options), new ParsleyAbstract(), window.ParsleyExtend)._bindFields();
|
2005
1958
|
break;
|
2006
1959
|
case 'parsleyField':
|
2007
|
-
parsleyInstance = $.extend(
|
2008
|
-
new ParsleyField(this.$element, this.OptionsFactory, parentParsleyFormInstance),
|
2009
|
-
new ParsleyAbstract(),
|
2010
|
-
window.ParsleyExtend
|
2011
|
-
);
|
1960
|
+
parsleyInstance = $.extend(new parsley_field(this.$element, this.domOptions, this.options, this.parent), new ParsleyAbstract(), window.ParsleyExtend);
|
2012
1961
|
break;
|
2013
1962
|
case 'parsleyFieldMultiple':
|
2014
|
-
parsleyInstance = $.extend(
|
2015
|
-
new ParsleyField(this.$element, this.OptionsFactory, parentParsleyFormInstance),
|
2016
|
-
new ParsleyAbstract(),
|
2017
|
-
new ParsleyMultiple(),
|
2018
|
-
window.ParsleyExtend
|
2019
|
-
)._init(multiple);
|
1963
|
+
parsleyInstance = $.extend(new parsley_field(this.$element, this.domOptions, this.options, this.parent), new ParsleyMultiple(), new ParsleyAbstract(), window.ParsleyExtend)._init();
|
2020
1964
|
break;
|
2021
1965
|
default:
|
2022
1966
|
throw new Error(type + 'is not a supported Parsley type');
|
2023
1967
|
}
|
2024
|
-
|
2025
|
-
|
1968
|
+
|
1969
|
+
if (this.options.multiple) ParsleyUtils__default.setAttr(this.$element, this.options.namespace, 'multiple', this.options.multiple);
|
1970
|
+
|
2026
1971
|
if ('undefined' !== typeof doNotStore) {
|
2027
1972
|
this.$element.data('ParsleyFieldMultiple', parsleyInstance);
|
1973
|
+
|
2028
1974
|
return parsleyInstance;
|
2029
1975
|
}
|
2030
|
-
|
2031
|
-
|
2032
|
-
|
2033
|
-
|
2034
|
-
|
2035
|
-
|
2036
|
-
|
1976
|
+
|
1977
|
+
// Store the freshly bound instance in a DOM element for later access using jQuery `data()`
|
1978
|
+
this.$element.data('Parsley', parsleyInstance);
|
1979
|
+
|
1980
|
+
// Tell the world we have a new ParsleyForm or ParsleyField instance!
|
1981
|
+
parsleyInstance._actualizeTriggers();
|
1982
|
+
parsleyInstance._trigger('init');
|
1983
|
+
|
2037
1984
|
return parsleyInstance;
|
2038
1985
|
}
|
2039
1986
|
};
|
1987
|
+
|
1988
|
+
var vernums = $.fn.jquery.split('.');
|
1989
|
+
if (parseInt(vernums[0]) <= 1 && parseInt(vernums[1]) < 8) {
|
1990
|
+
throw "The loaded version of jQuery is too old. Please upgrade to 1.8.x or better.";
|
1991
|
+
}
|
1992
|
+
if (!vernums.forEach) {
|
1993
|
+
ParsleyUtils__default.warn('Parsley requires ES5 to run properly. Please include https://github.com/es-shims/es5-shim');
|
1994
|
+
}
|
1995
|
+
// Inherit `on`, `off` & `trigger` to Parsley:
|
1996
|
+
var Parsley = $.extend(new ParsleyAbstract(), {
|
1997
|
+
$element: $(document),
|
1998
|
+
actualizeOptions: null,
|
1999
|
+
_resetOptions: null,
|
2000
|
+
Factory: ParsleyFactory,
|
2001
|
+
version: '2.4.4'
|
2002
|
+
});
|
2003
|
+
|
2004
|
+
// Supplement ParsleyField and Form with ParsleyAbstract
|
2005
|
+
// This way, the constructors will have access to those methods
|
2006
|
+
$.extend(parsley_field.prototype, ParsleyUI.Field, ParsleyAbstract.prototype);
|
2007
|
+
$.extend(ParsleyForm.prototype, ParsleyUI.Form, ParsleyAbstract.prototype);
|
2008
|
+
// Inherit actualizeOptions and _resetOptions:
|
2009
|
+
$.extend(ParsleyFactory.prototype, ParsleyAbstract.prototype);
|
2010
|
+
|
2040
2011
|
// ### jQuery API
|
2041
2012
|
// `$('.elem').parsley(options)` or `$('.elem').psly(options)`
|
2042
2013
|
$.fn.parsley = $.fn.psly = function (options) {
|
2043
2014
|
if (this.length > 1) {
|
2044
2015
|
var instances = [];
|
2016
|
+
|
2045
2017
|
this.each(function () {
|
2046
2018
|
instances.push($(this).parsley(options));
|
2047
2019
|
});
|
2020
|
+
|
2048
2021
|
return instances;
|
2049
2022
|
}
|
2023
|
+
|
2050
2024
|
// Return undefined if applied to non existing DOM element
|
2051
2025
|
if (!$(this).length) {
|
2052
|
-
|
2053
|
-
|
2026
|
+
ParsleyUtils__default.warn('You must bind Parsley on an existing element.');
|
2027
|
+
|
2054
2028
|
return;
|
2055
2029
|
}
|
2056
|
-
|
2030
|
+
|
2031
|
+
return new ParsleyFactory(this, options);
|
2057
2032
|
};
|
2058
|
-
|
2059
|
-
// UI is a class apart that only listen to some events and them modify DOM accordingly
|
2060
|
-
// Could be overriden by defining a `window.ParsleyConfig.ParsleyUI` appropriate class (with `listen()` method basically)
|
2061
|
-
window.ParsleyUI = 'function' === typeof ParsleyUtils.get(window, 'ParsleyConfig.ParsleyUI') ?
|
2062
|
-
new window.ParsleyConfig.ParsleyUI().listen() : new ParsleyUI().listen();
|
2033
|
+
|
2063
2034
|
// ### ParsleyField and ParsleyForm extension
|
2064
|
-
// Ensure
|
2065
|
-
if ('undefined' === typeof window.ParsleyExtend)
|
2066
|
-
|
2067
|
-
// ###
|
2068
|
-
//
|
2069
|
-
|
2070
|
-
|
2035
|
+
// Ensure the extension is now defined if it wasn't previously
|
2036
|
+
if ('undefined' === typeof window.ParsleyExtend) window.ParsleyExtend = {};
|
2037
|
+
|
2038
|
+
// ### Parsley config
|
2039
|
+
// Inherit from ParsleyDefault, and copy over any existing values
|
2040
|
+
Parsley.options = $.extend(ParsleyUtils__default.objectCreate(ParsleyDefaults), window.ParsleyConfig);
|
2041
|
+
window.ParsleyConfig = Parsley.options; // Old way of accessing global options
|
2042
|
+
|
2071
2043
|
// ### Globals
|
2072
2044
|
window.Parsley = window.psly = Parsley;
|
2073
|
-
window.ParsleyUtils =
|
2074
|
-
|
2045
|
+
window.ParsleyUtils = ParsleyUtils__default;
|
2046
|
+
|
2047
|
+
// ### Define methods that forward to the registry, and deprecate all access except through window.Parsley
|
2048
|
+
var registry = window.Parsley._validatorRegistry = new ParsleyValidatorRegistry(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);
|
2049
|
+
window.ParsleyValidator = {};
|
2050
|
+
$.each('setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator'.split(' '), function (i, method) {
|
2051
|
+
window.Parsley[method] = $.proxy(registry, method);
|
2052
|
+
window.ParsleyValidator[method] = function () {
|
2053
|
+
var _window$Parsley;
|
2054
|
+
|
2055
|
+
ParsleyUtils__default.warnOnce('Accessing the method \'' + method + '\' through ParsleyValidator is deprecated. Simply call \'window.Parsley.' + method + '(...)\'');
|
2056
|
+
return (_window$Parsley = window.Parsley)[method].apply(_window$Parsley, arguments);
|
2057
|
+
};
|
2058
|
+
});
|
2059
|
+
|
2060
|
+
// ### ParsleyUI
|
2061
|
+
// Deprecated global object
|
2062
|
+
window.Parsley.UI = ParsleyUI;
|
2063
|
+
window.ParsleyUI = {
|
2064
|
+
removeError: function removeError(instance, name, doNotUpdateClass) {
|
2065
|
+
var updateClass = true !== doNotUpdateClass;
|
2066
|
+
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.');
|
2067
|
+
return instance.removeError(name, { updateClass: updateClass });
|
2068
|
+
},
|
2069
|
+
getErrorsMessages: function getErrorsMessages(instance) {
|
2070
|
+
ParsleyUtils__default.warnOnce('Accessing ParsleyUI is deprecated. Call \'getErrorsMessages\' on the instance directly.');
|
2071
|
+
return instance.getErrorsMessages();
|
2072
|
+
}
|
2073
|
+
};
|
2074
|
+
$.each('addError updateError'.split(' '), function (i, method) {
|
2075
|
+
window.ParsleyUI[method] = function (instance, name, message, assert, doNotUpdateClass) {
|
2076
|
+
var updateClass = true !== doNotUpdateClass;
|
2077
|
+
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.');
|
2078
|
+
return instance[method](name, { message: message, assert: assert, updateClass: updateClass });
|
2079
|
+
};
|
2080
|
+
});
|
2081
|
+
|
2075
2082
|
// ### PARSLEY auto-binding
|
2076
2083
|
// Prevent it by setting `ParsleyConfig.autoBind` to `false`
|
2077
|
-
if (false !==
|
2084
|
+
if (false !== window.ParsleyConfig.autoBind) {
|
2078
2085
|
$(function () {
|
2079
2086
|
// Works only on `data-parsley-validate`.
|
2080
|
-
if ($('[data-parsley-validate]').length)
|
2081
|
-
|
2087
|
+
if ($('[data-parsley-validate]').length) $('[data-parsley-validate]').parsley();
|
2088
|
+
});
|
2089
|
+
}
|
2090
|
+
|
2091
|
+
var o = $({});
|
2092
|
+
var deprecated = function deprecated() {
|
2093
|
+
ParsleyUtils__default.warnOnce("Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley");
|
2094
|
+
};
|
2095
|
+
|
2096
|
+
// Returns an event handler that calls `fn` with the arguments it expects
|
2097
|
+
function adapt(fn, context) {
|
2098
|
+
// Store to allow unbinding
|
2099
|
+
if (!fn.parsleyAdaptedCallback) {
|
2100
|
+
fn.parsleyAdaptedCallback = function () {
|
2101
|
+
var args = Array.prototype.slice.call(arguments, 0);
|
2102
|
+
args.unshift(this);
|
2103
|
+
fn.apply(context || o, args);
|
2104
|
+
};
|
2105
|
+
}
|
2106
|
+
return fn.parsleyAdaptedCallback;
|
2107
|
+
}
|
2108
|
+
|
2109
|
+
var eventPrefix = 'parsley:';
|
2110
|
+
// Converts 'parsley:form:validate' into 'form:validate'
|
2111
|
+
function eventName(name) {
|
2112
|
+
if (name.lastIndexOf(eventPrefix, 0) === 0) return name.substr(eventPrefix.length);
|
2113
|
+
return name;
|
2114
|
+
}
|
2115
|
+
|
2116
|
+
// $.listen is deprecated. Use Parsley.on instead.
|
2117
|
+
$.listen = function (name, callback) {
|
2118
|
+
var context;
|
2119
|
+
deprecated();
|
2120
|
+
if ('object' === typeof arguments[1] && 'function' === typeof arguments[2]) {
|
2121
|
+
context = arguments[1];
|
2122
|
+
callback = arguments[2];
|
2123
|
+
}
|
2124
|
+
|
2125
|
+
if ('function' !== typeof callback) throw new Error('Wrong parameters');
|
2126
|
+
|
2127
|
+
window.Parsley.on(eventName(name), adapt(callback, context));
|
2128
|
+
};
|
2129
|
+
|
2130
|
+
$.listenTo = function (instance, name, fn) {
|
2131
|
+
deprecated();
|
2132
|
+
if (!(instance instanceof parsley_field) && !(instance instanceof ParsleyForm)) throw new Error('Must give Parsley instance');
|
2133
|
+
|
2134
|
+
if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong parameters');
|
2135
|
+
|
2136
|
+
instance.on(eventName(name), adapt(fn));
|
2137
|
+
};
|
2138
|
+
|
2139
|
+
$.unsubscribe = function (name, fn) {
|
2140
|
+
deprecated();
|
2141
|
+
if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong arguments');
|
2142
|
+
window.Parsley.off(eventName(name), fn.parsleyAdaptedCallback);
|
2143
|
+
};
|
2144
|
+
|
2145
|
+
$.unsubscribeTo = function (instance, name) {
|
2146
|
+
deprecated();
|
2147
|
+
if (!(instance instanceof parsley_field) && !(instance instanceof ParsleyForm)) throw new Error('Must give Parsley instance');
|
2148
|
+
instance.off(eventName(name));
|
2149
|
+
};
|
2150
|
+
|
2151
|
+
$.unsubscribeAll = function (name) {
|
2152
|
+
deprecated();
|
2153
|
+
window.Parsley.off(eventName(name));
|
2154
|
+
$('form,input,textarea,select').each(function () {
|
2155
|
+
var instance = $(this).data('Parsley');
|
2156
|
+
if (instance) {
|
2157
|
+
instance.off(eventName(name));
|
2158
|
+
}
|
2159
|
+
});
|
2160
|
+
};
|
2161
|
+
|
2162
|
+
// $.emit is deprecated. Use jQuery events instead.
|
2163
|
+
$.emit = function (name, instance) {
|
2164
|
+
var _instance;
|
2165
|
+
|
2166
|
+
deprecated();
|
2167
|
+
var instanceGiven = instance instanceof parsley_field || instance instanceof ParsleyForm;
|
2168
|
+
var args = Array.prototype.slice.call(arguments, instanceGiven ? 2 : 1);
|
2169
|
+
args.unshift(eventName(name));
|
2170
|
+
if (!instanceGiven) {
|
2171
|
+
instance = window.Parsley;
|
2172
|
+
}
|
2173
|
+
(_instance = instance).trigger.apply(_instance, _toConsumableArray(args));
|
2174
|
+
};
|
2175
|
+
|
2176
|
+
var pubsub = {};
|
2177
|
+
|
2178
|
+
$.extend(true, Parsley, {
|
2179
|
+
asyncValidators: {
|
2180
|
+
'default': {
|
2181
|
+
fn: function fn(xhr) {
|
2182
|
+
// By default, only status 2xx are deemed successful.
|
2183
|
+
// Note: we use status instead of state() because responses with status 200
|
2184
|
+
// but invalid messages (e.g. an empty body for content type set to JSON) will
|
2185
|
+
// result in state() === 'rejected'.
|
2186
|
+
return xhr.status >= 200 && xhr.status < 300;
|
2187
|
+
},
|
2188
|
+
url: false
|
2189
|
+
},
|
2190
|
+
reverse: {
|
2191
|
+
fn: function fn(xhr) {
|
2192
|
+
// If reverse option is set, a failing ajax request is considered successful
|
2193
|
+
return xhr.status < 200 || xhr.status >= 300;
|
2194
|
+
},
|
2195
|
+
url: false
|
2196
|
+
}
|
2197
|
+
},
|
2198
|
+
|
2199
|
+
addAsyncValidator: function addAsyncValidator(name, fn, url, options) {
|
2200
|
+
Parsley.asyncValidators[name] = {
|
2201
|
+
fn: fn,
|
2202
|
+
url: url || false,
|
2203
|
+
options: options || {}
|
2204
|
+
};
|
2205
|
+
|
2206
|
+
return this;
|
2207
|
+
}
|
2208
|
+
|
2209
|
+
});
|
2210
|
+
|
2211
|
+
Parsley.addValidator('remote', {
|
2212
|
+
requirementType: {
|
2213
|
+
'': 'string',
|
2214
|
+
'validator': 'string',
|
2215
|
+
'reverse': 'boolean',
|
2216
|
+
'options': 'object'
|
2217
|
+
},
|
2218
|
+
|
2219
|
+
validateString: function validateString(value, url, options, instance) {
|
2220
|
+
var data = {};
|
2221
|
+
var ajaxOptions;
|
2222
|
+
var csr;
|
2223
|
+
var validator = options.validator || (true === options.reverse ? 'reverse' : 'default');
|
2224
|
+
|
2225
|
+
if ('undefined' === typeof Parsley.asyncValidators[validator]) throw new Error('Calling an undefined async validator: `' + validator + '`');
|
2226
|
+
|
2227
|
+
url = Parsley.asyncValidators[validator].url || url;
|
2228
|
+
|
2229
|
+
// Fill current value
|
2230
|
+
if (url.indexOf('{value}') > -1) {
|
2231
|
+
url = url.replace('{value}', encodeURIComponent(value));
|
2232
|
+
} else {
|
2233
|
+
data[instance.$element.attr('name') || instance.$element.attr('id')] = value;
|
2234
|
+
}
|
2235
|
+
|
2236
|
+
// Merge options passed in from the function with the ones in the attribute
|
2237
|
+
var remoteOptions = $.extend(true, options.options || {}, Parsley.asyncValidators[validator].options);
|
2238
|
+
|
2239
|
+
// All `$.ajax(options)` could be overridden or extended directly from DOM in `data-parsley-remote-options`
|
2240
|
+
ajaxOptions = $.extend(true, {}, {
|
2241
|
+
url: url,
|
2242
|
+
data: data,
|
2243
|
+
type: 'GET'
|
2244
|
+
}, remoteOptions);
|
2245
|
+
|
2246
|
+
// Generate store key based on ajax options
|
2247
|
+
instance.trigger('field:ajaxoptions', instance, ajaxOptions);
|
2248
|
+
|
2249
|
+
csr = $.param(ajaxOptions);
|
2250
|
+
|
2251
|
+
// Initialise querry cache
|
2252
|
+
if ('undefined' === typeof Parsley._remoteCache) Parsley._remoteCache = {};
|
2253
|
+
|
2254
|
+
// Try to retrieve stored xhr
|
2255
|
+
var xhr = Parsley._remoteCache[csr] = Parsley._remoteCache[csr] || $.ajax(ajaxOptions);
|
2256
|
+
|
2257
|
+
var handleXhr = function handleXhr() {
|
2258
|
+
var result = Parsley.asyncValidators[validator].fn.call(instance, xhr, url, options);
|
2259
|
+
if (!result) // Map falsy results to rejected promise
|
2260
|
+
result = $.Deferred().reject();
|
2261
|
+
return $.when(result);
|
2262
|
+
};
|
2263
|
+
|
2264
|
+
return xhr.then(handleXhr, handleXhr);
|
2265
|
+
},
|
2266
|
+
|
2267
|
+
priority: -1
|
2268
|
+
});
|
2269
|
+
|
2270
|
+
Parsley.on('form:submit', function () {
|
2271
|
+
Parsley._remoteCache = {};
|
2272
|
+
});
|
2273
|
+
|
2274
|
+
window.ParsleyExtend.addAsyncValidator = function () {
|
2275
|
+
ParsleyUtils.warnOnce('Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`');
|
2276
|
+
return Parsley.addAsyncValidator.apply(Parsley, arguments);
|
2277
|
+
};
|
2278
|
+
|
2279
|
+
// This is included with the Parsley library itself,
|
2280
|
+
// thus there is no use in adding it to your project.
|
2281
|
+
Parsley.addMessages('en', {
|
2282
|
+
defaultMessage: "This value seems to be invalid.",
|
2283
|
+
type: {
|
2284
|
+
email: "This value should be a valid email.",
|
2285
|
+
url: "This value should be a valid url.",
|
2286
|
+
number: "This value should be a valid number.",
|
2287
|
+
integer: "This value should be a valid integer.",
|
2288
|
+
digits: "This value should be digits.",
|
2289
|
+
alphanum: "This value should be alphanumeric."
|
2290
|
+
},
|
2291
|
+
notblank: "This value should not be blank.",
|
2292
|
+
required: "This value is required.",
|
2293
|
+
pattern: "This value seems to be invalid.",
|
2294
|
+
min: "This value should be greater than or equal to %s.",
|
2295
|
+
max: "This value should be lower than or equal to %s.",
|
2296
|
+
range: "This value should be between %s and %s.",
|
2297
|
+
minlength: "This value is too short. It should have %s characters or more.",
|
2298
|
+
maxlength: "This value is too long. It should have %s characters or fewer.",
|
2299
|
+
length: "This value length is invalid. It should be between %s and %s characters long.",
|
2300
|
+
mincheck: "You must select at least %s choices.",
|
2301
|
+
maxcheck: "You must select %s choices or fewer.",
|
2302
|
+
check: "You must select between %s and %s choices.",
|
2303
|
+
equalto: "This value should be the same."
|
2304
|
+
});
|
2305
|
+
|
2306
|
+
Parsley.setLocale('en');
|
2307
|
+
|
2308
|
+
/**
|
2309
|
+
* inputevent - Alleviate browser bugs for input events
|
2310
|
+
* https://github.com/marcandre/inputevent
|
2311
|
+
* @version v0.0.3 - (built Thu, Apr 14th 2016, 5:58 pm)
|
2312
|
+
* @author Marc-Andre Lafortune <github@marc-andre.ca>
|
2313
|
+
* @license MIT
|
2314
|
+
*/
|
2315
|
+
|
2316
|
+
function InputEvent() {
|
2317
|
+
var _this13 = this;
|
2318
|
+
|
2319
|
+
var globals = window || global;
|
2320
|
+
|
2321
|
+
// Slightly odd way construct our object. This way methods are force bound.
|
2322
|
+
// Used to test for duplicate library.
|
2323
|
+
$.extend(this, {
|
2324
|
+
|
2325
|
+
// For browsers that do not support isTrusted, assumes event is native.
|
2326
|
+
isNativeEvent: function isNativeEvent(evt) {
|
2327
|
+
return evt.originalEvent && evt.originalEvent.isTrusted !== false;
|
2328
|
+
},
|
2329
|
+
|
2330
|
+
fakeInputEvent: function fakeInputEvent(evt) {
|
2331
|
+
if (_this13.isNativeEvent(evt)) {
|
2332
|
+
$(evt.target).trigger('input');
|
2333
|
+
}
|
2334
|
+
},
|
2335
|
+
|
2336
|
+
misbehaves: function misbehaves(evt) {
|
2337
|
+
if (_this13.isNativeEvent(evt)) {
|
2338
|
+
_this13.behavesOk(evt);
|
2339
|
+
$(document).on('change.inputevent', evt.data.selector, _this13.fakeInputEvent);
|
2340
|
+
_this13.fakeInputEvent(evt);
|
2341
|
+
}
|
2342
|
+
},
|
2343
|
+
|
2344
|
+
behavesOk: function behavesOk(evt) {
|
2345
|
+
if (_this13.isNativeEvent(evt)) {
|
2346
|
+
$(document) // Simply unbinds the testing handler
|
2347
|
+
.off('input.inputevent', evt.data.selector, _this13.behavesOk).off('change.inputevent', evt.data.selector, _this13.misbehaves);
|
2348
|
+
}
|
2349
|
+
},
|
2350
|
+
|
2351
|
+
// Bind the testing handlers
|
2352
|
+
install: function install() {
|
2353
|
+
if (globals.inputEventPatched) {
|
2354
|
+
return;
|
2355
|
+
}
|
2356
|
+
globals.inputEventPatched = '0.0.3';
|
2357
|
+
var _arr = ['select', 'input[type="checkbox"]', 'input[type="radio"]', 'input[type="file"]'];
|
2358
|
+
for (var _i = 0; _i < _arr.length; _i++) {
|
2359
|
+
var selector = _arr[_i];
|
2360
|
+
$(document).on('input.inputevent', selector, { selector: selector }, _this13.behavesOk).on('change.inputevent', selector, { selector: selector }, _this13.misbehaves);
|
2361
|
+
}
|
2362
|
+
},
|
2363
|
+
|
2364
|
+
uninstall: function uninstall() {
|
2365
|
+
delete globals.inputEventPatched;
|
2366
|
+
$(document).off('.inputevent');
|
2367
|
+
}
|
2368
|
+
|
2082
2369
|
});
|
2083
|
-
}
|
2370
|
+
};
|
2371
|
+
|
2372
|
+
var inputevent = new InputEvent();
|
2373
|
+
|
2374
|
+
inputevent.install();
|
2375
|
+
|
2376
|
+
var parsley = Parsley;
|
2377
|
+
|
2378
|
+
return parsley;
|
2379
|
+
});
|
2380
|
+
//# sourceMappingURL=parsley.js.map
|