jquery-form-validator-rails 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/README.md +30 -2
- data/app/assets/javascripts/date.dev.js +81 -0
- data/app/assets/javascripts/file.dev.js +195 -0
- data/app/assets/javascripts/file.js +1 -1
- data/app/assets/javascripts/form-test.html +422 -0
- data/app/assets/javascripts/html5.dev.js +144 -0
- data/app/assets/javascripts/html5.js +1 -1
- data/app/assets/javascripts/jquery.form-validator.js +229 -251
- data/app/assets/javascripts/jquery.form-validator.min.js +10 -0
- data/app/assets/javascripts/location.dev.js +78 -0
- data/app/assets/javascripts/qunit.html +635 -0
- data/app/assets/javascripts/security.dev.js +51 -24
- data/app/assets/javascripts/security.js +1 -1
- data/app/assets/javascripts/sweden.dev.js +1 -1
- data/app/assets/javascripts/uk.dev.js +1 -1
- data/lib/jquery/form/validator/rails/version.rb +1 -1
- metadata +21 -14
@@ -0,0 +1,144 @@
|
|
1
|
+
/**
|
2
|
+
* jQuery Form Validator Module: html5
|
3
|
+
* ------------------------------------------
|
4
|
+
* Created by Victor Jonsson <http://www.victorjonsson.se>
|
5
|
+
*
|
6
|
+
* The following module will make this jQuery plugin serve as a
|
7
|
+
* html5 fallback. It makes older browsers support the following
|
8
|
+
* - validation when type="email"
|
9
|
+
* - validation when type="url"
|
10
|
+
* - validation when type="time"
|
11
|
+
* - validation when type="date"
|
12
|
+
* - validation when type="number" and max="" min=""
|
13
|
+
* - validation when pattern="REGEXP"
|
14
|
+
* - validation when using maxlength
|
15
|
+
* - Using datalist element for creating suggestions
|
16
|
+
* - placeholders
|
17
|
+
*
|
18
|
+
* @website http://formvalidator.net/
|
19
|
+
* @license Dual licensed under the MIT or GPL Version 2 licenses
|
20
|
+
* @version 2.2.beta.50
|
21
|
+
*/
|
22
|
+
(function($, window) {
|
23
|
+
|
24
|
+
"use strict";
|
25
|
+
|
26
|
+
var SUPPORTS_PLACEHOLDER = 'placeholder' in document.createElement('INPUT'),
|
27
|
+
SUPPORTS_DATALIST = 'options' in document.createElement('DATALIST');
|
28
|
+
|
29
|
+
$(window).bind('validatorsLoaded formValidationSetup', function(evt, $form) {
|
30
|
+
|
31
|
+
if( !$form ) {
|
32
|
+
$form = $('form');
|
33
|
+
}
|
34
|
+
|
35
|
+
var hasLoadedDateModule = false;
|
36
|
+
|
37
|
+
$form.each(function() {
|
38
|
+
var $f = $(this),
|
39
|
+
$formInputs = $f.find('input,textarea,select'),
|
40
|
+
foundHtml5Rule = false;
|
41
|
+
|
42
|
+
$formInputs.each(function() {
|
43
|
+
var validation = [],
|
44
|
+
$input = $(this),
|
45
|
+
isRequired = $input.attr('required'),
|
46
|
+
attrs = {};
|
47
|
+
|
48
|
+
switch ( ($input.attr('type') || '').toLowerCase() ) {
|
49
|
+
case 'time':
|
50
|
+
validation.push('time');
|
51
|
+
if( !$.formUtils.validators.validate_date && !hasLoadedDateModule ) {
|
52
|
+
hasLoadedDateModule = true;
|
53
|
+
$.formUtils.loadModules('date');
|
54
|
+
}
|
55
|
+
break;
|
56
|
+
case 'url':
|
57
|
+
validation.push('url');
|
58
|
+
break;
|
59
|
+
case 'email':
|
60
|
+
validation.push('email');
|
61
|
+
break;
|
62
|
+
case 'date':
|
63
|
+
validation.push('date');
|
64
|
+
break;
|
65
|
+
case 'number':
|
66
|
+
validation.push('number');
|
67
|
+
var max = $input.attr('max'),
|
68
|
+
min = $input.attr('min');
|
69
|
+
if( min || max ) {
|
70
|
+
if( !min )
|
71
|
+
min = 0;
|
72
|
+
if( !max )
|
73
|
+
max = 9007199254740992; // js max int
|
74
|
+
|
75
|
+
attrs['data-validation-allowing'] = 'range['+min+';'+max+']';
|
76
|
+
if( min.indexOf('-') === 0 || max.indexOf('-') === 0 ) {
|
77
|
+
attrs['data-validation-allowing'] += ',negative';
|
78
|
+
}
|
79
|
+
if( min.indexOf('.') > -1 || max.indexOf('.') > -1 ) {
|
80
|
+
attrs['data-validation-allowing'] += ',float';
|
81
|
+
}
|
82
|
+
}
|
83
|
+
break;
|
84
|
+
}
|
85
|
+
|
86
|
+
if( $input.attr('pattern') ) {
|
87
|
+
validation.push('custom');
|
88
|
+
attrs['data-validation-regexp'] = $input.attr('pattern');
|
89
|
+
}
|
90
|
+
if( $input.attr('maxlength') ) {
|
91
|
+
validation.push('length');
|
92
|
+
attrs['data-validation-length'] = 'max'+$input.attr('maxlength');
|
93
|
+
}
|
94
|
+
|
95
|
+
if( !SUPPORTS_DATALIST && $input.attr('list') ) {
|
96
|
+
var suggestions = [];
|
97
|
+
$('#'+$input.attr('list')+' option').each(function() {
|
98
|
+
var $opt = $(this);
|
99
|
+
suggestions.push($opt.attr('value') || $opt.text());
|
100
|
+
});
|
101
|
+
$.formUtils.suggest( $input, suggestions );
|
102
|
+
}
|
103
|
+
|
104
|
+
if( validation.length ) {
|
105
|
+
if( !isRequired ) {
|
106
|
+
attrs['data-validation-optional'] = 'true';
|
107
|
+
}
|
108
|
+
|
109
|
+
foundHtml5Rule = true;
|
110
|
+
$input.attr('data-validation', validation.join(' '));
|
111
|
+
|
112
|
+
$.each(attrs, function(attrName, attrVal) {
|
113
|
+
$input.attr(attrName, attrVal);
|
114
|
+
});
|
115
|
+
}
|
116
|
+
});
|
117
|
+
|
118
|
+
if( foundHtml5Rule ) {
|
119
|
+
$f.trigger('html5ValidationAttrsFound');
|
120
|
+
}
|
121
|
+
|
122
|
+
if( !SUPPORTS_PLACEHOLDER ) {
|
123
|
+
$formInputs.filter('input[placeholder]').each(function() {
|
124
|
+
this.defaultValue = this.getAttribute('placeholder');
|
125
|
+
$(this)
|
126
|
+
.bind('focus', function() {
|
127
|
+
if(this.value == this.defaultValue) {
|
128
|
+
this.value = '';
|
129
|
+
$(this).removeClass('showing-placeholder');
|
130
|
+
}
|
131
|
+
})
|
132
|
+
.bind('blur', function() {
|
133
|
+
if($.trim(this.value) == '') {
|
134
|
+
this.value = this.defaultValue;
|
135
|
+
$(this).addClass('showing-placeholder');
|
136
|
+
}
|
137
|
+
});
|
138
|
+
});
|
139
|
+
}
|
140
|
+
|
141
|
+
});
|
142
|
+
});
|
143
|
+
|
144
|
+
})(jQuery, window);
|
@@ -1 +1 @@
|
|
1
|
-
(function($,window){"use strict";var SUPPORTS_PLACEHOLDER="placeholder"in document.createElement("INPUT"),SUPPORTS_DATALIST="options"in document.createElement("DATALIST");$(window).bind("validatorsLoaded formValidationSetup",function(evt,$form){if(!$form){$form=$("form")}var hasLoadedDateModule=false;$form.each(function(){var $f=$(this),$formInputs=$f.find("input,textarea,select"),foundHtml5Rule=false;$formInputs.each(function(){var validation=[],$input=$(this),isRequired=$input.attr("required"),attrs={};switch(($input.attr("type")||"").toLowerCase()){case"time":validation.push("time");if(!$.formUtils.validators.validate_date&&!hasLoadedDateModule){hasLoadedDateModule=true;$.formUtils.loadModules("date")}break;case"url":validation.push("url");break;case"email":validation.push("email");break;case"date":validation.push("date");break;case"number":validation.push("number");var max=$input.attr("max"),min=$input.attr("min");if(min||max){if(!min)min=0;if(!max)max=9007199254740992;attrs["data-validation-allowing"]="range["+min+";"+max+"]";if(min.indexOf("-")===0||max.indexOf("-")===0){attrs["data-validation-allowing"]+=",negative"}if(min.indexOf(".")>-1||max.indexOf(".")>-1){attrs["data-validation-allowing"]+=",float"}}break}if($input.attr("pattern")){validation.push("custom");attrs["data-validation-regexp"]=$input.attr("pattern")}if($input.attr("maxlength")){validation.push("length");attrs["data-validation-length"]="max"+$input.attr("maxlength")}
|
1
|
+
(function($,window){"use strict";var SUPPORTS_PLACEHOLDER="placeholder"in document.createElement("INPUT"),SUPPORTS_DATALIST="options"in document.createElement("DATALIST");$(window).bind("validatorsLoaded formValidationSetup",function(evt,$form){if(!$form){$form=$("form")}var hasLoadedDateModule=false;$form.each(function(){var $f=$(this),$formInputs=$f.find("input,textarea,select"),foundHtml5Rule=false;$formInputs.each(function(){var validation=[],$input=$(this),isRequired=$input.attr("required"),attrs={};switch(($input.attr("type")||"").toLowerCase()){case"time":validation.push("time");if(!$.formUtils.validators.validate_date&&!hasLoadedDateModule){hasLoadedDateModule=true;$.formUtils.loadModules("date")}break;case"url":validation.push("url");break;case"email":validation.push("email");break;case"date":validation.push("date");break;case"number":validation.push("number");var max=$input.attr("max"),min=$input.attr("min");if(min||max){if(!min)min=0;if(!max)max=9007199254740992;attrs["data-validation-allowing"]="range["+min+";"+max+"]";if(min.indexOf("-")===0||max.indexOf("-")===0){attrs["data-validation-allowing"]+=",negative"}if(min.indexOf(".")>-1||max.indexOf(".")>-1){attrs["data-validation-allowing"]+=",float"}}break}if($input.attr("pattern")){validation.push("custom");attrs["data-validation-regexp"]=$input.attr("pattern")}if($input.attr("maxlength")){validation.push("length");attrs["data-validation-length"]="max"+$input.attr("maxlength")}if(!SUPPORTS_DATALIST&&$input.attr("list")){var suggestions=[];$("#"+$input.attr("list")+" option").each(function(){var $opt=$(this);suggestions.push($opt.attr("value")||$opt.text())});$.formUtils.suggest($input,suggestions)}if(validation.length){if(!isRequired){attrs["data-validation-optional"]="true"}foundHtml5Rule=true;$input.attr("data-validation",validation.join(" "));$.each(attrs,function(attrName,attrVal){$input.attr(attrName,attrVal)})}});if(foundHtml5Rule){$f.trigger("html5ValidationAttrsFound")}if(!SUPPORTS_PLACEHOLDER){$formInputs.filter("input[placeholder]").each(function(){this.defaultValue=this.getAttribute("placeholder");$(this).bind("focus",function(){if(this.value==this.defaultValue){this.value="";$(this).removeClass("showing-placeholder")}}).bind("blur",function(){if($.trim(this.value)==""){this.value=this.defaultValue;$(this).addClass("showing-placeholder")}})})}})})})(jQuery,window);
|
@@ -5,7 +5,7 @@
|
|
5
5
|
*
|
6
6
|
* @website http://formvalidator.net/
|
7
7
|
* @license Dual licensed under the MIT or GPL Version 2 licenses
|
8
|
-
* @version 2.
|
8
|
+
* @version 2.2.beta.50
|
9
9
|
*/
|
10
10
|
(function($) {
|
11
11
|
|
@@ -15,10 +15,15 @@
|
|
15
15
|
_applyErrorStyle = function($elem, conf) {
|
16
16
|
$elem
|
17
17
|
.addClass(conf.errorElementClass)
|
18
|
-
.removeClass('valid')
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
.removeClass('valid');
|
19
|
+
|
20
|
+
var $parent = $elem.parent();
|
21
|
+
if($parent.hasClass("input-group"))
|
22
|
+
$parent = $parent.parent();
|
23
|
+
|
24
|
+
$parent
|
25
|
+
.addClass(conf.inputParentClassOnError)
|
26
|
+
.removeClass(conf.inputParentClassOnSuccess);
|
22
27
|
|
23
28
|
if(conf.borderColorOnError !== '') {
|
24
29
|
$elem.css('border-color', conf.borderColorOnError);
|
@@ -26,20 +31,29 @@
|
|
26
31
|
},
|
27
32
|
_removeErrorStyle = function($elem, conf) {
|
28
33
|
$elem.each(function() {
|
29
|
-
|
30
|
-
|
34
|
+
var $this = $(this),
|
35
|
+
$parent = $this.parent();
|
36
|
+
|
37
|
+
if($parent.hasClass("input-group"))
|
38
|
+
$parent = $parent.parent();
|
39
|
+
|
40
|
+
_setInlineErrorMessage($this, '', conf, conf.errorMessagePosition);
|
41
|
+
|
42
|
+
$this
|
31
43
|
.removeClass('valid')
|
32
44
|
.removeClass(conf.errorElementClass)
|
33
|
-
.css('border-color', '')
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
45
|
+
.css('border-color', '');
|
46
|
+
|
47
|
+
$parent
|
48
|
+
.removeClass(conf.inputParentClassOnError)
|
49
|
+
.removeClass(conf.inputParentClassOnSuccess)
|
50
|
+
.find('.'+conf.errorMessageClass) // remove inline span holding error message
|
51
|
+
.remove();
|
39
52
|
});
|
40
53
|
},
|
41
54
|
_setInlineErrorMessage = function($input, mess, conf, $messageContainer) {
|
42
55
|
var custom = _getInlineErrorElement($input);
|
56
|
+
|
43
57
|
if( custom ) {
|
44
58
|
custom.innerHTML = mess;
|
45
59
|
}
|
@@ -64,10 +78,12 @@
|
|
64
78
|
}
|
65
79
|
}
|
66
80
|
else {
|
67
|
-
|
81
|
+
var $parent = $input.parent();
|
82
|
+
if($parent.hasClass("input-group")) $parent = $parent.parent();
|
83
|
+
var $mess = $parent.find('.'+conf.errorMessageClass+'.help-block');
|
68
84
|
if( $mess.length == 0 ) {
|
69
85
|
$mess = $('<span></span>').addClass('help-block').addClass(conf.errorMessageClass);
|
70
|
-
$mess.appendTo($
|
86
|
+
$mess.appendTo($parent);
|
71
87
|
}
|
72
88
|
$mess.html(mess);
|
73
89
|
}
|
@@ -97,8 +113,15 @@
|
|
97
113
|
$.fn.validateOnBlur = function(language, settings) {
|
98
114
|
this.find('input[data-validation],textarea[data-validation],select[data-validation]')
|
99
115
|
.bind('blur.validation', function() {
|
100
|
-
$(this).validateInputOnBlur(language, settings);
|
116
|
+
$(this).validateInputOnBlur(language, settings, true, 'blur');
|
117
|
+
});
|
118
|
+
if(settings.validateCheckboxRadioOnClick) {
|
119
|
+
// bind click event to validate on click for radio & checkboxes for nice UX
|
120
|
+
this.find('input[type=checkbox][data-validation],input[type=radio][data-validation]')
|
121
|
+
.bind('click.validation', function() {
|
122
|
+
$(this).validateInputOnBlur(language, settings, true, 'click');
|
101
123
|
});
|
124
|
+
}
|
102
125
|
|
103
126
|
return this;
|
104
127
|
};
|
@@ -113,10 +136,10 @@
|
|
113
136
|
this.find('input[data-validation][data-validation-event],textarea[data-validation][data-validation-event],select[data-validation][data-validation-event]')
|
114
137
|
.each(function(){
|
115
138
|
var $el = $(this),
|
116
|
-
etype = $el.
|
139
|
+
etype = $el.valAttr("event");
|
117
140
|
if (etype){
|
118
141
|
$el.bind(etype + ".validation", function(){
|
119
|
-
$(this).validateInputOnBlur(language, settings,
|
142
|
+
$(this).validateInputOnBlur(language, settings, true, etype);
|
120
143
|
});
|
121
144
|
}
|
122
145
|
});
|
@@ -139,8 +162,6 @@
|
|
139
162
|
// Remove previously added event listeners
|
140
163
|
this.find('.has-help-txt')
|
141
164
|
.valAttr('has-keyup-event', false)
|
142
|
-
.valAttr('backend-valid', false)
|
143
|
-
.valAttr('backend-invalid', false)
|
144
165
|
.removeClass('has-help-txt');
|
145
166
|
|
146
167
|
// Add help text listeners
|
@@ -188,23 +209,21 @@
|
|
188
209
|
*
|
189
210
|
* @param {Object} [language] Optional, will override $.formUtils.LANG
|
190
211
|
* @param {Object} [conf] Optional, will override the default settings
|
191
|
-
* @param {Boolean}
|
192
|
-
* @param {String}
|
212
|
+
* @param {Boolean} attachKeyupEvent Optional
|
213
|
+
* @param {String} eventType
|
193
214
|
* @return {jQuery}
|
194
215
|
*/
|
195
|
-
$.fn.validateInputOnBlur = function(language, conf, attachKeyupEvent,
|
196
|
-
|
197
|
-
|
198
|
-
if(!eventContext)
|
199
|
-
eventContext = 'blur';
|
216
|
+
$.fn.validateInputOnBlur = function(language, conf, attachKeyupEvent, eventType) {
|
217
|
+
|
218
|
+
$.formUtils.eventType = eventType;
|
200
219
|
|
201
220
|
if( (this.valAttr('suggestion-nr') || this.valAttr('postpone') || this.hasClass('hasDatepicker')) && !window.postponedValidation ) {
|
202
|
-
// This validation has to be postponed
|
221
|
+
// This validation has to be postponed
|
203
222
|
var _self = this,
|
204
223
|
postponeTime = this.valAttr('postpone') || 200;
|
205
224
|
|
206
225
|
window.postponedValidation = function() {
|
207
|
-
_self.validateInputOnBlur(language, conf, attachKeyupEvent);
|
226
|
+
_self.validateInputOnBlur(language, conf, attachKeyupEvent, eventType);
|
208
227
|
window.postponedValidation = false;
|
209
228
|
};
|
210
229
|
setTimeout(function() {
|
@@ -218,7 +237,6 @@
|
|
218
237
|
|
219
238
|
language = $.extend({}, $.formUtils.LANG, language || {});
|
220
239
|
_removeErrorStyle(this, conf);
|
221
|
-
|
222
240
|
var $elem = this,
|
223
241
|
$form = $elem.closest("form"),
|
224
242
|
validationRule = $elem.attr(conf.validationRuleAttribute),
|
@@ -227,25 +245,26 @@
|
|
227
245
|
language,
|
228
246
|
$.extend({}, conf, {errorMessagePosition:'element'}),
|
229
247
|
$form,
|
230
|
-
|
248
|
+
eventType
|
231
249
|
);
|
232
|
-
|
233
|
-
$elem.trigger('validation', [validation===null ? null : validation===true]);
|
234
|
-
|
250
|
+
|
235
251
|
if(validation === true) {
|
236
252
|
$elem
|
237
253
|
.addClass('valid')
|
238
254
|
.parent()
|
239
|
-
.addClass(
|
255
|
+
.addClass(conf.inputParentClassOnSuccess);
|
256
|
+
|
240
257
|
} else if(validation !== null) {
|
241
258
|
|
242
259
|
_applyErrorStyle($elem, conf);
|
243
260
|
_setInlineErrorMessage($elem, validation, conf, conf.errorMessagePosition);
|
244
261
|
|
245
262
|
if(attachKeyupEvent) {
|
246
|
-
$elem
|
247
|
-
|
248
|
-
|
263
|
+
$elem
|
264
|
+
.unbind('keyup.validation')
|
265
|
+
.bind('keyup.validation', function() {
|
266
|
+
$(this).validateInputOnBlur(language, conf, false, 'keyup');
|
267
|
+
});
|
249
268
|
}
|
250
269
|
}
|
251
270
|
|
@@ -273,7 +292,7 @@
|
|
273
292
|
};
|
274
293
|
|
275
294
|
/**
|
276
|
-
* Function that
|
295
|
+
* Function that validates all inputs in active form
|
277
296
|
*
|
278
297
|
* @param {Object} [language]
|
279
298
|
* @param {Object} [conf]
|
@@ -293,6 +312,14 @@
|
|
293
312
|
language = $.extend({}, $.formUtils.LANG, language || {});
|
294
313
|
displayError = displayError !== false;
|
295
314
|
|
315
|
+
if($.formUtils.errorDisplayPreventedWhenHalted) {
|
316
|
+
// isValid() was called programmatically with argument displayError set
|
317
|
+
// to false when the validation was halted by any of the validators
|
318
|
+
delete $.formUtils.errorDisplayPreventedWhenHalted
|
319
|
+
displayError = false;
|
320
|
+
}
|
321
|
+
|
322
|
+
|
296
323
|
$.formUtils.isValidatingEntireForm = true;
|
297
324
|
$.formUtils.haltValidation = false;
|
298
325
|
|
@@ -303,18 +330,18 @@
|
|
303
330
|
* @para {jQuery} $elem
|
304
331
|
*/
|
305
332
|
var addErrorMessage = function(mess, $elem) {
|
306
|
-
|
307
|
-
|
308
|
-
if ($.inArray(mess, errorMessages) < 0) {
|
309
|
-
errorMessages.push(mess);
|
310
|
-
}
|
311
|
-
errorInputs.push($elem);
|
312
|
-
$elem.attr('current-error', mess);
|
313
|
-
if( displayError )
|
314
|
-
_applyErrorStyle($elem, conf);
|
333
|
+
if ($.inArray(mess, errorMessages) < 0) {
|
334
|
+
errorMessages.push(mess);
|
315
335
|
}
|
336
|
+
errorInputs.push($elem);
|
337
|
+
$elem.attr('current-error', mess);
|
338
|
+
if( displayError )
|
339
|
+
_applyErrorStyle($elem, conf);
|
316
340
|
},
|
317
341
|
|
342
|
+
/** Holds inputs (of type checkox or radio) already validated, to prevent recheck of mulitple checkboxes & radios */
|
343
|
+
checkedInputs = [],
|
344
|
+
|
318
345
|
/** Error messages for this validation */
|
319
346
|
errorMessages = [],
|
320
347
|
|
@@ -346,9 +373,15 @@
|
|
346
373
|
|
347
374
|
// Validate element values
|
348
375
|
$form.find('input,textarea,select').filter(':not([type="submit"],[type="button"])').each(function() {
|
349
|
-
var $elem = $(this)
|
350
|
-
|
351
|
-
|
376
|
+
var $elem = $(this),
|
377
|
+
elementType = $elem.attr('type'),
|
378
|
+
isCheckboxOrRadioBtn = elementType == 'radio' || elementType == 'checkbox',
|
379
|
+
elementName = $elem.attr('name');
|
380
|
+
|
381
|
+
if (!ignoreInput(elementName, elementType) && (!isCheckboxOrRadioBtn || $.inArray(elementName, checkedInputs) < 0) ) {
|
382
|
+
|
383
|
+
if( isCheckboxOrRadioBtn )
|
384
|
+
checkedInputs.push(elementName);
|
352
385
|
|
353
386
|
var validation = $.formUtils.validateInput(
|
354
387
|
$elem,
|
@@ -358,24 +391,18 @@
|
|
358
391
|
'submit'
|
359
392
|
);
|
360
393
|
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
addErrorMessage(validation, $elem);
|
370
|
-
} else {
|
371
|
-
$elem
|
372
|
-
.valAttr('current-error', false)
|
373
|
-
.addClass('valid')
|
374
|
-
.parent()
|
394
|
+
if(validation != null) {
|
395
|
+
if(validation !== true) {
|
396
|
+
addErrorMessage(validation, $elem);
|
397
|
+
} else {
|
398
|
+
$elem
|
399
|
+
.valAttr('current-error', false)
|
400
|
+
.addClass('valid')
|
401
|
+
.parent()
|
375
402
|
.addClass('has-success');
|
403
|
+
}
|
376
404
|
}
|
377
405
|
}
|
378
|
-
|
379
406
|
});
|
380
407
|
|
381
408
|
// Run validation callback
|
@@ -423,6 +450,10 @@
|
|
423
450
|
return false;
|
424
451
|
}
|
425
452
|
|
453
|
+
if( !displayError && $.formUtils.haltValidation ) {
|
454
|
+
$.formUtils.errorDisplayPreventedWhenHalted = true;
|
455
|
+
}
|
456
|
+
|
426
457
|
return !$.formUtils.haltValidation;
|
427
458
|
};
|
428
459
|
|
@@ -469,32 +500,34 @@
|
|
469
500
|
|
470
501
|
/**
|
471
502
|
* A bit smarter split function
|
503
|
+
* delimiter can be space, comma, dash or pipe
|
472
504
|
* @param {String} val
|
473
505
|
* @param {Function|String} [func]
|
474
|
-
* @param {String} [delim]
|
475
506
|
* @returns {Array|void}
|
476
507
|
*/
|
477
|
-
$.split = function(val, func
|
508
|
+
$.split = function(val, func) {
|
478
509
|
if( typeof func != 'function' ) {
|
479
|
-
// return
|
510
|
+
// return array
|
480
511
|
if( !val )
|
481
512
|
return [];
|
482
513
|
var values = [];
|
483
|
-
$.each(val.split(func ? func:
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
514
|
+
$.each(val.split(func ? func: /[,|-\s]\s*/g ),
|
515
|
+
function(i,str) {
|
516
|
+
str = $.trim(str);
|
517
|
+
if( str.length )
|
518
|
+
values.push(str);
|
519
|
+
}
|
520
|
+
);
|
488
521
|
return values;
|
489
522
|
} else if( val ) {
|
490
|
-
//
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
523
|
+
// exec callback func on each
|
524
|
+
$.each(val.split(/[,|-\s]\s*/g),
|
525
|
+
function(i, str) {
|
526
|
+
str = $.trim(str);
|
527
|
+
if( str.length )
|
528
|
+
return func(str, i);
|
529
|
+
}
|
530
|
+
);
|
498
531
|
}
|
499
532
|
};
|
500
533
|
|
@@ -511,6 +544,7 @@
|
|
511
544
|
*/
|
512
545
|
validateOnEvent : true,
|
513
546
|
validateOnBlur : true,
|
547
|
+
validateCheckboxRadioOnClick : true,
|
514
548
|
showHelpOnFocus : true,
|
515
549
|
addSuggestions : true,
|
516
550
|
modules : '',
|
@@ -518,15 +552,15 @@
|
|
518
552
|
language : false,
|
519
553
|
onSuccess : false,
|
520
554
|
onError : false,
|
521
|
-
onElementValidate : false
|
555
|
+
onElementValidate : false,
|
522
556
|
});
|
523
557
|
|
524
558
|
conf = $.extend(defaultConf, conf || {});
|
525
559
|
|
526
560
|
// Add validation to forms
|
527
|
-
|
561
|
+
$(conf.form).each(function(i, form) {
|
528
562
|
|
529
|
-
var $form = $(
|
563
|
+
var $form = $(form);
|
530
564
|
$window.trigger('formValidationSetup', [$form]);
|
531
565
|
|
532
566
|
// Remove all event listeners previously added
|
@@ -544,22 +578,34 @@
|
|
544
578
|
$form.bind('submit.validation', function() {
|
545
579
|
var $form = $(this);
|
546
580
|
|
581
|
+
if( $.formUtils.haltValidation ) {
|
582
|
+
// pressing several times on submit button while validation is halted
|
583
|
+
return false;
|
584
|
+
}
|
585
|
+
|
547
586
|
if($.formUtils.isLoadingModules) {
|
548
587
|
setTimeout(function() {
|
549
588
|
$form.trigger('submit.validation');
|
550
589
|
}, 200);
|
551
590
|
return false;
|
552
591
|
}
|
592
|
+
|
553
593
|
var valid = $form.isValid(conf.language, conf);
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
return false;
|
558
|
-
} else if ( !valid && typeof conf.onError == 'function' ) {
|
559
|
-
conf.onError($form);
|
594
|
+
|
595
|
+
if( $.formUtils.haltValidation ) {
|
596
|
+
// Validation got halted by one of the validators
|
560
597
|
return false;
|
561
598
|
} else {
|
562
|
-
|
599
|
+
if( valid && typeof conf.onSuccess == 'function') {
|
600
|
+
var callbackResponse = conf.onSuccess($form);
|
601
|
+
if( callbackResponse === false )
|
602
|
+
return false;
|
603
|
+
} else if ( !valid && typeof conf.onError == 'function' ) {
|
604
|
+
conf.onError($form);
|
605
|
+
return false;
|
606
|
+
} else {
|
607
|
+
return valid;
|
608
|
+
}
|
563
609
|
}
|
564
610
|
})
|
565
611
|
.bind('reset.validation', function() {
|
@@ -621,7 +667,9 @@
|
|
621
667
|
scrollToTopOnError : true,
|
622
668
|
dateFormat : 'yyyy-mm-dd',
|
623
669
|
addValidClassOnAll : false, // whether or not to apply class="valid" even if the input wasn't validated
|
624
|
-
decimalSeparator : '.'
|
670
|
+
decimalSeparator : '.',
|
671
|
+
inputParentClassOnError : 'has-error', // twitter-bootstrap default class name
|
672
|
+
inputParentClassOnSuccess : 'has-success' // twitter-bootstrap default class name
|
625
673
|
}
|
626
674
|
},
|
627
675
|
|
@@ -763,16 +811,11 @@
|
|
763
811
|
} else {
|
764
812
|
var findScriptPathAndLoadModules = function() {
|
765
813
|
var foundPath = false;
|
766
|
-
$('script').each(function() {
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
if( foundPath == '/' )
|
772
|
-
foundPath = '';
|
773
|
-
return false;
|
774
|
-
}
|
775
|
-
}
|
814
|
+
$('script[src*="form-validator"]').each(function() {
|
815
|
+
foundPath = this.src.substr(0, this.src.lastIndexOf('/')) + '/';
|
816
|
+
if( foundPath == '/' )
|
817
|
+
foundPath = '';
|
818
|
+
return false;
|
776
819
|
});
|
777
820
|
|
778
821
|
if( foundPath !== false) {
|
@@ -790,8 +833,8 @@
|
|
790
833
|
|
791
834
|
/**
|
792
835
|
* Validate the value of given element according to the validation rules
|
793
|
-
* found in the attribute data-validation. Will return
|
794
|
-
* error message
|
836
|
+
* found in the attribute data-validation. Will return null if no validation
|
837
|
+
* should take place, returns true if valid or error message if not valid
|
795
838
|
*
|
796
839
|
* @param {jQuery} $elem
|
797
840
|
* @param {Object} language ($.formUtils.LANG)
|
@@ -807,7 +850,7 @@
|
|
807
850
|
|
808
851
|
$elem.trigger('beforeValidation');
|
809
852
|
|
810
|
-
var value =
|
853
|
+
var value = $elem.val() || '',
|
811
854
|
optional = $elem.valAttr('optional'),
|
812
855
|
|
813
856
|
// test if a checkbox forces this element to be validated
|
@@ -859,41 +902,58 @@
|
|
859
902
|
var validator = $.formUtils.validators[rule];
|
860
903
|
|
861
904
|
if( validator && typeof validator['validatorFunction'] == 'function' ) {
|
905
|
+
|
862
906
|
// special change of element for checkbox_group rule
|
863
907
|
if ( rule == 'validate_checkbox_group' ) {
|
864
|
-
// set element to first in group, so error msg
|
908
|
+
// set element to first in group, so error msg attr doesn't need to be set on all elements in group
|
865
909
|
$elem = $("[name='"+$elem.attr('name')+"']:eq(0)");
|
866
910
|
}
|
867
|
-
|
868
|
-
var isValid =
|
911
|
+
|
912
|
+
var isValid = null;
|
869
913
|
if( eventContext != 'keyup' || validator.validateOnKeyUp ) {
|
870
914
|
isValid = validator.validatorFunction(value, $elem, conf, language, $form);
|
871
915
|
}
|
872
916
|
|
873
917
|
if(!isValid) {
|
874
|
-
validationErrorMsg =
|
875
|
-
if(
|
876
|
-
validationErrorMsg = $elem.attr(conf.validationErrorMsgAttribute);
|
918
|
+
validationErrorMsg = null;
|
919
|
+
if( isValid !== null ) {
|
920
|
+
validationErrorMsg = $elem.attr(conf.validationErrorMsgAttribute+'-'+rule.replace('validate_', ''));
|
877
921
|
if( !validationErrorMsg ) {
|
878
|
-
validationErrorMsg =
|
879
|
-
if( !validationErrorMsg )
|
880
|
-
validationErrorMsg = validator.
|
922
|
+
validationErrorMsg = $elem.attr(conf.validationErrorMsgAttribute);
|
923
|
+
if( !validationErrorMsg ) {
|
924
|
+
validationErrorMsg = language[validator.errorMessageKey];
|
925
|
+
if( !validationErrorMsg )
|
926
|
+
validationErrorMsg = validator.errorMessage;
|
927
|
+
}
|
881
928
|
}
|
882
929
|
}
|
883
930
|
return false; // breaks the iteration
|
884
931
|
}
|
885
932
|
|
886
933
|
} else {
|
887
|
-
|
934
|
+
throw new Error('Using undefined validator "'+rule+'"');
|
888
935
|
}
|
889
936
|
|
890
937
|
}, ' ');
|
891
938
|
|
939
|
+
var result;
|
940
|
+
|
892
941
|
if( typeof validationErrorMsg == 'string' ) {
|
893
|
-
|
942
|
+
$elem.trigger('validation', false);
|
943
|
+
result = validationErrorMsg;
|
944
|
+
} else if( validationErrorMsg === null && !conf.addValidClassOnAll ) {
|
945
|
+
result = null;
|
894
946
|
} else {
|
895
|
-
|
947
|
+
$elem.trigger('validation', true);
|
948
|
+
result = true;
|
949
|
+
}
|
950
|
+
|
951
|
+
// Run element validation callback
|
952
|
+
if( typeof conf.onElementValidate == 'function' && result !== null ) {
|
953
|
+
conf.onElementValidate((result === true), $elem, $form, validationErrorMsg);
|
896
954
|
}
|
955
|
+
|
956
|
+
return result;
|
897
957
|
},
|
898
958
|
|
899
959
|
/**
|
@@ -907,7 +967,7 @@
|
|
907
967
|
parseDate : function(val, dateFormat) {
|
908
968
|
var divider = dateFormat.replace(/[a-zA-Z]/gi, '').substring(0,1),
|
909
969
|
regexp = '^',
|
910
|
-
formatParts = dateFormat.split(divider),
|
970
|
+
formatParts = dateFormat.split(divider || null),
|
911
971
|
matches, day, month, year;
|
912
972
|
|
913
973
|
$.each(formatParts, function(i, part) {
|
@@ -1018,7 +1078,7 @@
|
|
1018
1078
|
numericRangeCheck : function(value, rangeAllowed)
|
1019
1079
|
{
|
1020
1080
|
// split by dash
|
1021
|
-
var range = $.split(rangeAllowed
|
1081
|
+
var range = $.split(rangeAllowed);
|
1022
1082
|
// min or max
|
1023
1083
|
var minmax = parseInt(rangeAllowed.substr(3),10)
|
1024
1084
|
// range ?
|
@@ -1028,7 +1088,8 @@
|
|
1028
1088
|
{ return ["min", minmax]; } // value is below min
|
1029
1089
|
else if (rangeAllowed.indexOf('max') === 0 && (value > minmax ) ) // max
|
1030
1090
|
{ return ["max", minmax]; } // value is above max
|
1031
|
-
|
1091
|
+
// since no other returns executed, value is in allowed range
|
1092
|
+
return [ "ok" ] ;
|
1032
1093
|
},
|
1033
1094
|
|
1034
1095
|
|
@@ -1269,24 +1330,24 @@
|
|
1269
1330
|
badTelephone : 'You have not given a correct phone number',
|
1270
1331
|
badSecurityAnswer : 'You have not given a correct answer to the security question',
|
1271
1332
|
badDate : 'You have not given a correct date',
|
1272
|
-
lengthBadStart : '
|
1333
|
+
lengthBadStart : 'The input value must be between ',
|
1273
1334
|
lengthBadEnd : ' characters',
|
1274
|
-
lengthTooLongStart : '
|
1275
|
-
lengthTooShortStart : '
|
1276
|
-
notConfirmed : '
|
1335
|
+
lengthTooLongStart : 'The input value is longer than ',
|
1336
|
+
lengthTooShortStart : 'The input value is shorter than ',
|
1337
|
+
notConfirmed : 'Input values could not be confirmed',
|
1277
1338
|
badDomain : 'Incorrect domain value',
|
1278
|
-
badUrl : 'The
|
1279
|
-
badCustomVal : '
|
1280
|
-
badInt : 'The
|
1281
|
-
badSecurityNumber : 'Your
|
1339
|
+
badUrl : 'The input value is not a correct URL',
|
1340
|
+
badCustomVal : 'The input value is incorrect',
|
1341
|
+
badInt : 'The input value was not a correct number',
|
1342
|
+
badSecurityNumber : 'Your social security number was incorrect',
|
1282
1343
|
badUKVatAnswer : 'Incorrect UK VAT Number',
|
1283
1344
|
badStrength : 'The password isn\'t strong enough',
|
1284
1345
|
badNumberOfSelectedOptionsStart : 'You have to choose at least ',
|
1285
1346
|
badNumberOfSelectedOptionsEnd : ' answers',
|
1286
|
-
badAlphaNumeric : 'The
|
1347
|
+
badAlphaNumeric : 'The input value can only contain alphanumeric characters ',
|
1287
1348
|
badAlphaNumericExtra: ' and ',
|
1288
|
-
wrongFileSize : 'The file you are trying to upload is too large',
|
1289
|
-
wrongFileType : '
|
1349
|
+
wrongFileSize : 'The file you are trying to upload is too large (max %s)',
|
1350
|
+
wrongFileType : 'Only files of type %s is allowed',
|
1290
1351
|
groupCheckedRangeStart : 'Please choose between ',
|
1291
1352
|
groupCheckedTooFewStart : 'Please choose at least ',
|
1292
1353
|
groupCheckedTooManyStart : 'Please choose a maximum of ',
|
@@ -1312,7 +1373,7 @@
|
|
1312
1373
|
var emailParts = email.toLowerCase().split('@');
|
1313
1374
|
if( emailParts.length == 2 ) {
|
1314
1375
|
return $.formUtils.validators.validate_domain.validatorFunction(emailParts[1]) &&
|
1315
|
-
!(/[^\w\+\.\-]/.test(emailParts[0]));
|
1376
|
+
!(/[^\w\+\.\-]/.test(emailParts[0])) && emailParts[0].length > 0;
|
1316
1377
|
}
|
1317
1378
|
|
1318
1379
|
return false;
|
@@ -1326,98 +1387,14 @@
|
|
1326
1387
|
*/
|
1327
1388
|
$.formUtils.addValidator({
|
1328
1389
|
name : 'domain',
|
1329
|
-
validatorFunction : function(val
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1337
|
-
'.de', '.diamonds', '.directory', '.dj', '.dk', '.dm', '.do', '.dz', '.ec', '.edu', '.ee',
|
1338
|
-
'.eg', '.enterprises', '.equipment', '.er', '.es', '.estate', '.et', '.eu', '.fi', '.fj',
|
1339
|
-
'.fk', '.fm', '.fo', '.fr', '.ga', '.gallery', '.gb', '.gd', '.ge', '.gf', '.gg', '.gh',
|
1340
|
-
'.gi', '.gl', '.gm', '.gn', '.gov', '.gp', '.gq', '.gr', '.graphics', '.gs', '.gt', '.gu',
|
1341
|
-
'.guru', '.gw', '.gy', '.hk', '.hm', '.hn', '.holdings', '.hr', '.ht', '.hu', '.id', '.ie',
|
1342
|
-
'.il', '.im', '.in', '.info', '.int', '.io', '.iq', '.ir', '.is', '.it', '.je', '.jm', '.jo',
|
1343
|
-
'.jobs', '.jp', '.ke', '.kg', '.kh', '.ki', '.kitchen', '.km', '.kn', '.kp', '.kr', '.kw',
|
1344
|
-
'.ky', '.kz', '.la', '.land', '.lb', '.lc', '.li', '.lighting', '.lk', '.lr', '.ls', '.lt',
|
1345
|
-
'.lu', '.lv', '.ly', '.ma', '.mc', '.md', '.me', '.menu', '.mg', '.mh', '.mil', '.mk', '.ml',
|
1346
|
-
'.mm', '.mn', '.mo', '.mobi', '.mp', '.mq', '.mr', '.ms', '.mt', '.mu', '.museum', '.mv',
|
1347
|
-
'.mw', '.mx', '.my', '.mz', '.na', '.name', '.nc', '.ne', '.net', '.nf', '.ng', '.ni',
|
1348
|
-
'.nl', '.no', '.np', '.nr', '.nu', '.nz', '.om', '.org', '.pa', '.pe', '.pf', '.pg', '.ph',
|
1349
|
-
'.photography', '.pk', '.pl', '.plumbing', '.pm', '.pn', '.post', '.pr', '.pro', '.ps', '.pt',
|
1350
|
-
'.pw', '.py', '.qa', '.re', '.ro', '.rs', '.ru', '.rw', '.sa', '.sb', '.sc', '.sd', '.se',
|
1351
|
-
'.sexy', '.sg', '.sh', '.si', '.singles', '.sj', '.sk', '.sl', '.sm', '.sn', '.so', '.sr',
|
1352
|
-
'.st', '.su', '.sv', '.sx', '.sy', '.sz', '.tattoo', '.tc', '.td', '.technology', '.tel', '.tf',
|
1353
|
-
'.tg', '.th', '.tips', '.tj', '.tk', '.tl', '.tm', '.tn', '.to', '.today', '.tp', '.tr', '.travel',
|
1354
|
-
'.tt', '.tv', '.tw', '.tz', '.ua', '.ug', '.uk', '.uno', '.us', '.uy', '.uz', '.va', '.vc', '.ve',
|
1355
|
-
'.ventures', '.vg', '.vi', '.vn', '.voyage', '.vu', '.wf', '.ws', '.xn--3e0b707e', '.xn--45brj9c',
|
1356
|
-
'.xn--80ao21a', '.xn--80asehdb', '.xn--80aswg', '.xn--90a3ac', '.xn--clchc0ea0b2g2a9gcd', '.xn--fiqs8s',
|
1357
|
-
'.xn--fiqz9s', '.xn--fpcrj9c3d', '.xn--fzc2c9e2c', '.xn--gecrj9c', '.xn--h2brj9c', '.xn--j1amh',
|
1358
|
-
'.xn--j6w193g', '.xn--kprw13d', '.xn--kpry57d', '.xn--l1acc', '.xn--lgbbat1ad8j', '.xn--mgb9awbf',
|
1359
|
-
'.xn--mgba3a4f16a', '.xn--mgbaam7a8h', '.xn--mgbayh7gpa', '.xn--mgbbh1a71e', '.xn--mgbc0a9azcg',
|
1360
|
-
'.xn--mgberp4a5d4ar', '.xn--mgbx4cd0ab', '.xn--ngbc5azd', '.xn--o3cw4h', '.xn--ogbpf8fl', '.xn--p1ai',
|
1361
|
-
'.xn--pgbs0dh', '.xn--q9jyb4c', '.xn--s9brj9c', '.xn--unup4y', '.xn--wgbh1c', '.xn--wgbl6a',
|
1362
|
-
'.xn--xkc2al3hye2a', '.xn--xkc2dl3a5ee0h', '.xn--yfro4i67o', '.xn--ygbi2ammx', '.xxx', '.ye',
|
1363
|
-
'.yt', '.za', '.zm', '.zw'],
|
1364
|
-
|
1365
|
-
ukTopDomains = ['co', 'me', 'ac', 'gov', 'judiciary','ltd', 'mod', 'net', 'nhs', 'nic',
|
1366
|
-
'org', 'parliament', 'plc', 'police', 'sch', 'bl', 'british-library', 'jet','nls'],
|
1367
|
-
|
1368
|
-
dot = val.lastIndexOf('.'),
|
1369
|
-
domain = val.substring(0, dot),
|
1370
|
-
ext = val.substring(dot, val.length),
|
1371
|
-
hasTopDomain = false;
|
1372
|
-
|
1373
|
-
for (var i = 0; i < topDomains.length; i++) {
|
1374
|
-
if (topDomains[i] === ext) {
|
1375
|
-
if(ext==='.uk') {
|
1376
|
-
//Run Extra Checks for UK Domain Names
|
1377
|
-
var domainParts = val.split('.');
|
1378
|
-
var tld2 = domainParts[domainParts.length-2];
|
1379
|
-
for(var j = 0; j < ukTopDomains.length; j++) {
|
1380
|
-
if(ukTopDomains[j] === tld2) {
|
1381
|
-
hasTopDomain = true;
|
1382
|
-
break;
|
1383
|
-
}
|
1384
|
-
}
|
1385
|
-
|
1386
|
-
if(hasTopDomain)
|
1387
|
-
break;
|
1388
|
-
|
1389
|
-
} else {
|
1390
|
-
hasTopDomain = true;
|
1391
|
-
break;
|
1392
|
-
}
|
1393
|
-
}
|
1394
|
-
}
|
1395
|
-
|
1396
|
-
if (!hasTopDomain) {
|
1397
|
-
return false;
|
1398
|
-
} else if (dot < 2 || dot > 57) {
|
1399
|
-
return false;
|
1400
|
-
} else {
|
1401
|
-
var firstChar = domain.substring(0, 1),
|
1402
|
-
lastChar = domain.substring(domain.length - 1, domain.length);
|
1403
|
-
|
1404
|
-
if (firstChar === '-' || firstChar === '.' || lastChar === '-' || lastChar === '.') {
|
1405
|
-
return false;
|
1406
|
-
}
|
1407
|
-
if (domain.split('.').length > 3 || domain.split('..').length > 1) {
|
1408
|
-
return false;
|
1409
|
-
}
|
1410
|
-
if (domain.replace(/[-\da-z\.]/g, '') !== '') {
|
1411
|
-
return false;
|
1412
|
-
}
|
1413
|
-
}
|
1414
|
-
|
1415
|
-
// It's valid, lets update input with trimmed value perhaps??
|
1416
|
-
if(typeof $input !== 'undefined') {
|
1417
|
-
$input.val(val);
|
1418
|
-
}
|
1419
|
-
|
1420
|
-
return true;
|
1390
|
+
validatorFunction : function(val) {
|
1391
|
+
return val.length > 0 &&
|
1392
|
+
val.length <= 253 && // Including sub domains
|
1393
|
+
!(/[^a-zA-Z0-9]/.test(val.substr(-2))) &&
|
1394
|
+
!(/[^a-zA-Z]/.test(val.substr(0,1))) &&
|
1395
|
+
!(/[^a-zA-Z0-9\.\-]/.test(val)) &&
|
1396
|
+
val.split('..').length == 1 &&
|
1397
|
+
val.split('.').length > 1;
|
1421
1398
|
},
|
1422
1399
|
errorMessage : '',
|
1423
1400
|
errorMessageKey: 'badDomain'
|
@@ -1452,8 +1429,7 @@
|
|
1452
1429
|
type = $el.attr('type');
|
1453
1430
|
|
1454
1431
|
if(lengthAllowed == undefined) {
|
1455
|
-
|
1456
|
-
alert('Please add attribute "data-validation-length" to '+elementType+' named '+$el.attr('name'));
|
1432
|
+
alert('Please add attribute "data-validation-length" to '+$el[0].nodeName+' named '+$el.attr('name'));
|
1457
1433
|
return true;
|
1458
1434
|
}
|
1459
1435
|
|
@@ -1500,8 +1476,9 @@
|
|
1500
1476
|
// - General improvements made by Stéphane Moureau <https://github.com/TraderStf>
|
1501
1477
|
var urlFilter = /^(https?|ftp):\/\/((((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])(\w|-|\.|~|[\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])(\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/(((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|\[|\]|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#(((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i;
|
1502
1478
|
if( urlFilter.test(url) ) {
|
1503
|
-
var domain = url.split('://')[1]
|
1504
|
-
|
1479
|
+
var domain = url.split('://')[1],
|
1480
|
+
domainSlashPos = domain.indexOf('/');
|
1481
|
+
|
1505
1482
|
if(domainSlashPos > -1)
|
1506
1483
|
domain = domain.substr(0, domainSlashPos);
|
1507
1484
|
|
@@ -1523,7 +1500,9 @@
|
|
1523
1500
|
var allowing = $el.valAttr('allowing') || '',
|
1524
1501
|
decimalSeparator = $el.valAttr('decimal-separator') || conf.decimalSeparator,
|
1525
1502
|
allowsRange = false,
|
1526
|
-
begin, end
|
1503
|
+
begin, end,
|
1504
|
+
steps = $el.valAttr('step') || '',
|
1505
|
+
allowsSteps = false;
|
1527
1506
|
|
1528
1507
|
if(allowing.indexOf('number') == -1)
|
1529
1508
|
allowing += ',number';
|
@@ -1538,6 +1517,9 @@
|
|
1538
1517
|
end = parseFloat(allowing.substring(allowing.indexOf(";")+1,allowing.indexOf("]")));
|
1539
1518
|
allowsRange = true;
|
1540
1519
|
}
|
1520
|
+
|
1521
|
+
if(steps != "")
|
1522
|
+
allowsSteps = true;
|
1541
1523
|
|
1542
1524
|
if( decimalSeparator == ',' ) {
|
1543
1525
|
if( val.indexOf('.') > -1 ) {
|
@@ -1547,10 +1529,10 @@
|
|
1547
1529
|
val = val.replace(',', '.');
|
1548
1530
|
}
|
1549
1531
|
|
1550
|
-
if(allowing.indexOf('number') > -1 && val.replace(/[0-9]/g, '') === '' && (!allowsRange || (val >= begin && val <= end)) ) {
|
1532
|
+
if(allowing.indexOf('number') > -1 && val.replace(/[0-9]/g, '') === '' && (!allowsRange || (val >= begin && val <= end)) && (!allowsSteps || (val%steps == 0)) ) {
|
1551
1533
|
return true;
|
1552
1534
|
}
|
1553
|
-
if(allowing.indexOf('float') > -1 && val.match(new RegExp('^([0-9]+)\\.([0-9]+)$')) !== null && (!allowsRange || (val >= begin && val <= end)) ) {
|
1535
|
+
if(allowing.indexOf('float') > -1 && val.match(new RegExp('^([0-9]+)\\.([0-9]+)$')) !== null && (!allowsRange || (val >= begin && val <= end)) && (!allowsSteps || (val%steps == 0)) ) {
|
1554
1536
|
return true;
|
1555
1537
|
}
|
1556
1538
|
}
|
@@ -1568,7 +1550,7 @@
|
|
1568
1550
|
validatorFunction : function(val, $el, conf, language) {
|
1569
1551
|
var patternStart = '^([a-zA-Z0-9',
|
1570
1552
|
patternEnd = ']+)$',
|
1571
|
-
additionalChars = $el.
|
1553
|
+
additionalChars = $el.valAttr('allowing'),
|
1572
1554
|
pattern = '';
|
1573
1555
|
|
1574
1556
|
if( additionalChars ) {
|
@@ -1609,14 +1591,7 @@
|
|
1609
1591
|
$.formUtils.addValidator({
|
1610
1592
|
name : 'date',
|
1611
1593
|
validatorFunction : function(date, $el, conf) {
|
1612
|
-
var dateFormat = 'yyyy-mm-dd';
|
1613
|
-
if($el.valAttr('format')) {
|
1614
|
-
dateFormat = $el.valAttr('format');
|
1615
|
-
}
|
1616
|
-
else if( conf.dateFormat ) {
|
1617
|
-
dateFormat = conf.dateFormat;
|
1618
|
-
}
|
1619
|
-
|
1594
|
+
var dateFormat = $el.valAttr('format') || conf.dateFormat || 'yyyy-mm-dd';
|
1620
1595
|
return $.formUtils.parseDate(date, dateFormat) !== false;
|
1621
1596
|
},
|
1622
1597
|
errorMessage : '',
|
@@ -1635,20 +1610,24 @@
|
|
1635
1610
|
$.formUtils.addValidator({
|
1636
1611
|
name : 'checkbox_group',
|
1637
1612
|
validatorFunction : function(val, $el, conf, lang, $form)
|
1638
|
-
{
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1613
|
+
{
|
1614
|
+
// preset return var
|
1615
|
+
var checkResult = true,
|
1616
|
+
// get name of element. since it is a checkbox group, all checkboxes will have same name
|
1617
|
+
elname = $el.attr('name'),
|
1618
|
+
// get count of checked checkboxes with this name
|
1619
|
+
checkedCount = $("input[type=checkbox][name^='"+elname+"']:checked", $form).length,
|
1620
|
+
// get el attr that specs qty required / allowed
|
1621
|
+
qtyAllowed = $el.valAttr('qty');
|
1622
|
+
|
1646
1623
|
if (qtyAllowed == undefined) {
|
1647
1624
|
var elementType = $el.get(0).nodeName;
|
1648
1625
|
alert('Attribute "data-validation-qty" is missing from '+elementType+' named '+$el.attr('name'));
|
1649
1626
|
}
|
1627
|
+
|
1650
1628
|
// call Utility function to check if count is above min, below max, within range etc.
|
1651
1629
|
var qtyCheckResults = $.formUtils.numericRangeCheck(checkedCount, qtyAllowed) ;
|
1630
|
+
|
1652
1631
|
// results will be array, [0]=result str, [1]=qty int
|
1653
1632
|
switch(qtyCheckResults[0] ) {
|
1654
1633
|
// outside allowed range
|
@@ -1671,8 +1650,7 @@
|
|
1671
1650
|
checkResult = true;
|
1672
1651
|
}
|
1673
1652
|
|
1674
|
-
|
1675
|
-
|
1653
|
+
return checkResult;
|
1676
1654
|
}
|
1677
1655
|
// errorMessage : '', // set above in switch statement
|
1678
1656
|
// errorMessageKey: '' // not used
|