[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Fmsystem-commits] [14419] API: update form-validator from upstream
From: |
Sigurd Nes |
Subject: |
[Fmsystem-commits] [14419] API: update form-validator from upstream |
Date: |
Thu, 19 Nov 2015 10:13:25 +0000 |
Revision: 14419
http://svn.sv.gnu.org/viewvc/?view=rev&root=fmsystem&revision=14419
Author: sigurdne
Date: 2015-11-19 10:13:24 +0000 (Thu, 19 Nov 2015)
Log Message:
-----------
API: update form-validator from upstream
Modified Paths:
--------------
branches/dev-syncromind/phpgwapi/inc/class.jquery.inc.php
branches/dev-syncromind/phpgwapi/js/form-validator/README.md
branches/dev-syncromind/phpgwapi/js/form-validator/date.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/date.js
branches/dev-syncromind/phpgwapi/js/form-validator/file.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/file.js
branches/dev-syncromind/phpgwapi/js/form-validator/html5.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/html5.js
branches/dev-syncromind/phpgwapi/js/form-validator/jquery.form-validator.js
branches/dev-syncromind/phpgwapi/js/form-validator/jquery.form-validator.min.js
branches/dev-syncromind/phpgwapi/js/form-validator/jsconf.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/jsconf.js
branches/dev-syncromind/phpgwapi/js/form-validator/location.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/location.js
branches/dev-syncromind/phpgwapi/js/form-validator/security.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/security.js
branches/dev-syncromind/phpgwapi/js/form-validator/sweden.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/sweden.js
branches/dev-syncromind/phpgwapi/js/form-validator/uk.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/uk.js
Added Paths:
-----------
branches/dev-syncromind/phpgwapi/js/form-validator/brazil.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/brazil.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/
branches/dev-syncromind/phpgwapi/js/form-validator/lang/cz.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/cz.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/de.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/de.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/es.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/es.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/fr.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/fr.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/it.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/it.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/no.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/no.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/pl.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/pl.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/pt.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/pt.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/ro.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/ro.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/ru.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/ru.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/sv.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/lang/sv.js
branches/dev-syncromind/phpgwapi/js/form-validator/sanitize.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/sanitize.js
branches/dev-syncromind/phpgwapi/js/form-validator/theme-default.css
branches/dev-syncromind/phpgwapi/js/form-validator/theme-default.min.css
branches/dev-syncromind/phpgwapi/js/form-validator/toggleDisabled.dev.js
branches/dev-syncromind/phpgwapi/js/form-validator/toggleDisabled.js
Removed Paths:
-------------
branches/dev-syncromind/phpgwapi/js/form-validator/form-test.html
branches/dev-syncromind/phpgwapi/js/form-validator/qunit.html
Modified: branches/dev-syncromind/phpgwapi/inc/class.jquery.inc.php
===================================================================
--- branches/dev-syncromind/phpgwapi/inc/class.jquery.inc.php 2015-11-19
00:28:05 UTC (rev 14418)
+++ branches/dev-syncromind/phpgwapi/inc/class.jquery.inc.php 2015-11-19
10:13:24 UTC (rev 14419)
@@ -203,57 +203,16 @@
$errorMessagePosition = "'top'";
}
- $translation = '';
- if(!$times_loaded)//first time only
- {
- //TODO: add translations
- $translation = <<<JS
-
- var validateLanguage = {
- errorTitle : 'Form submission failed!',
- requiredFields : 'You have not answered all
required fields',
- badTime : 'You have not given a correct time',
- badEmail : 'You have not given a correct
e-mail address',
- badTelephone : 'You have not given a correct
phone number',
- badSecurityAnswer : 'You have not given a
correct answer to the security question',
- badDate : 'You have not given a correct date',
- lengthBadStart : 'You must give an answer
between ',
- lengthBadEnd : ' characters',
- lengthTooLongStart : 'You have given an answer
longer than ',
- lengthTooShortStart : 'You have given an
answer shorter than ',
- notConfirmed : 'Values could not be confirmed',
- badDomain : 'Incorrect domain value',
- badUrl : 'The answer you gave was not a
correct URL',
- badCustomVal : 'You gave an incorrect answer',
- badInt : 'The answer you gave was not a
correct number',
- badSecurityNumber : 'Your social security
number was incorrect',
- badUKVatAnswer : 'Incorrect UK VAT Number',
- badStrength : 'The password isn\'t strong
enough',
- badNumberOfSelectedOptionsStart : 'You have to
choose at least ',
- badNumberOfSelectedOptionsEnd : ' answers',
- badAlphaNumeric : 'The answer you gave must
contain only alphanumeric characters ',
- badAlphaNumericExtra: ' and ',
- wrongFileSize : 'The file you are trying to
upload is too large',
- wrongFileType : 'The file you are trying to
upload is of wrong type',
- groupCheckedRangeStart : 'Please choose
between ',
- groupCheckedTooFewStart : 'Please choose at
least ',
- groupCheckedTooManyStart : 'Please choose a
maximum of ',
- groupCheckedEnd : ' item(s)'
- };
-JS;
- }
-
$js = <<<JS
- {$translation}
$(document).ready(function ()
{
$.validate({
+ lang:
'{$GLOBALS['phpgw_info']['user']['preferences']['common']['lang']}', //
(supported languages are fr, de, se, sv, en, pt, no)
modules : {$modules_js},
form: '#{$form_id}',
validateOnBlur : false,
scrollToTopOnError : false,
- errorMessagePosition :
{$errorMessagePosition},
- language : validateLanguage
+ errorMessagePosition :
{$errorMessagePosition}
});
});
JS;
Modified: branches/dev-syncromind/phpgwapi/js/form-validator/README.md
===================================================================
--- branches/dev-syncromind/phpgwapi/js/form-validator/README.md
2015-11-19 00:28:05 UTC (rev 14418)
+++ branches/dev-syncromind/phpgwapi/js/form-validator/README.md
2015-11-19 10:13:24 UTC (rev 14419)
@@ -1,12 +1,8 @@
# jQuery Form Validator
-With this feature rich jQuery plugin it becomes easy to validate user input
while keeping your
- HTML markup clean from javascript code. Even though this plugin has **a wide
range of validation functions**
-it's designed to require as little bandwidth as possible. This is achieved by
grouping together validation functions
-in "modules", making it possible for the programmer to load **only those
functions that's needed** to validate a
-particular form.
+jQuery Form Validator is a **feature rich and multilingual** jQuery plugin
that makes it easy to validate user input while keeping your HTML markup clean
from javascript code. Even though this plugin has a wide range of validation
functions it's **designed to require as little network traffic as possible**.
This is achieved by grouping together validation functions in "modules", making
it possible to load only those functions that's needed to validate a particular
form.
-**Form demos and full documentation is available at http://formvalidator.net/**
+**Form demos and full documentation available at http://formvalidator.net/**
*Usage example*
@@ -40,7 +36,7 @@
### Support for HTML5
-As of version 2.2 (unreleased) you can use this plugin as a fallback solution
for the validation attributes in the HTML5 spec. Add the module `html5` to the
module string and you can use the following native features:
+As of version 2.2 (unreleased) you can use this plugin as a fallback solution
for the validation attributes in the HTML5 spec. Add the module `html5` to the
module declaration and you can use the following native features:
**Attributes**: require, pattern, maxlength, min, max, placeholder
@@ -78,6 +74,7 @@
* **CVV**
* **strength** — *Validate the strength of a password*
* **server** — *Validate value of input on server side*
+ * **letternumeric** — *Validate that the input value consists out of only
letters and/or numbers*
Read the documentation for the security module at
[http://formvalidator.net/#security-validators](http://formvalidator.net/#security-validators)
@@ -99,7 +96,8 @@
### Module: file
* **mime**
* **extension**
- * **size**
+ * **size** (file size)
+ * **dimension** (size dimension and ratio)
Read the documentation for the file module at
[http://formvalidator.net/#file-validators](http://formvalidator.net/#file-validators)
@@ -118,7 +116,26 @@
Read the documentation for the UK module at
[http://formvalidator.net/#uk-validators](http://formvalidator.net/#uk-validators)
+### Module: brazil
+ * **brphone** — Validate a brazilian telephone number
+ * **cep**
+ * **cpf**
+### Module: sanitation
+ * **trim**
+ * **trimLeft**
+ * **trimRight**
+ * **upper** — (convert all letters to upper case)
+ * **lower** — (convert all letters to lower case)
+ * **capitalize** — (convert the first letter in all words to upper case)
+ * **insertRight** — (declare a text that should be inserted at the end of
the value, attribute data-sanitize-insert-right)
+ * **insertLeft** — (declare a text that should be inserted at the beginning
of the value, attribute data-sanitize-insert-left)
+ * **escape** — (convert < > & ' " to html entities)
+ * **numberFormat** — (declare the attribute data-sanitize-number-format with
any of the formats described on http://numeraljs.com/. Note that this rule
requires that numeral.js is included in the page)
+
+Read the documentation for the sanitation module at
[http://formvalidator.net/#data-sanitation](http://formvalidator.net/#data-sanitation)
+
+
## Writing a custom validator
You can use the function `$.formUtils.addValidator()` to add your own
validation function. Here's an example of a validator
that checks if the input contains an even number.
@@ -215,75 +232,14 @@
Read about how to customize this plugin over at
[http://formvalidator.net/#configuration](http://formvalidator.net/#configuration)
+### Validate On Event ###
+You can cause an element to be validated upon the firing of an event, by
attaching an attribute to the form input element named
`data-validation-event="click"`. When the configuration settings have
`validateOnEvent : true`, the click event will trigger the onBlur validaton for
that element. Possible use case: Checkboxes. Instead of waiting for the
checkbox to lose focus (blur) and waiting for a validation to occurr, you can
specify that elements validation should occur as soon as that checkbox element
is clicked.
+
## Localization
-This plugin contains a set of error dialogs. In case you don't define an
inline error message the plugin
-will fall back on one of the dialogs below. You can how ever add the attribute
*data-validation-error-msg* to an
-element, and that message will be displayed instead. All error dialogs can be
overwritten by passing an
-object into the validation function.
-```javascript
-var enErrorDialogs = {
- errorTitle : 'Form submission failed!',
- requiredFields : 'You have not answered all required fields',
- badTime : 'You have not given a correct time',
- badEmail : 'You have not given a correct e-mail address',
- badTelephone : 'You have not given a correct phone number',
- badSecurityAnswer : 'You have not given a correct answer to the security
question',
- badDate : 'You have not given a correct date',
- lengthBadStart : 'You must give an answer between ',
- lengthBadEnd : 'characters',
- lengthTooLongStart : 'You have given an answer longer than ',
- lengthTooShortStart : 'You have given an answer shorter than ',
- notConfirmed : 'Values could not be confirmed',
- badDomain : 'Incorrect domain value',
- badUrl : 'The answer you gave was not a correct URL',
- badCustomVal : 'You gave an incorrect answer',
- badInt : 'The answer you gave was not a correct number',
- badSecurityNumber : 'Your social security number was incorrect',
- badUKVatAnswer : 'Incorrect UK VAT Number',
- badStrength : 'The password isn\'t strong enough',
- badNumberOfSelectedOptionsStart : 'You have to choose at least ',
- badNumberOfSelectedOptionsEnd : ' answers',
- badAlphaNumeric : 'The answer you gave must contain only alphanumeric
characters ',
- badAlphaNumericExtra: ' and ',
- wrongFileSize : 'The file you are trying to upload is too large',
- wrongFileType : 'The file you are trying to upload is of wrong type',
- groupCheckedTooFewStart : 'Please choose at least ',
- groupCheckedTooManyStart : 'Please choose a maximum of ',
- groupCheckedRangeStart : 'Please choose between ',
- groupCheckedEnd : ' item(s)'
-};
-```
+This plugin comes with translations for English, German, French Spanish and
Swedish. You can also choose to override the error
+dialogs yourself. Here you can read more about
[localization](http://formvalidator.net/#localization)
-```html
-<form action="script.php">
- ...
-</form>
-<script src="js/jquery.min.js"></script>
-<script src="js/form-validator/jquery.form-validator.min.js"></script>
-<script src="js/form-validator/locale.en.js"></script>
-<script>
- $.validate({
- language : enErrorDialogs
- });
-</script>
-...
-```
-
-It's also possible to add inline error messages. If you add attribute
`data-validation-error-msg` to an element the value of
-that attribute will be displayed instead of the error dialog that the
validation function refers to.
-
-## Input length restriction
-```html
-<p>
- History (<span id="maxlength">50</span> characters left)
- <textarea rows="3" id="area"></textarea>
-</p>
-<script type="text/javascript">
- $('#area').restrictLength( $('#maxlength') );
-</script>
-```
-
## Program Flow
Form submit() event is bound to jQ func **validateForm()** when the form is
submitted, it calls
jQ func **$.formUtils.validateInput**, which calls **validatorFunction** for
the specific validation
@@ -295,7 +251,30 @@
## Changelog
-#### 2.2.0 (unreleased)
+#### 2.3.0 (unreleased)
+- New translations (Polish, Romanian, Czech, Russian, Italian)
+- Several improvements made to already existing translations
+
+#### 2.2.8
+- The plugin is now again possible to install via bower.
+- Portoguese language pack and validators
+- New module used for data-sanitiation
+- E-mail addresses now validated in accordance to rfc 6531
+- Now possible to use $.fn.validate to programmatically validate inputs
+- Hidden inputs won't get validated by default (can be overriden using option
validateHiddenInputs)
+
+
+#### 2.2.43
+- Fixed min/max parse error in HTML5 module
+- Now also supports Twitter bootstraps horizontal forms
+- This plugin now also distributes a default CSS theme including success/fail
icons (used on formvalidator.net)
+- Email validation now won't fail if email begins with a number
+- This plugin now comes with error dialogs translated to English, French,
German, Spanish and English.
+- New validator `letternumeric`. Validates that input consists out of any type
of letter (not only alphanumeric) and/or numbers
+- You can now validate image dimension and ratio
+- ... and a bunch of other smaller bug fixes and improvements.
+
+#### 2.2.0
* Now possible to define an error message for each validation rule on a
certain input (issue #113)
* This plugin now serves as a html5 fallback. You can now use the native
attributes to declare which type
of validation that should be applied.
@@ -305,8 +284,15 @@
* Use the attribute data-validation-confirm to declare which input that should
be confirmed when using validation=confirmation (issue #112)
* Validation "required" now supports inputs of type radio
* $.validateForm is now deprecated, use $.isValid instead
+* Possible to check if form is valid programmatically without showing error
messages
+* Select elements can now be validated server-side
+* Cleaned up dialog messages
+* Various IE8 fixes
+* Possible to send along parameters to the server when using server side
validation
+* Now possible to set your own parameter name when using server side validation
+* Improved/simplified URL validation
+* ... and a whole lot more small improvements
-
#### 2.1.47
* Incorrect error-styling when using datepicker or suggestions is now fixed
* Incorrect error-styling of select elements is now fixed
@@ -332,22 +318,22 @@
* Correction of the US states in validation "federatestate"
* Fixed bug in server validation
-#### 2.1.9
+#### 2.1.09
* File validation now support multiple files
* Length validation can now be used to validate the number of uploaded files
using a file input that supports multiple files
* Validation classes is no longer applied on inputs that for some reason
shouldn't become validated
-#### 2.1.8
+#### 2.1.08
* Now possible to configure the decimal separator when validating float
values. Use either the
attribute *data-validation-decimal-separator* or the property
*decimalSeparator* when
calling $.validate()
* $.validationSetup is renamed to $.validate. You will still be able to
initiate the validation by calling
the $.validationSetup but it's considered deprecated.
-#### 2.1.6
- * Modules can now be loaded from remote website
+#### 2.1.06
+ * Modules can now be loaded from remote websites
-#### 2.1.5
+#### 2.1.05
* Fixed language bug (issue #43 on github)
* Validation on server side is now triggered by the blur event
* Now using class names that's compliant with twitter bootstrap 3.x
Added: branches/dev-syncromind/phpgwapi/js/form-validator/brazil.dev.js
===================================================================
--- branches/dev-syncromind/phpgwapi/js/form-validator/brazil.dev.js
(rev 0)
+++ branches/dev-syncromind/phpgwapi/js/form-validator/brazil.dev.js
2015-11-19 10:13:24 UTC (rev 14419)
@@ -0,0 +1,115 @@
+/**
+ * jQuery Form Validator Module: Brazil
+ * ------------------------------------------
+ * Created by Eduardo Cuducos <http://cuducos.me/>
+ *
+ * This form validation module adds validators typically used on
+ * websites in the Brazil. This module adds the following validators:
+ * - cpf
+ * - cep
+ * - brphone
+ *
+ * @website http://formvalidator.net/#brazil-validators
+ * @license MIT
+ * @version 2.2.83
+ */
+
+$.formUtils.addValidator({
+ name : 'cpf',
+ validatorFunction : function(string) {
+
+ // Based on this post from DevMedia:
+ // http://www.devmedia.com.br/validar-cpf-com-javascript/23916
+
+ // clean up the input (digits only) and set some support vars
+ var cpf = string.replace(/\D/g,'');
+ var sum1 = 0;
+ var sum2 = 0;
+ var remainder1 = 0;
+ var remainder2 = 0;
+
+ // skip special cases
+ if (cpf.length !== 11 || cpf === '00000000000') {
+ return false;
+ }
+
+ // check 1st verification digit
+ for (i = 1; i<= 9; i++) {
+ sum1 += parseInt(cpf.substring(i - 1, i)) * (11 - i);
+ }
+ remainder1 = (sum1 * 10) % 11;
+ if (remainder1 >= 10) {
+ remainder1 = 0;
+ }
+ if (remainder1 !== parseInt(cpf.substring(9, 10))) {
+ return false;
+ }
+
+ // check 2nd verification digit
+ for (i = 1; i <= 10; i++) {
+ sum2 += parseInt(cpf.substring(i - 1, i)) * (12 - i);
+ }
+ remainder2 = (sum2 * 10) % 11;
+ if (remainder2 >= 10) {
+ remainder2 = 0;
+ }
+ if (remainder2 !== parseInt(cpf.substring(10, 11))) {
+ return false;
+ }
+
+ return true;
+
+ },
+ errorMessage : '',
+ errorMessageKey: 'badBrazilCPFAnswer'
+
+});
+
+$.formUtils.addValidator({
+ name : 'brphone',
+ validatorFunction : function(string) {
+
+ // validates telefones such as (having X as numbers):
+ // (XX) XXXX-XXXX
+ // (XX) XXXXX-XXXX
+ // XX XXXXXXXX
+ // XX XXXXXXXXX
+ // XXXXXXXXXX
+ // XXXXXXXXXXX
+ // +XX XX XXXXX-XXXX
+ // +X XX XXXX-XXXX
+ // And so on…
+
+ if
(string.match(/^(\+[\d]{1,3}[\s]{0,1}){0,1}(\(){0,1}(\d){2}(\)){0,1}(\s){0,1}(\d){4,5}([-.
]){0,1}(\d){4}$/g)) {
+ return true;
+ }
+
+ return false;
+
+ },
+ errorMessage : '',
+ errorMessageKey: 'badBrazilTelephoneAnswer'
+
+});
+
+$.formUtils.addValidator({
+ name : 'cep',
+ validatorFunction : function(string) {
+
+ // validates CEP such as (having X as numbers):
+ // XXXXX-XXX
+ // XXXXX.XXX
+ // XXXXX XXX
+ // XXXXXXXX
+
+ if (string.match(/^(\d){5}([-. ]){0,1}(\d){3}$/g)) {
+ return true;
+ }
+
+ return false;
+
+ },
+ errorMessage : '',
+ errorMessageKey: 'badBrazilCEPAnswer'
+
+});
Added: branches/dev-syncromind/phpgwapi/js/form-validator/brazil.js
===================================================================
--- branches/dev-syncromind/phpgwapi/js/form-validator/brazil.js
(rev 0)
+++ branches/dev-syncromind/phpgwapi/js/form-validator/brazil.js
2015-11-19 10:13:24 UTC (rev 14419)
@@ -0,0 +1,8 @@
+/**
+ * JQUERY-FORM-VALIDATOR
+ *
+ * @website by
+ * @license MIT
+ * @version 2.2.83
+ */
+$.formUtils.addValidator({name:"cpf",validatorFunction:function(a){var
b=a.replace(/\D/g,""),c=0,d=0,e=0,f=0;if(11!==b.length||"00000000000"===b)return!1;for(i=1;i<=9;i++)c+=parseInt(b.substring(i-1,i))*(11-i);if(e=10*c%11,e>=10&&(e=0),e!==parseInt(b.substring(9,10)))return!1;for(i=1;i<=10;i++)d+=parseInt(b.substring(i-1,i))*(12-i);return
f=10*d%11,f>=10&&(f=0),f!==parseInt(b.substring(10,11))?!1:!0},errorMessage:"",errorMessageKey:"badBrazilCPFAnswer"}),$.formUtils.addValidator({name:"brphone",validatorFunction:function(a){return
a.match(/^(\+[\d]{1,3}[\s]{0,1}){0,1}(\(){0,1}(\d){2}(\)){0,1}(\s){0,1}(\d){4,5}([-.
]){0,1}(\d){4}$/g)?!0:!1},errorMessage:"",errorMessageKey:"badBrazilTelephoneAnswer"}),$.formUtils.addValidator({name:"cep",validatorFunction:function(a){return
a.match(/^(\d){5}([-.
]){0,1}(\d){3}$/g)?!0:!1},errorMessage:"",errorMessageKey:"badBrazilCEPAnswer"});
\ No newline at end of file
Modified: branches/dev-syncromind/phpgwapi/js/form-validator/date.dev.js
===================================================================
--- branches/dev-syncromind/phpgwapi/js/form-validator/date.dev.js
2015-11-19 00:28:05 UTC (rev 14418)
+++ branches/dev-syncromind/phpgwapi/js/form-validator/date.dev.js
2015-11-19 10:13:24 UTC (rev 14419)
@@ -9,8 +9,8 @@
* - Birth date
*
* @website http://formvalidator.net/#location-validators
- * @license Dual licensed under the MIT or GPL Version 2 licenses
- * @version 2.2.beta.58
+ * @license MIT
+ * @version 2.2.83
*/
(function($) {
@@ -45,7 +45,7 @@
if($el.valAttr('format')) {
dateFormat = $el.valAttr('format');
}
- else if(typeof conf.dateFormat != 'undefined') {
+ else if(typeof conf.dateFormat !== 'undefined') {
dateFormat = conf.dateFormat;
}
@@ -78,4 +78,4 @@
errorMessageKey: 'badDate'
});
-})(jQuery);
\ No newline at end of file
+})(jQuery);
Modified: branches/dev-syncromind/phpgwapi/js/form-validator/date.js
===================================================================
--- branches/dev-syncromind/phpgwapi/js/form-validator/date.js 2015-11-19
00:28:05 UTC (rev 14418)
+++ branches/dev-syncromind/phpgwapi/js/form-validator/date.js 2015-11-19
10:13:24 UTC (rev 14419)
@@ -1 +1,8 @@
-(function($){$.formUtils.addValidator({name:"time",validatorFunction:function(time){if(time.match(/^(\d{2}):(\d{2})$/)===null){return
false}else{var hours=parseInt(time.split(":")[0],10);var
minutes=parseInt(time.split(":")[1],10);if(hours>23||minutes>59){return
false}}return
true},errorMessage:"",errorMessageKey:"badTime"});$.formUtils.addValidator({name:"birthdate",validatorFunction:function(val,$el,conf){var
dateFormat="yyyy-mm-dd";if($el.valAttr("format")){dateFormat=$el.valAttr("format")}else
if(typeof conf.dateFormat!="undefined"){dateFormat=conf.dateFormat}var
inputDate=$.formUtils.parseDate(val,dateFormat);if(!inputDate){return false}var
d=new Date;var currentYear=d.getFullYear();var year=inputDate[0];var
month=inputDate[1];var day=inputDate[2];if(year===currentYear){var
currentMonth=d.getMonth()+1;if(month===currentMonth){var
currentDay=d.getDate();return day<=currentDay}else{return
month<currentMonth}}else{return
year<currentYear&&year>currentYear-124}},errorMessage:"",errorMessageKey:"badDate"})})(jQuery);
+/**
+ * JQUERY-FORM-VALIDATOR
+ *
+ * @website by
+ * @license MIT
+ * @version 2.2.83
+ */
+!function(a){a.formUtils.addValidator({name:"time",validatorFunction:function(a){if(null===a.match(/^(\d{2}):(\d{2})$/))return!1;var
b=parseInt(a.split(":")[0],10),c=parseInt(a.split(":")[1],10);return
b>23||c>59?!1:!0},errorMessage:"",errorMessageKey:"badTime"}),a.formUtils.addValidator({name:"birthdate",validatorFunction:function(b,c,d){var
e="yyyy-mm-dd";c.valAttr("format")?e=c.valAttr("format"):"undefined"!=typeof
d.dateFormat&&(e=d.dateFormat);var
f=a.formUtils.parseDate(b,e);if(!f)return!1;var g=new
Date,h=g.getFullYear(),i=f[0],j=f[1],k=f[2];if(i===h){var
l=g.getMonth()+1;if(j===l){var m=g.getDate();return m>=k}return l>j}return
h>i&&i>h-124},errorMessage:"",errorMessageKey:"badDate"})}(jQuery);
\ No newline at end of file
Modified: branches/dev-syncromind/phpgwapi/js/form-validator/file.dev.js
===================================================================
--- branches/dev-syncromind/phpgwapi/js/form-validator/file.dev.js
2015-11-19 00:28:05 UTC (rev 14418)
+++ branches/dev-syncromind/phpgwapi/js/form-validator/file.dev.js
2015-11-19 10:13:24 UTC (rev 14419)
@@ -8,49 +8,78 @@
* - file size
* - file extension
*
- * @website http://formvalidator.net/
- * @license Dual licensed under the MIT or GPL Version 2 licenses
- * @version 2.2.beta.58
+ * @website http://formvalidator.net/#file-validators
+ * @license MIT
+ * @version 2.2.83
*/
(function($, window) {
'use strict';
- var SUPPORTS_FILE_READER = typeof window.FileReader != 'undefined',
+ var SUPPORTS_FILE_READER = typeof window.FileReader !== 'undefined',
- /**
- * @return {Array}
- */
- _getTypes = function($input) {
- var allowedTypes = $.split( ($input.valAttr('allowing') ||
'').toLowerCase() );
+ /**
+ * @return {Array}
+ */
+ _getTypes = function($input) {
+ var allowedTypes = $.split( ($input.valAttr('allowing') ||
'').toLowerCase() );
+ if ($.inArray('jpg', allowedTypes) > -1 && $.inArray('jpeg',
allowedTypes) === -1) {
+ allowedTypes.push('jpeg');
+ }
+ else if ($.inArray('jpeg', allowedTypes) > -1 && $.inArray('jpg',
allowedTypes) === -1) {
+ allowedTypes.push('jpg');
+ }
+ return allowedTypes;
+ },
- if( $.inArray('jpg', allowedTypes) > -1 && $.inArray('jpeg',
allowedTypes) == -1)
- allowedTypes.push('jpeg');
- else if( $.inArray('jpeg', allowedTypes) > -1 && $.inArray('jpg',
allowedTypes) == -1)
- allowedTypes.push('jpg');
- return allowedTypes;
- },
+ /**
+ * @param {Object} obj
+ * @param {String} key
+ * @param {String} insert
+ * @param {Object} lang
+ */
+ _generateErrorMsg = function(obj, key, insert, lang) {
+ var msg = lang[key] || '';
+ obj.errorMessageKey = ''; // only use message attached to this object
+ obj.errorMessage = msg.replace('\%s', insert);
+ },
- /**
- * @param {Object} obj
- * @param {String} key
- * @param {String} insert
- * @param {Object} lang
- */
- _generateErrorMsg = function(obj, key, insert, lang) {
- var msg = lang[key];
- obj.errorMessageKey = ''; // only use message attached to this
object
- obj.errorMessage = msg.replace('\%s', insert);
- },
+ /**
+ * @param {String} msg
+ */
+ _log = function(msg) {
+ if( window.console && window.console.log ) {
+ window.console.log(msg);
+ }
+ },
- /**
- * @param {String} msg
- */
- _log = function(msg) {
- if( window.console && window.console.log ) {
- window.console.log(msg);
- }
+ /**
+ * @param {String} imgPath
+ * @param {Function} successCallback
+ * @param {Function} errCallback
+ * @private
+ */
+ _loadImage = function(imgPath, successCallback, errCallback) {
+ var reader = new FileReader(),
+ image = new Image();
+
+ reader.readAsDataURL(imgPath);
+
+ reader.onload = function(fileObj) {
+
+ image.onload = function() {
+ $(window).trigger('imageValidation', [this]);
+ successCallback(this);
+ };
+
+ image.onerror= function() {
+ errCallback();
+ };
+
+ image.src = fileObj.target.result;
+
};
+ };
/*
* Validate mime type (falls back on validate_extension in older browsers)
@@ -88,7 +117,7 @@
} else {
_log('FileReader not supported by browser, will check file
extension');
- return
$.formUtils.validators.validate_extension.validatorFunction(str, $input);
+ return
$.formUtils.validators.validate_extension.validatorFunction(str, $input, conf,
language);
}
},
errorMessage : '',
@@ -106,15 +135,16 @@
allowedTypes = _getTypes($input);
$.each($input.get(0).files || [value], function(i, file) {
- var val = typeof file == 'string' ? file : (file.value ||
file.fileName || file.name),
+ var val = typeof file === 'string' ? file : (file.value ||
file.fileName || file.name),
ext = val.substr( val.lastIndexOf('.')+1 );
- if( $.inArray(ext.toLowerCase(), allowedTypes) == -1 ) {
+ if( $.inArray(ext.toLowerCase(), allowedTypes) === -1 ) {
valid = false;
_generateErrorMsg(_this, 'wrongFileType',
allowedTypes.join(', '), language);
return false;
}
});
+
return valid;
},
errorMessage : '',
@@ -159,19 +189,207 @@
*/
$.formUtils.convertSizeNameToBytes = function(sizeName) {
sizeName = sizeName.toUpperCase();
- if( sizeName.substr(sizeName.length-1, 1) == 'M' ) {
+ if( sizeName.substr(sizeName.length-1, 1) === 'M' ) {
return parseInt(sizeName.substr(0, sizeName.length-1), 10) * 1024
* 1024;
- } else if( sizeName.substr(sizeName.length-2, 2) == 'MB' ) {
+ } else if( sizeName.substr(sizeName.length-2, 2) === 'MB' ) {
return parseInt(sizeName.substr(0, sizeName.length-2), 10) * 1024
* 1024;
- } else if( sizeName.substr(sizeName.length-2, 2) == 'KB' ) {
+ } else if( sizeName.substr(sizeName.length-2, 2) === 'KB' ) {
return parseInt(sizeName.substr(0, sizeName.length-2), 10) * 1024;
- } else if( sizeName.substr(sizeName.length-1, 1) == 'B' ) {
+ } else if( sizeName.substr(sizeName.length-1, 1) === 'B' ) {
return parseInt(sizeName.substr(0, sizeName.length-1), 10);
} else {
return parseInt(sizeName, 10);
}
};
+ var disableFormSubmit = function() {
+ return false;
+ };
+
+ /**
+ * Attach dimension check onto formUtils only for unit testing purpose
+ * @param {HTMLImageElement} img
+ * @param {String} dimDeclaration
+ * @param {Boolean|String} Returns error message if image was invalid,
false otherwise
+ */
+ $.formUtils.checkImageDimension = function(img, dimDeclaration, language) {
+ var error = false,
+ restrictedDim = {width:0, height:0},
+ getDimRestriction = function(dimDeclaration) {
+ dimDeclaration = dimDeclaration.replace('min', '').replace('max',
'');
+ var chunks = dimDeclaration.split('x');
+ restrictedDim.width = chunks[0];
+ restrictedDim.height = chunks[1] ? chunks[1] : chunks[0];
+ },
+ minDeclaration = false,
+ maxDeclaration = false,
+ declarationParts = dimDeclaration.split('-');
+
+ if( declarationParts.length === 1 ) {
+ if( declarationParts[0].indexOf('min') === 0 ) {
+ minDeclaration = declarationParts[0];
+ } else {
+ maxDeclaration = declarationParts[0];
+ }
+ } else {
+ minDeclaration = declarationParts[0];
+ maxDeclaration = declarationParts[1];
+ }
+
+ if( minDeclaration ) {
+ // check min
+ getDimRestriction(minDeclaration);
+ if( img.width < restrictedDim.width || img.height <
restrictedDim.height ) {
+ error = language.imageTooSmall + ' ('+language.min+'
'+restrictedDim.width+'x'+restrictedDim.height+'px)';
+ }
+ }
+
+ if( !error && maxDeclaration ) {
+ // Check max
+ getDimRestriction(maxDeclaration);
+ if( img.width > restrictedDim.width || img.height >
restrictedDim.height ) {
+ if( img.width > restrictedDim.width ) {
+ error = language.imageTooWide +' '+restrictedDim.width+'px';
+ } else {
+ error = language.imageTooTall +' '+restrictedDim.height+'px';
+ }
+ error += ' ('+language.max+'
'+restrictedDim.width+'x'+restrictedDim.height+'px)';
+ }
+ }
+
+ return error;
+ };
+
+ /**
+ * Attach ratio validation onto formUtils only for unit testing purpose
+ * @param {HTMLImageElement} img
+ * @param {String} dimDeclaration
+ * @param {Boolean|String} Returns error message if image was invalid,
false otherwise
+ */
+ $.formUtils.checkImageRatio = function(img, ratioDeclaration, language) {
+ var ratio = img.width / img.height,
+ calculateRatio = function(declaration) {
+ var dims = declaration.replace('max', '').replace('min',
'').split(':');
+ return dims[0] / dims[1];
+ },
+ declarationParts = ratioDeclaration.split('-'),
+ isWithin = function(val, min, max) {
+ return val >= min && val <= max;
+ };
+
+ if ( declarationParts.length === 1 ) {
+ if ( ratio !== calculateRatio(declarationParts[0]) ) {
+ return language.imageRatioNotAccepted;
+ }
+ }
+ else if( declarationParts.length === 2 && !isWithin(ratio,
calculateRatio(declarationParts[0]), calculateRatio(declarationParts[1])) ) {
+ return language.imageRatioNotAccepted;
+ }
+ return false;
+ };
+
+ /**
+ * Validate image dimension
+ */
+ $.formUtils.addValidator({
+ name : 'dimension',
+ validatorFunction : function(val, $input, conf, language, $form) {
+ var hasCorrectDim = false;
+ if( SUPPORTS_FILE_READER ) {
+ var file = $input.get(0).files || [];
+ hasCorrectDim = true;
+
+ if( $input.attr('data-validation').indexOf('mime') === -1) {
+ alert('You should validate file type being jpg, gif or png on
input '+$input[0].name);
+ return false;
+ }
+ else if( file.length > 1 ) {
+ alert('Validating image dimensions does not support inputs
allowing multiple files');
+ return false;
+ } else if( file.length === 0) {
+ return true;
+ }
+
+ if( $input.valAttr('has-valid-dim') ) {
+ return true;
+ }
+ else if( $input.valAttr('has-not-valid-dim') ) {
+ this.errorMessage = language.wrongFileDim + ' ' +
$input.valAttr('has-not-valid-dim');
+ return false;
+ }
+ else if($.formUtils.eventType === 'keyup') {
+ return null;
+ }
+
+ var wasFormSubmit = false;
+
+ if( $.formUtils.isValidatingEntireForm ) {
+ wasFormSubmit = true;
+ $.formUtils.haltValidation = true;
+ $form
+ .bind('submit', disableFormSubmit)
+ .addClass('on-blur');
+ }
+
+ _loadImage(file[0], function(img) {
+ var error = false;
+
+ if ( $input.valAttr('dimension') ) {
+ error = $.formUtils.checkImageDimension(img,
$input.valAttr('dimension'), language);
+ }
+
+ if ( !error && $input.valAttr('ratio') ) {
+ error = $.formUtils.checkImageRatio(img,
$input.valAttr('ratio'), language);
+ }
+
+ // Set validation result flag on input
+ if( error ) {
+ $input.valAttr('has-not-valid-dim', error);
+ }
+ else {
+ $input.valAttr('has-valid-dim', 'true');
+ }
+
+ // Remove validation flag when input changed
+ if( !$input.valAttr('has-keyup-event') ) {
+ $input
+ .valAttr('has-keyup-event', '1')
+ .bind('keyup change', function(evt) {
+ if( evt.keyCode !== 9 && evt.keyCode !== 16 ) {
+ $(this)
+ .valAttr('has-not-valid-dim', false)
+ .valAttr('has-valid-dim', false);
+ }
+ });
+ }
+
+ if( wasFormSubmit ) {
+ $.formUtils.haltValidation = false;
+ $form
+ .removeClass('on-blur')
+ .get(0).onsubmit = function() {};
+
+ $form.unbind('submit', disableFormSubmit);
+ $form.trigger('submit'); // fire submit once more
+
+ } else {
+ $input.trigger('blur'); // triggers the validation once more
+ }
+
+ }, function(err) {
+ throw err;
+ });
+
+ return true;
+ }
+
+ return hasCorrectDim;
+ },
+ errorMessage : '',
+ errorMessageKey: '' // error message created dynamically
+ // errorMessageKey: 'wrongFileDim'
+ });
+
/*
* This event listener will remove error messages for file
* inputs when file changes
@@ -192,4 +410,4 @@
});
});
-})(jQuery, window);
\ No newline at end of file
+})(jQuery, window);
Modified: branches/dev-syncromind/phpgwapi/js/form-validator/file.js
===================================================================
--- branches/dev-syncromind/phpgwapi/js/form-validator/file.js 2015-11-19
00:28:05 UTC (rev 14418)
+++ branches/dev-syncromind/phpgwapi/js/form-validator/file.js 2015-11-19
10:13:24 UTC (rev 14419)
@@ -1 +1,8 @@
-(function($,window){"use strict";var SUPPORTS_FILE_READER=typeof
window.FileReader!="undefined",_getTypes=function($input){var
allowedTypes=$.split(($input.valAttr("allowing")||"").toLowerCase());if($.inArray("jpg",allowedTypes)>-1&&$.inArray("jpeg",allowedTypes)==-1)allowedTypes.push("jpeg");else
if($.inArray("jpeg",allowedTypes)>-1&&$.inArray("jpg",allowedTypes)==-1)allowedTypes.push("jpg");return
allowedTypes},_generateErrorMsg=function(obj,key,insert,lang){var
msg=lang[key];obj.errorMessageKey="";obj.errorMessage=msg.replace("%s",insert)},_log=function(msg){if(window.console&&window.console.log){window.console.log(msg)}};$.formUtils.addValidator({name:"mime",validatorFunction:function(str,$input,conf,language){if(SUPPORTS_FILE_READER){var
valid=true,files=$input.get(0).files||[],mime="",allowedTypes=_getTypes($input);if(files.length){$.each(files,function(i,file){valid=false;mime=file.type||"";$.each(allowedTypes,function(j,type){valid=mime.indexOf(type)>-1;if(valid){return
false}});return valid});if(!valid){_log("Trying to upload a file with mime
type "+mime+" which is not
allowed");_generateErrorMsg(this,"wrongFileType",allowedTypes.join(",
"),language)}}return valid}else{_log("FileReader not supported by browser, will
check file extension");return
$.formUtils.validators.validate_extension.validatorFunction(str,$input)}},errorMessage:"",errorMessageKey:"wrongFileType"});$.formUtils.addValidator({name:"extension",validatorFunction:function(value,$input,conf,language){var
valid=true,_this=this,allowedTypes=_getTypes($input);$.each($input.get(0).files||[value],function(i,file){var
val=typeof
file=="string"?file:file.value||file.fileName||file.name,ext=val.substr(val.lastIndexOf(".")+1);if($.inArray(ext.toLowerCase(),allowedTypes)==-1){valid=false;_generateErrorMsg(_this,"wrongFileType",allowedTypes.join(",
"),language);return false}});return
valid},errorMessage:"",errorMessageKey:"wrongFileType"});$.formUtils.addValidator({name:"size",validatorFunction:function(val,$input,conf,language){var
maxSize=$input.valAttr("max-size");if(!maxSize){_log('Input
"'+$input.attr("name")+'" is missing data-validation-max-size
attribute');return true}else if(!SUPPORTS_FILE_READER){return true}var
maxBytes=$.formUtils.convertSizeNameToBytes(maxSize),valid=true;$.each($input.get(0).files||[],function(i,file){valid=file.size<=maxBytes;return
valid});if(!valid){_generateErrorMsg(this,"wrongFileSize",maxSize,language)}return
valid},errorMessage:"",errorMessageKey:"wrongFileSize"});$.formUtils.convertSizeNameToBytes=function(sizeName){sizeName=sizeName.toUpperCase();if(sizeName.substr(sizeName.length-1,1)=="M"){return
parseInt(sizeName.substr(0,sizeName.length-1),10)*1024*1024}else
if(sizeName.substr(sizeName.length-2,2)=="MB"){return
parseInt(sizeName.substr(0,sizeName.length-2),10)*1024*1024}else
if(sizeName.substr(sizeName.length-2,2)=="KB"){return
parseInt(sizeName.substr(0,sizeName.length-2),10)*1024}else
if(sizeName.substr(sizeName.length-1,1)=="B"){return
parseInt(sizeName.substr(0,sizeName.length-1),10)}else{return
parseInt(sizeName,10)}};$(window).one("validatorsLoaded
formValidationSetup",function(evt,$form){var
$inputs;if($form){$inputs=$form.find('input[type="file"]')}else{$inputs=$('input[type="file"]')}$inputs.filter("*[data-validation]").bind("change",function(){$(this).removeClass("error").parent().find(".form-error").remove()})})})(jQuery,window);
+/**
+ * JQUERY-FORM-VALIDATOR
+ *
+ * @website by
+ * @license MIT
+ * @version 2.2.83
+ */
+!function(a,b){"use strict";var c="undefined"!=typeof
b.FileReader,d=function(b){var
c=a.split((b.valAttr("allowing")||"").toLowerCase());return
a.inArray("jpg",c)>-1&&-1===a.inArray("jpeg",c)?c.push("jpeg"):a.inArray("jpeg",c)>-1&&-1===a.inArray("jpg",c)&&c.push("jpg"),c},e=function(a,b,c,d){var
e=d[b]||"";a.errorMessageKey="",a.errorMessage=e.replace("%s",c)},f=function(a){b.console&&b.console.log&&b.console.log(a)},g=function(c,d,e){var
f=new FileReader,g=new
Image;f.readAsDataURL(c),f.onload=function(c){g.onload=function(){a(b).trigger("imageValidation",[this]),d(this)},g.onerror=function(){e()},g.src=c.target.result}};a.formUtils.addValidator({name:"mime",validatorFunction:function(b,g,h,i){if(c){var
j=!0,k=g.get(0).files||[],l="",m=d(g);return
k.length&&(a.each(k,function(b,c){return
j=!1,l=c.type||"",a.each(m,function(a,b){return j=l.indexOf(b)>-1,j?!1:void
0}),j}),j||(f("Trying to upload a file with mime type "+l+" which is not
allowed"),e(this,"wrongFileType",m.join(", "),i))),j}return f("FileReader not
supported by browser, will check file
extension"),a.formUtils.validators.validate_extension.validatorFunction(b,g,h,i)},errorMessage:"",errorMessageKey:"wrongFileType"}),a.formUtils.addValidator({name:"extension",validatorFunction:function(b,c,f,g){var
h=!0,i=this,j=d(c);return a.each(c.get(0).files||[b],function(b,c){var
d="string"==typeof
c?c:c.value||c.fileName||c.name,f=d.substr(d.lastIndexOf(".")+1);return-1===a.inArray(f.toLowerCase(),j)?(h=!1,e(i,"wrongFileType",j.join(",
"),g),!1):void
0}),h},errorMessage:"",errorMessageKey:"wrongFileType"}),a.formUtils.addValidator({name:"size",validatorFunction:function(b,d,g,h){var
i=d.valAttr("max-size");if(!i)return f('Input "'+d.attr("name")+'" is missing
data-validation-max-size attribute'),!0;if(!c)return!0;var
j=a.formUtils.convertSizeNameToBytes(i),k=!0;return
a.each(d.get(0).files||[],function(a,b){return
k=b.size<=j}),k||e(this,"wrongFileSize",i,h),k},errorMessage:"",errorMessageKey:"wrongFileSize"}),a.formUtils.convertSizeNameToBytes=function(a){return
a=a.toUpperCase(),"M"===a.substr(a.length-1,1)?1024*parseInt(a.substr(0,a.length-1),10)*1024:"MB"===a.substr(a.length-2,2)?1024*parseInt(a.substr(0,a.length-2),10)*1024:"KB"===a.substr(a.length-2,2)?1024*parseInt(a.substr(0,a.length-2),10):"B"===a.substr(a.length-1,1)?parseInt(a.substr(0,a.length-1),10):parseInt(a,10)};var
h=function(){return!1};a.formUtils.checkImageDimension=function(a,b,c){var
d=!1,e={width:0,height:0},f=function(a){a=a.replace("min","").replace("max","");var
b=a.split("x");e.width=b[0],e.height=b[1]?b[1]:b[0]},g=!1,h=!1,i=b.split("-");return
1===i.length?0===i[0].indexOf("min")?g=i[0]:h=i[0]:(g=i[0],h=i[1]),g&&(f(g),(a.width<e.width||a.height<e.height)&&(d=c.imageTooSmall+"
("+c.min+"
"+e.width+"x"+e.height+"px)")),!d&&h&&(f(h),(a.width>e.width||a.height>e.height)&&(d=a.width>e.width?c.imageTooWide+"
"+e.width+"px":c.imageTooTall+" "+e.height+"px",d+=" ("+c.max+"
"+e.width+"x"+e.height+"px)")),d},a.formUtils.checkImageRatio=function(a,b,c){var
d=a.width/a.height,e=function(a){var
b=a.replace("max","").replace("min","").split(":");return
b[0]/b[1]},f=b.split("-"),g=function(a,b,c){return
a>=b&&c>=a};if(1===f.length){if(d!==e(f[0]))return c.imageRatioNotAccepted}else
if(2===f.length&&!g(d,e(f[0]),e(f[1])))return
c.imageRatioNotAccepted;return!1},a.formUtils.addValidator({name:"dimension",validatorFunction:function(b,d,e,f,i){var
j=!1;if(c){var
k=d.get(0).files||[];if(j=!0,-1===d.attr("data-validation").indexOf("mime"))return
alert("You should validate file type being jpg, gif or png on input
"+d[0].name),!1;if(k.length>1)return alert("Validating image dimensions does
not support inputs allowing multiple
files"),!1;if(0===k.length)return!0;if(d.valAttr("has-valid-dim"))return!0;if(d.valAttr("has-not-valid-dim"))return
this.errorMessage=f.wrongFileDim+"
"+d.valAttr("has-not-valid-dim"),!1;if("keyup"===a.formUtils.eventType)return
null;var l=!1;return
a.formUtils.isValidatingEntireForm&&(l=!0,a.formUtils.haltValidation=!0,i.bind("submit",h).addClass("on-blur")),g(k[0],function(b){var
c=!1;d.valAttr("dimension")&&(c=a.formUtils.checkImageDimension(b,d.valAttr("dimension"),f)),!c&&d.valAttr("ratio")&&(c=a.formUtils.checkImageRatio(b,d.valAttr("ratio"),f)),c?d.valAttr("has-not-valid-dim",c):d.valAttr("has-valid-dim","true"),d.valAttr("has-keyup-event")||d.valAttr("has-keyup-event","1").bind("keyup
change",function(b){9!==b.keyCode&&16!==b.keyCode&&a(this).valAttr("has-not-valid-dim",!1).valAttr("has-valid-dim",!1)}),l?(a.formUtils.haltValidation=!1,i.removeClass("on-blur").get(0).onsubmit=function(){},i.unbind("submit",h),i.trigger("submit")):d.trigger("blur")},function(a){throw
a}),!0}return
j},errorMessage:"",errorMessageKey:""}),a(b).one("validatorsLoaded
formValidationSetup",function(b,c){var
d;d=c?c.find('input[type="file"]'):a('input[type="file"]'),d.filter("*[data-validation]").bind("change",function(){a(this).removeClass("error").parent().find(".form-error").remove()})})}(jQuery,window);
\ No newline at end of file
Deleted: branches/dev-syncromind/phpgwapi/js/form-validator/form-test.html
===================================================================
--- branches/dev-syncromind/phpgwapi/js/form-validator/form-test.html
2015-11-19 00:28:05 UTC (rev 14418)
+++ branches/dev-syncromind/phpgwapi/js/form-validator/form-test.html
2015-11-19 10:13:24 UTC (rev 14419)
@@ -1,422 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8" />
- <title>Form Test</title>
- <link rel="stylesheet"
href="//netdna.bootstrapcdn.com/bootstrap/3.0.0-wip/css/bootstrap.min.css" />
- <link rel="stylesheet"
href="//code.jquery.com/ui/1.10.4/themes/black-tie/jquery-ui.css" />
- <style>
-
- /* Form and inputs */
- form {
- width: 500px;
- margin: 0 auto;
- padding: 20px;
- display: block;
- }
-
- input.form-control {
- width: 375px;
- }
-
- button, input[type="submit"], .button {
- margin-bottom: 8px;
- }
-
- /* While server is being requested */
- form.validating-server-side {
- background: #F2F2F2;
- }
-
- input.validating-server-side {
- opacity: 0.5;
- background: lightgoldenrodyellow;
- }
-
- /* modify inputs for password strength */
- .password-strength input.form-control {
- width: 375px;
- margin-right: 4px;
- display: inline;
- }
-
- .password-strength label {
- display: block;
- }
-
- /* Checkboxes */
- .form-group.check-boxes input {
- margin-left: 10px;
- }
-
- span.help {
- color: #999 !important;
- }
-
- /* Error container for form C */
-
- #error-container div {
- color: red;
- line-height: 140%;
- }
-
- #error-container div:last-child {
- padding-bottom: 10px;
- }
-
- </style>
-</head>
-<body>
-<div>
- <form action="" id="form-a" role="form">
- <div class="form-group">
- <label class="control-label" for="inline-suggestions">Inline
suggestions</label>
- <input name="inline suggestions" type="text"
id="inline-suggestions" class="form-control" data-suggestions="Monkey, Horse,
Hound, Fox, Tiger, Elephant" />
- </div>
-
- <div class="form-group">
- <label class="control-label" for="country-suggestions">Country
suggestions</label>
- <input name="country suggestions" data-validation="country"
type="text" id="country-suggestions" class="form-control" />
- </div>
-
- <div class="form-group">
- <label class="control-label" for="country-suggestions">Swedish
county suggestions</label>
- <input name="Swedish county suggestion"
data-validation="swecounty" type="text" id="swedish-county-suggestions"
class="form-control" />
- </div>
-
- <div class="form-group">
- <label class="control-label">Year</label>
- <input name="birth" class="form-control"
- data-validation="date"
- data-validation-format="yyyy/mm/dd"
- data-suggestions="2014/01/15,2014/01/16,2014/01/17" />
- </div>
-
- <div class="form-group">
- <label class="control-label">Datepicker</label>
- <input name="birth2" class="form-control"
- data-validation="date"
- data-validation-format="mm/dd/yyyy"
- id="datepicker" />
- </div>
-
- <div class="form-group">
- <label class="control-label">Number 0-10 (accepting floats with
comma)</label>
- <input name="floats" class="form-control"
- data-validation="number"
- data-validation-allowing="range[0;10], float"
- data-validation-decimal-separator=","
- />
- </div>
-
- <div class="form-group password-strength">
- <label class="control-label" for="password">Display password
strength (only strong)</label>
- <input name="password" type="password" id="password"
class="form-control" data-validation="strength" data-validation-strength="3" />
- </div>
-
- <div class="form-group">
- <label class="control-label">Alphanumeric and -_ and spaces</label>
- <input name="alphanumeric with spaces" class="form-control"
name="test" data-validation="alphanumeric" data-validation-allowing="-_ " />
- </div>
-
- <div class="form-group">
- <label class="control-label">Alphanumeric only</label>
- <input name="aplhanumeric only" class="form-control" name="test2"
data-validation="alphanumeric" />
- </div>
-
- <div class="checkbox form-group">
- <label>
- <input name="checkbox" type="checkbox"
data-validation="required" /> Must be checked
- </label>
- </div>
-
- <div class="form-group">
- <label class="control-label">Must choose one</label>
- <br />
- <input name="radio" type="radio" data-validation="required"
value="1" /> A
- <input name="radio" type="radio" value="1" /> B
- <input name="radio" type="radio" value="1" /> C
- <input name="radio" type="radio" value="1" /> D
- </div>
-
- <div class="form-group">
- <label class="control-label">Even numbers only</label>
- <input name="even numbers" class="form-control" name="test4"
data-validation="even_number" />
- </div>
-
- <div class="form-group">
- <label class="control-label">Make a choice</label>
- <br />
- <select name="choice" data-validation="required"
data-validation-error-msg="Please make a choice">
- <option value="">- - Choose - -</option>
- <option>A</option>
- <option>B</option>
- <option>C</option>
- <option>D</option>
- </select>
- </div>
-
- <div class="form-group">
- <label class="control-label">Text</label>
- (<span id="max-len">20</span> chars left)<br />
- <textarea id="text-area" class="form-control"
name="some-text"></textarea>
- </div>
- <div class="form-group">
- <label class="control-label">Server validation</label>
- <input class="form-control" name="code" value="secret"
- data-validation-helssp="The word is "secret""
- data-validation="server"
-
data-validation-url="http://formvalidator.net/validate-email.php" />
- </div>
- <div class="form-group">
- <label class="control-label">File validation</label>
- <input type="file" name="some-file1" class="form-control"
- data-validation="size mime required"
- data-validation-error-msg-size="The file cant be larger
than 400kb"
- data-validation-error-msg="You must upload an image file
(max 400 kb)"
- data-validation-allowing="jpg, png, ico"
- data-validation-max-size="400kb" />
- </div>
- <div class="form-group">
- <label class="control-label">File name</label>
- <input type="text" name="some-file2" class="form-control"
- data-validation="extension required"
- data-validation-error-msg="You must write a file name with
extension jpg|png|ico"
- data-validation-allowing="jpg, png, ico"
- />
- </div>
- <div class="form-group">
- <label class="control-label">
- Callback validation, set this value to "1" and
- validation will fail
- </label>
- <input id="callback" class="form-control" />
- </div>
-
- <div class="form-group check-boxes">
- <label>Checkbox group</label><br />
- <label>
- <input type="checkbox" name="box" value="1"
- data-validation="checkbox_group"
- data-validation-qty="1-2" /> 1
- </label>
- <label>
- <input type="checkbox" name="box" value="2" /> 2
- </label>
- <label>
- <input type="checkbox" name="box" value="3" /> 3
- </label>
- <label>
- <input type="checkbox" name="box" value="4" /> 4
- </label>
- <label>
- <input type="checkbox" name="box" value="5" /> 5
- </label>
- </div>
-
- <p style="line-height: 200%">
- <input type="submit" class="button">
- <br />
- <button class="button" type="button"
- onclick="alert('Form a is ' + ( $('#form-a').isValid({},
{}, false) ? 'VALID':'NOT VALID'));">
- Test validation via js (<strong>without error
messages</strong>)
- </button>
- <br />
- <button class="button" type="button"
- onclick="alert('Form a is ' + ( $('#form-a').isValid() ?
'VALID':'NOT VALID'));">
- Test validation via js (showing error messages)
- </button>
- <br />
- <input type="reset" class="button">
- </p>
- </form>
- <hr />
- <form id="form-b">
- <div class="form-group">
- <label class="control-label">Test</label>
- <input name="test" data-validation="number" type="text" />
- </div>
- <div class="form-group">
- <label class="control-label">Password</label>
- <input name="pass" data-validation="confirmation" type="password"
/>
- </div>
- <div class="form-group">
- <label class="control-label">Password again</label>
- <input name="pass_confirmation" type="password" />
- </div>
- <p>
- <input type="submit" class="button">
- <input type="reset" class="button">
- </p>
- </form>
- <hr />
- <form id="form-c">
- <div class="form-group">
- <label class="control-label">Country</label>
- <input name="test" data-validation="country"
data-validation-error-msg="No valid country given" />
- </div>
- <div class="form-group">
- <label class="control-label">E-mail</label>
- <input name="testmail" data-validation="email"
data-validation-error-msg="E-mail is not valid" />
- </div>
- <div class="form-group">
- <label class="control-label">Confirm e-mail</label>
- <input name="test" data-validation="confirmation"
data-validation-confirm="testmail" />
- </div>
- <div class="form-group">
- <label class="control-label">Alphanumeric (will only be validated
if the checkbox is checked)</label>
- <input name="test2"
- data-validation="alphanumeric"
- data-validation-error-msg="Invalid..."
- data-validation-if-checked="checker" />
- <br />
- <input type="checkbox" name="checker" />
- </div>
- <div id="error-container">
-
- </div>
- <p>
- <input type="submit" class="button">
- <input type="reset" class="button">
- </p>
- </form>
- <hr />
- <form id="form-d">
- <h2>HTML5 attributes</h2>
- <div class="form-group">
- <label class="control-label">type="email"</label>
- <input type="text" required="required" list="mejl" />
- <datalist id="mejl">
- <option value="Test">Test</option>
- <option value="test2">test2</option>
- <option value="test3">test3</option>
- </datalist>
- </div>
- <div class="form-group">
- <label class="control-label">type="url" (optional)</label>
- <input type="url" />
- </div>
- <div class="form-group">
- <label class="control-label">type="number"</label>
- <input type="number" required="required" />
- </div>
- <div class="form-group">
- <label class="control-label">type="number"</label>
- <input type="number" required="required" maxlength="30" />
- </div>
- <div class="form-group">
- <label class="control-label">type="number" range[-5;5]</label>
- <input type="number" min="-5" max="5" required="required" />
- </div>
- <div class="form-group">
- <label class="control-label">pattern="^([a-z]+)$"</label>
- <input type="text" name="some-colorz" list="some-colorz"
pattern="^([a-z]+)$" required="required" />
- <datalist id="some-colorz" style="display: none">
- <option value="Green">Green</option>
- <option value="Blue">Blue</option>
- <option value="Red">Red</option>
- <option value="Black">Black</option>
- <option value="White">White</option>
- </datalist>
- </div>
- <p>
- <input type="submit" class="button">
- <input type="reset" class="button">
- </p>
- </form>
-</div>
-<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
-<script src="//code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>
-<script src="jquery.form-validator.js"></script>
-<script>
-(function($, window) {
-
- var dev = '.dev'; //window.location.hash.indexOf('dev') > -1 ? '.dev' : '';
-
- // setup datepicker
- $("#datepicker").datepicker();
-
- // Add a new validator
- $.formUtils.addValidator({
- name : 'even_number',
- validatorFunction : function(value, $el, config, language, $form) {
- return parseInt(value, 10) % 2 === 0;
- },
- borderColorOnError : '',
- errorMessage : 'You have to give an even number',
- errorMessageKey: 'badEvenNumber'
- });
-
- window.applyValidation = function(validateOnBlur, forms, messagePosition) {
- if( !forms )
- forms = 'form';
- if( !messagePosition )
- messagePosition = 'top';
-
- $.validate({
- form : forms,
- language : {
- requiredFields: 'Du måste bocka för denna'
- },
- validateOnBlur : validateOnBlur,
- errorMessagePosition : messagePosition,
- scrollToTopOnError : true,
- borderColorOnError : 'purple',
- modules : 'security'+dev+', location'+dev+', sweden'+dev+',
html5'+dev+', file'+dev+', uk'+dev,
- onModulesLoaded: function() {
- $('#country-suggestions').suggestCountry();
- $('#swedish-county-suggestions').suggestSwedishCounty();
- $('#password').displayPasswordStrength();
- },
- onValidate : function($f) {
-
- console.log('about to validate form '+$f.attr('id'));
-
- var $callbackInput = $('#callback');
- if( $callbackInput.val() == 1 ) {
- return {
- element : $callbackInput,
- message : 'This validation was made in a callback'
- };
- }
- },
- onError : function($form) {
- alert('Invalid '+$form.attr('id'));
- },
- onSuccess : function($form) {
- alert('Valid '+$form.attr('id'));
- return false;
- }
- });
- };
-
- $('#text-area').restrictLength($('#max-len'));
-
- window.applyValidation(true, '#form-a', 'top');
- window.applyValidation(false, '#form-b', 'element');
- window.applyValidation(true, '#form-c', $('#error-container'));
- window.applyValidation(true, '#form-d', 'element');
-
- // Load one module outside $.validate() even though you do not have to
- $.formUtils.loadModules('date'+dev+'.js', false, false);
-
- $('input')
- .on('beforeValidation', function() {
- console.log('About to validate input "'+this.name+'"');
- })
- .on('validation', function(evt, isValid) {
- var validationResult = '';
- if( isValid === null ) {
- validationResult = 'not validated';
- } else if( isValid ) {
- validationResult = 'VALID';
- } else {
- validationResult = 'INVALID';
- }
- console.log('Input '+this.name+' is '+validationResult);
- });
-
-})(jQuery, window);
-</script>
-<body>
-</html>
\ No newline at end of file
Modified: branches/dev-syncromind/phpgwapi/js/form-validator/html5.dev.js
===================================================================
--- branches/dev-syncromind/phpgwapi/js/form-validator/html5.dev.js
2015-11-19 00:28:05 UTC (rev 14418)
+++ branches/dev-syncromind/phpgwapi/js/form-validator/html5.dev.js
2015-11-19 10:13:24 UTC (rev 14419)
@@ -16,129 +16,151 @@
* - placeholders
*
* @website http://formvalidator.net/
- * @license Dual licensed under the MIT or GPL Version 2 licenses
- * @version 2.2.beta.58
+ * @license MIT
+ * @version 2.2.83
*/
(function($, window) {
- "use strict";
+ 'use strict';
var SUPPORTS_PLACEHOLDER = 'placeholder' in
document.createElement('INPUT'),
- SUPPORTS_DATALIST = 'options' in document.createElement('DATALIST');
+ SUPPORTS_DATALIST = 'options' in document.createElement('DATALIST'),
+ hasLoadedDateModule = false,
+ setupValidationUsingHTML5Attr = function($form) {
- $(window).bind('validatorsLoaded formValidationSetup', function(evt,
$form) {
+ $form.each(function() {
+ var $f = $(this),
+ $formInputs = $f.find('input,textarea,select'),
+ foundHtml5Rule = false;
- if( !$form ) {
- $form = $('form');
- }
+ $formInputs.each(function() {
+ var validation = [],
+ $input = $(this),
+ isRequired = $input.attr('required'),
+ attrs = {};
- var hasLoadedDateModule = false;
+ 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'; // js max int
+ }
- $form.each(function() {
- var $f = $(this),
- $formInputs = $f.find('input,textarea,select'),
- foundHtml5Rule = false;
+ 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;
+ }
- $formInputs.each(function() {
- var validation = [],
- $input = $(this),
- isRequired = $input.attr('required'),
- attrs = {};
+ 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');
+ }
- 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; // js max int
+ if( !SUPPORTS_DATALIST && $input.attr('list') ) {
+ var suggestions = [],
+ $list = $('#'+$input.attr('list'));
- 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;
- }
+ $list.find('option').each(function() {
+ suggestions.push($(this).text());
+ });
- if( $input.attr('pattern') ) {
- validation.push('custom');
- attrs['data-validation-regexp'] = $input.attr('pattern');
+ if( suggestions.length === 0 ) {
+ // IE fix
+ var opts =
$.trim($('#'+$input.attr('list')).text()).split('\n');
+ $.each(opts, function(i, option) {
+ suggestions.push($.trim(option));
+ });
}
- 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 );
- }
+ $list.remove();
- if( validation.length ) {
- if( !isRequired ) {
- attrs['data-validation-optional'] = 'true';
- }
+ $.formUtils.suggest( $input, suggestions );
+ }
- foundHtml5Rule = true;
- $input.attr('data-validation', validation.join(' '));
+ if ( isRequired && validation.length === 0 ) {
+ validation.push('required');
+ }
- $.each(attrs, function(attrName, attrVal) {
- $input.attr(attrName, attrVal);
- });
+ 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');
+ $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');
- }
- });
- });
+ $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');
+ }
+ });
+ });
}
- });
+ });
+ };
+
+ $(window).bind('validatorsLoaded formValidationSetup', function(evt,
$form) {
+ if( !$form ) {
+ $form = $('form');
+ }
+ setupValidationUsingHTML5Attr($form);
});
-})(jQuery, window);
\ No newline at end of file
+ // Make this method available outside the module
+ $.formUtils.setupValidationUsingHTML5Attr = setupValidationUsingHTML5Attr;
+
+})(jQuery, window);
Modified: branches/dev-syncromind/phpgwapi/js/form-validator/html5.js
===================================================================
--- branches/dev-syncromind/phpgwapi/js/form-validator/html5.js 2015-11-19
00:28:05 UTC (rev 14418)
+++ branches/dev-syncromind/phpgwapi/js/form-validator/html5.js 2015-11-19
10:13:24 UTC (rev 14419)
@@ -1 +1,8 @@
-(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);
+/**
+ * JQUERY-FORM-VALIDATOR
+ *
+ * @website by
+ * @license MIT
+ * @version 2.2.83
+ */
+!function(a,b){"use strict";var c="placeholder"in
document.createElement("INPUT"),d="options"in
document.createElement("DATALIST"),e=!1,f=function(b){b.each(function(){var
b=a(this),f=b.find("input,textarea,select"),g=!1;f.each(function(){var
b=[],c=a(this),f=c.attr("required"),h={};switch((c.attr("type")||"").toLowerCase()){case"time":b.push("time"),a.formUtils.validators.validate_date||e||(e=!0,a.formUtils.loadModules("date"));break;case"url":b.push("url");break;case"email":b.push("email");break;case"date":b.push("date");break;case"number":b.push("number");var
i=c.attr("max"),j=c.attr("min");(j||i)&&(j||(j="0"),i||(i="9007199254740992"),h["data-validation-allowing"]="range["+j+";"+i+"]",(0===j.indexOf("-")||0===i.indexOf("-"))&&(h["data-validation-allowing"]+=",negative"),(j.indexOf(".")>-1||i.indexOf(".")>-1)&&(h["data-validation-allowing"]+=",float"))}if(c.attr("pattern")&&(b.push("custom"),h["data-validation-regexp"]=c.attr("pattern")),c.attr("maxlength")&&(b.push("length"),h["data-validation-length"]="max"+c.attr("maxlength")),!d&&c.attr("list")){var
k=[],l=a("#"+c.attr("list"));if(l.find("option").each(function(){k.push(a(this).text())}),0===k.length){var
m=a.trim(a("#"+c.attr("list")).text()).split("\n");a.each(m,function(b,c){k.push(a.trim(c))})}l.remove(),a.formUtils.suggest(c,k)}f&&0===b.length&&b.push("required"),b.length&&(f||(h["data-validation-optional"]="true"),g=!0,c.attr("data-validation",b.join("
")),a.each(h,function(a,b){c.attr(a,b)}))}),g&&b.trigger("html5ValidationAttrsFound"),c||f.filter("input[placeholder]").each(function(){this.defaultValue=this.getAttribute("placeholder"),a(this).bind("focus",function(){this.value===this.defaultValue&&(this.value="",a(this).removeClass("showing-placeholder"))}).bind("blur",function(){""===a.trim(this.value)&&(this.value=this.defaultValue,a(this).addClass("showing-placeholder"))})})})};a(b).bind("validatorsLoaded
formValidationSetup",function(b,c){c||(c=a("form")),f(c)}),a.formUtils.setupValidationUsingHTML5Attr=f}(jQuery,window);
\ No newline at end of file
Modified:
branches/dev-syncromind/phpgwapi/js/form-validator/jquery.form-validator.js
===================================================================
--- branches/dev-syncromind/phpgwapi/js/form-validator/jquery.form-validator.js
2015-11-19 00:28:05 UTC (rev 14418)
+++ branches/dev-syncromind/phpgwapi/js/form-validator/jquery.form-validator.js
2015-11-19 10:13:24 UTC (rev 14419)
@@ -1,347 +1,399 @@
/**
-* jQuery Form Validator
-* ------------------------------------------
-* Created by Victor Jonsson <http://www.victorjonsson.se>
-*
-* @website http://formvalidator.net/
-* @license Dual licensed under the MIT or GPL Version 2 licenses
-* @version 2.2.beta.58
-*/
-(function($) {
+ * jQuery Form Validator
+ * ------------------------------------------
+ * Created by Victor Jonsson <http://www.victorjonsson.se>
+ *
+ * @website http://formvalidator.net/
+ * @license MIT
+ * @version 2.2.83
+ */
+(function ($) {
- 'use strict';
+ 'use strict';
- var $window = $(window),
- _applyErrorStyle = function($elem, conf) {
- $elem
- .addClass(conf.errorElementClass)
- .removeClass('valid');
+ var $window = $(window),
+ _getInputParentContainer = function ($elem) {
+ if ($elem.valAttr('error-msg-container')) {
+ return $($elem.valAttr('error-msg-container'));
+ } else {
+ var $parent = $elem.parent();
+ if ( !$parent.hasClass('form-group') &&
!$parent.closest('form').hasClass('form-horizontal') ) {
+ var $formGroup = $parent.closest('.form-group');
+ if ($formGroup.length) {
+ return $formGroup.eq(0);
+ }
+ }
+ return $parent;
+ }
+ },
+ _applyErrorStyle = function ($elem, conf) {
+ $elem
+ .addClass(conf.errorElementClass)
+ .removeClass('valid');
- var $parent = $elem.parent();
- if($parent.hasClass("input-group"))
- $parent = $parent.parent();
-
- $parent
- .addClass(conf.inputParentClassOnError)
- .removeClass(conf.inputParentClassOnSuccess);
+ _getInputParentContainer($elem)
+ .addClass(conf.inputParentClassOnError)
+ .removeClass(conf.inputParentClassOnSuccess);
- if(conf.borderColorOnError !== '') {
- $elem.css('border-color', conf.borderColorOnError);
- }
- },
- _removeErrorStyle = function($elem, conf) {
- $elem.each(function() {
- var $this = $(this),
- $parent = $this.parent();
+ if (conf.borderColorOnError !== '') {
+ $elem.css('border-color', conf.borderColorOnError);
+ }
+ },
+ _removeErrorStyle = function ($elem, conf) {
+ $elem.each(function () {
+ var $this = $(this);
- if($parent.hasClass("input-group"))
- $parent = $parent.parent();
+ _setInlineErrorMessage($this, '', conf, conf.errorMessagePosition);
- _setInlineErrorMessage($this, '', conf,
conf.errorMessagePosition);
+ $this
+ .removeClass('valid')
+ .removeClass(conf.errorElementClass)
+ .css('border-color', '');
- $this
- .removeClass('valid')
- .removeClass(conf.errorElementClass)
- .css('border-color', '');
+ _getInputParentContainer($this)
+ .removeClass(conf.inputParentClassOnError)
+ .removeClass(conf.inputParentClassOnSuccess)
+ .find('.' + conf.errorMessageClass) // remove inline span holding
error message
+ .remove();
+ });
+ },
+ _setInlineErrorMessage = function ($input, mess, conf, $messageContainer) {
+ var custom = document.getElementById($input.attr('name') + '_err_msg'),
+ setErrorMessage = function($elem) {
+ $window.trigger('validationErrorDisplay', [$input, $elem]);
+ $elem.html(mess);
+ },
+ $mess = {};
- $parent
- .removeClass(conf.inputParentClassOnError)
- .removeClass(conf.inputParentClassOnSuccess)
- .find('.'+conf.errorMessageClass) // remove inline span
holding error message
- .remove();
- });
- },
- _setInlineErrorMessage = function($input, mess, conf,
$messageContainer) {
- var custom = _getInlineErrorElement($input);
-
- if( custom ) {
- custom.innerHTML = mess;
- }
- else if( typeof $messageContainer == 'object' ) {
- var $found = false;
-
$messageContainer.find('.'+conf.errorMessageClass).each(function() {
- if( this.inputReferer == $input[0] ) {
- $found = $(this);
- return false;
- }
- });
- if( $found ) {
- if( !mess ) {
- $found.remove();
- } else {
- $found.html(mess);
- }
- } else {
- var $mess = $('<div
class="'+conf.errorMessageClass+'">'+mess+'</div>');
- $mess[0].inputReferer = $input[0];
- $messageContainer.prepend($mess);
- }
- }
- else {
- var $parent = $input.parent();
- if($parent.hasClass("input-group")) $parent =
$parent.parent();
- var $mess =
$parent.find('.'+conf.errorMessageClass+'.help-block');
- if( $mess.length == 0 ) {
- $mess =
$('<span></span>').addClass('help-block').addClass(conf.errorMessageClass);
- $mess.appendTo($parent);
- }
- $mess.html(mess);
- }
- },
- _getInlineErrorElement = function($input, conf) {
- return document.getElementById($input.attr('name')+'_err_msg');
- },
- _templateMessage = function($form, title, errorMessages, conf) {
- var messages =
conf.errorMessageTemplate.messages.replace(/\{errorTitle\}/g, title);
- var fields = [];
- $.each(errorMessages, function(i, msg) {
-
fields.push(conf.errorMessageTemplate.field.replace(/\{msg\}/g, msg));
- });
- messages = messages.replace(/\{fields\}/g, fields.join(''));
- var container =
conf.errorMessageTemplate.container.replace(/\{errorMessageClass\}/g,
conf.errorMessageClass);
- container = container.replace(/\{messages\}/g, messages);
- $form.children().eq(0).before(container);
- };
+ if (custom) {
+ setErrorMessage($(custom));
+ }
+ else if (typeof $messageContainer === 'object') {
+ var $found = false;
+ $messageContainer.find('.' + conf.errorMessageClass).each(function () {
+ if (this.inputReferer === $input[0]) {
+ $found = $(this);
+ return false;
+ }
+ });
+ if ($found) {
+ if (!mess) {
+ $found.remove();
+ } else {
+ setErrorMessage($found);
+ }
+ } else {
+ $mess = $('<div class="' + conf.errorMessageClass + '"></div>');
+ setErrorMessage($mess);
+ $mess[0].inputReferer = $input[0];
+ $messageContainer.prepend($mess);
+ }
+ }
+ else {
+ var $parent = _getInputParentContainer($input);
+ $mess = $parent.find('.' + conf.errorMessageClass + '.help-block');
- /**
- * Assigns validateInputOnBlur function to elements blur event
- *
- * @param {Object} language Optional, will override $.formUtils.LANG
- * @param {Object} settings Optional, will override the default settings
- * @return {jQuery}
- */
- $.fn.validateOnBlur = function(language, settings) {
-
this.find('input[data-validation],textarea[data-validation],select[data-validation]')
- .bind('blur.validation', function() {
- $(this).validateInputOnBlur(language, settings, true, 'blur');
- });
- if(settings.validateCheckboxRadioOnClick) {
- // bind click event to validate on click for radio & checkboxes for
nice UX
-
this.find('input[type=checkbox][data-validation],input[type=radio][data-validation]')
- .bind('click.validation', function() {
- $(this).validateInputOnBlur(language, settings, true, 'click');
- });
+ if ($mess.length === 0) {
+ $mess =
$('<span></span>').addClass('help-block').addClass(conf.errorMessageClass);
+ $mess.appendTo($parent);
}
- return this;
+ setErrorMessage($mess);
+ }
+ },
+ _templateMessage = function ($form, title, errorMessages, conf) {
+ var messages =
conf.errorMessageTemplate.messages.replace(/\{errorTitle\}/g, title),
+ fields = [],
+ container;
+
+ $.each(errorMessages, function (i, msg) {
+ fields.push(conf.errorMessageTemplate.field.replace(/\{msg\}/g, msg));
+ });
+
+ messages = messages.replace(/\{fields\}/g, fields.join(''));
+ container =
conf.errorMessageTemplate.container.replace(/\{errorMessageClass\}/g,
conf.errorMessageClass);
+ container = container.replace(/\{messages\}/g, messages);
+ $form.children().eq(0).before(container);
};
- /*
- * Assigns validateInputOnBlur function to elements custom event
- * @param {Object} language Optional, will override $.formUtils.LANG
- * @param {Object} settings Optional, will override the default settings
- * * @return {jQuery}
- */
- $.fn.validateOnEvent = function(language, settings) {
-
this.find('input[data-validation][data-validation-event],textarea[data-validation][data-validation-event],select[data-validation][data-validation-event]')
- .each(function(){
- var $el = $(this),
- etype = $el.valAttr("event");
- if (etype){
- $el.bind(etype + ".validation",
function(){
- $(this).validateInputOnBlur(language, settings,
true, etype);
- });
- }
- });
- return this;
- };
- /**
- * fade in help message when input gains focus
- * fade out when input loses focus
- * <input data-help="The info that I want to display for the user when
input is focused" ... />
- *
- * @param {String} attrName - Optional, default is data-help
- * @return {jQuery}
- */
- $.fn.showHelpOnFocus = function(attrName) {
- if(!attrName) {
- attrName = 'data-validation-help';
+ /**
+ * Assigns validateInputOnBlur function to elements blur event
+ *
+ * @param {Object} language Optional, will override $.formUtils.LANG
+ * @param {Object} conf Optional, will override the default settings
+ * @return {jQuery}
+ */
+ $.fn.validateOnBlur = function (language, conf) {
+ this.find('*[data-validation]')
+ .bind('blur.validation', function () {
+ $(this).validateInputOnBlur(language, conf, true, 'blur');
+ });
+ if (conf.validateCheckboxRadioOnClick) {
+ // bind click event to validate on click for radio & checkboxes for nice
UX
+
this.find('input[type=checkbox][data-validation],input[type=radio][data-validation]')
+ .bind('click.validation', function () {
+ $(this).validateInputOnBlur(language, conf, true, 'click');
+ });
+ }
+
+ return this;
+ };
+
+ /*
+ * Assigns validateInputOnBlur function to elements custom event
+ * @param {Object} language Optional, will override $.formUtils.LANG
+ * @param {Object} settings Optional, will override the default settings
+ * * @return {jQuery}
+ */
+ $.fn.validateOnEvent = function (language, settings) {
+ this.find('*[data-validation-event]')
+ .each(function () {
+ var $el = $(this),
+ etype = $el.valAttr('event');
+ if (etype) {
+ $el
+ .unbind(etype + '.validation')
+ .bind(etype + '.validation', function () {
+ $(this).validateInputOnBlur(language, settings, true, etype);
+ });
}
+ });
+ return this;
+ };
- // Remove previously added event listeners
- this.find('.has-help-txt')
- .valAttr('has-keyup-event', false)
- .removeClass('has-help-txt');
+ /**
+ * fade in help message when input gains focus
+ * fade out when input loses focus
+ * <input data-help="The info that I want to display for the user when input
is focused" ... />
+ *
+ * @param {String} attrName - Optional, default is data-help
+ * @return {jQuery}
+ */
+ $.fn.showHelpOnFocus = function (attrName) {
+ if (!attrName) {
+ attrName = 'data-validation-help';
+ }
- // Add help text listeners
- this.find('textarea,input').each(function() {
- var $elem = $(this),
- className = 'jquery_form_help_' + ($elem.attr('name') ||
'').replace( /(:|\.|\[|\])/g, "" ),
- help = $elem.attr(attrName);
+ // Remove previously added event listeners
+ this.find('.has-help-txt')
+ .valAttr('has-keyup-event', false)
+ .removeClass('has-help-txt');
- if(help) {
- $elem
- .addClass('has-help-txt')
- .unbind('focus.help')
- .bind('focus.help', function() {
- var $help = $elem.parent().find('.'+className);
- if($help.length == 0) {
- $help = $('<span />')
- .addClass(className)
- .addClass('help')
- .addClass('help-block') // twitter bs
- .text(help)
- .hide();
+ // Add help text listeners
+ this.find('textarea,input').each(function () {
+ var $elem = $(this),
+ className = 'jquery_form_help_' + ($elem.attr('name') ||
'').replace(/(:|\.|\[|\])/g, ''),
+ help = $elem.attr(attrName);
- $elem.after($help);
+ if (help) {
+ $elem
+ .addClass('has-help-txt')
+ .unbind('focus.help')
+ .bind('focus.help', function () {
+ var $help = $elem.parent().find('.' + className);
+ if ($help.length === 0) {
+ $help = $('<span />')
+ .addClass(className)
+ .addClass('help')
+ .addClass('help-block') // twitter bs
+ .text(help)
+ .hide();
- }
- $help.fadeIn();
- })
- .unbind('blur.help')
- .bind('blur.help', function() {
- $(this)
- .parent()
- .find('.'+className)
- .fadeOut('slow');
- });
+ $elem.after($help);
}
- });
+ $help.fadeIn();
+ })
+ .unbind('blur.help')
+ .bind('blur.help', function () {
+ $(this)
+ .parent()
+ .find('.' + className)
+ .fadeOut('slow');
+ });
+ }
+ });
- return this;
- };
+ return this;
+ };
- /**
- * Validate single input when it loses focus
- * shows error message in a span element
- * that is appended to the parent element
- *
- * @param {Object} [language] Optional, will override $.formUtils.LANG
- * @param {Object} [conf] Optional, will override the default settings
- * @param {Boolean} attachKeyupEvent Optional
- * @param {String} eventType
- * @return {jQuery}
- */
- $.fn.validateInputOnBlur = function(language, conf, attachKeyupEvent,
eventType) {
+ /**
+ * @param {Function} cb
+ * @param {Object} [conf]
+ * @param {Object} [lang]
+ */
+ $.fn.validate = function(cb, conf, lang) {
+ var language = $.extend({}, $.formUtils.LANG, lang || {});
+ this.each(function() {
+ var $elem = $(this),
+ formDefaultConfig = $elem.closest('form').get(0).validationConfig ||
{};
- $.formUtils.eventType = eventType;
+ $elem.one('validation', function(evt, isValid) {
+ if ( typeof cb === 'function' ) {
+ cb(isValid, this, evt);
+ }
+ });
- if( (this.valAttr('suggestion-nr') || this.valAttr('postpone') ||
this.hasClass('hasDatepicker')) && !window.postponedValidation ) {
- // This validation has to be postponed
- var _self = this,
- postponeTime = this.valAttr('postpone') || 200;
+ $elem.validateInputOnBlur(
+ language,
+ $.extend({}, formDefaultConfig, conf || {}),
+ true
+ );
+ });
+ };
- window.postponedValidation = function() {
- _self.validateInputOnBlur(language, conf, attachKeyupEvent,
eventType);
- window.postponedValidation = false;
- };
- setTimeout(function() {
- if( window.postponedValidation ) {
- window.postponedValidation();
- }
- }, postponeTime);
+ /**
+ * Tells whether or not validation of this input will have to postpone the
form submit ()
+ * @returns {Boolean}
+ */
+ $.fn.willPostponeValidation = function() {
+ return (this.valAttr('suggestion-nr') ||
+ this.valAttr('postpone') ||
+ this.hasClass('hasDatepicker')) &&
+ !window.postponedValidation;
+ };
- return this;
- }
+ /**
+ * Validate single input when it loses focus
+ * shows error message in a span element
+ * that is appended to the parent element
+ *
+ * @param {Object} [language] Optional, will override $.formUtils.LANG
+ * @param {Object} [conf] Optional, will override the default settings
+ * @param {Boolean} attachKeyupEvent Optional
+ * @param {String} eventType
+ * @return {jQuery}
+ */
+ $.fn.validateInputOnBlur = function (language, conf, attachKeyupEvent,
eventType) {
- language = $.extend({}, $.formUtils.LANG, language || {});
- _removeErrorStyle(this, conf);
- var $elem = this,
- $form = $elem.closest("form"),
- validationRule = $elem.attr(conf.validationRuleAttribute),
- validation = $.formUtils.validateInput(
- $elem,
- language,
- $.extend({}, conf,
{errorMessagePosition:'element'}),
- $form,
- eventType
- );
-
- if(validation === true) {
- $elem
- .addClass('valid')
- .parent()
- .addClass(conf.inputParentClassOnSuccess);
-
- } else if(validation !== null) {
+ $.formUtils.eventType = eventType;
- _applyErrorStyle($elem, conf);
- _setInlineErrorMessage($elem, validation, conf,
conf.errorMessagePosition);
+ if ( this.willPostponeValidation() ) {
+ // This validation has to be postponed
+ var _self = this,
+ postponeTime = this.valAttr('postpone') || 200;
- if(attachKeyupEvent) {
- $elem
- .unbind('keyup.validation')
- .bind('keyup.validation', function() {
- $(this).validateInputOnBlur(language, conf, false,
'keyup');
- });
- }
+ window.postponedValidation = function () {
+ _self.validateInputOnBlur(language, conf, attachKeyupEvent, eventType);
+ window.postponedValidation = false;
+ };
+
+ setTimeout(function () {
+ if (window.postponedValidation) {
+ window.postponedValidation();
}
+ }, postponeTime);
- return this;
- };
+ return this;
+ }
- /**
- * Short hand for fetching/adding/removing element attributes
- * prefixed with 'data-validation-'
- *
- * @param {String} name
- * @param {String|Boolean} [val]
- * @return string|undefined
- * @protected
- */
- $.fn.valAttr = function(name, val) {
- if( val === undefined ) {
- return this.attr('data-validation-'+name);
- } else if( val === false || val === null ) {
- return this.removeAttr('data-validation-'+name);
- } else {
- if(name.length > 0) name='-'+name;
- return this.attr('data-validation'+name, val);
- }
- };
+ language = $.extend({}, $.formUtils.LANG, language || {});
+ _removeErrorStyle(this, conf);
+ var $elem = this,
+ $form = $elem.closest('form'),
+ result = $.formUtils.validateInput(
+ $elem,
+ language,
+ conf,
+ $form,
+ eventType
+ );
- /**
- * Function that validates all inputs in active form
- *
- * @param {Object} [language]
- * @param {Object} [conf]
- * @param {Boolean} [displayError] Defaults to true
- */
- $.fn.isValid = function(language, conf, displayError) {
+ if ( result.isValid ) {
+ if( result.shouldChangeDisplay ) {
+ $elem.addClass('valid');
+ _getInputParentContainer($elem)
+ .addClass(conf.inputParentClassOnSuccess);
+ }
+ }
+ else if (!result.isValid) {
- if ($.formUtils.isLoadingModules) {
- var $self = this;
- setTimeout(function () {
- $self.isValid(language, conf, displayError);
- }, 200);
- return null;
- }
+ _applyErrorStyle($elem, conf);
+ _setInlineErrorMessage($elem, result.errorMsg, conf,
conf.errorMessagePosition);
- conf = $.extend({}, $.formUtils.defaultConfig(), conf || {});
- language = $.extend({}, $.formUtils.LANG, language || {});
- displayError = displayError !== false;
+ if (attachKeyupEvent) {
+ $elem
+ .unbind('keyup.validation')
+ .bind('keyup.validation', function () {
+ $(this).validateInputOnBlur(language, conf, false, 'keyup');
+ });
+ }
+ }
- if($.formUtils.errorDisplayPreventedWhenHalted) {
- // isValid() was called programmatically with argument
displayError set
- // to false when the validation was halted by any of the validators
- delete $.formUtils.errorDisplayPreventedWhenHalted
- displayError = false;
- }
+ return this;
+ };
+ /**
+ * Short hand for fetching/adding/removing element attributes
+ * prefixed with 'data-validation-'
+ *
+ * @param {String} name
+ * @param {String|Boolean} [val]
+ * @return string|undefined
+ * @protected
+ */
+ $.fn.valAttr = function (name, val) {
+ if (val === undefined) {
+ return this.attr('data-validation-' + name);
+ } else if (val === false || val === null) {
+ return this.removeAttr('data-validation-' + name);
+ } else {
+ name = ((name.length > 0) ? '-' + name : '');
+ return this.attr('data-validation' + name, val);
+ }
+ };
- $.formUtils.isValidatingEntireForm = true;
- $.formUtils.haltValidation = false;
+ /**
+ * Function that validates all inputs in active form
+ *
+ * @param {Object} [language]
+ * @param {Object} [conf]
+ * @param {Boolean} [displayError] Defaults to true
+ */
+ $.fn.isValid = function (language, conf, displayError) {
- /**
- * Adds message to error message stack if not already in the message
stack
- *
- * @param {String} mess
- * @para {jQuery} $elem
- */
- var addErrorMessage = function(mess, $elem) {
- if ($.inArray(mess, errorMessages) < 0) {
- errorMessages.push(mess);
- }
- errorInputs.push($elem);
- $elem.attr('current-error', mess);
- if( displayError )
- _applyErrorStyle($elem, conf);
+ if ($.formUtils.isLoadingModules) {
+ var $self = this;
+ setTimeout(function () {
+ $self.isValid(language, conf, displayError);
+ }, 200);
+ return null;
+ }
+
+ conf = $.extend({}, $.formUtils.defaultConfig(), conf || {});
+ language = $.extend({}, $.formUtils.LANG, language || {});
+ displayError = displayError !== false;
+
+ if ($.formUtils.errorDisplayPreventedWhenHalted) {
+ // isValid() was called programmatically with argument displayError set
+ // to false when the validation was halted by any of the validators
+ delete $.formUtils.errorDisplayPreventedWhenHalted;
+ displayError = false;
+ }
+
+ $.formUtils.isValidatingEntireForm = true;
+ $.formUtils.haltValidation = false;
+
+ /**
+ * Adds message to error message stack if not already in the message stack
+ *
+ * @param {String} mess
+ * @para {jQuery} $elem
+ */
+ var addErrorMessage = function (mess, $elem) {
+ if ($.inArray(mess, errorMessages) < 0) {
+ errorMessages.push(mess);
+ }
+ errorInputs.push($elem);
+ $elem.attr('current-error', mess);
+ if (displayError) {
+ _applyErrorStyle($elem, conf);
+ }
},
/** Holds inputs (of type checkox or radio) already validated, to
prevent recheck of mulitple checkboxes & radios */
checkedInputs = [],
-
+
/** Error messages for this validation */
errorMessages = [],
@@ -351,1308 +403,1429 @@
/** Form instance */
$form = this,
- /**
- * Tells whether or not to validate element with this name and of this
type
- *
- * @param {String} name
- * @param {String} type
- * @return {Boolean}
- */
- ignoreInput = function(name, type) {
- if (type === 'submit' || type === 'button' || type == 'reset') {
- return true;
- }
- return $.inArray(name, conf.ignore || []) > -1;
- };
-
- // Reset style and remove error class
- if( displayError ) {
- $form.find('.'+conf.errorMessageClass+'.alert').remove();
-
_removeErrorStyle($form.find('.'+conf.errorElementClass+',.valid'), conf);
+ /**
+ * Tells whether or not to validate element with this name and of this
type
+ *
+ * @param {String} name
+ * @param {String} type
+ * @return {Boolean}
+ */
+ ignoreInput = function (name, type) {
+ if (type === 'submit' || type === 'button' || type === 'reset') {
+ return true;
}
+ return $.inArray(name, conf.ignore || []) > -1;
+ };
- // Validate element values
-
$form.find('input,textarea,select').filter(':not([type="submit"],[type="button"])').each(function()
{
- var $elem = $(this),
- elementType = $elem.attr('type'),
- isCheckboxOrRadioBtn = elementType == 'radio' || elementType
== 'checkbox',
- elementName = $elem.attr('name');
+ // Reset style and remove error class
+ if (displayError) {
+ $form.find('.' + conf.errorMessageClass + '.alert').remove();
+ _removeErrorStyle($form.find('.' + conf.errorElementClass + ',.valid'),
conf);
+ }
- if (!ignoreInput(elementName, elementType) &&
(!isCheckboxOrRadioBtn || $.inArray(elementName, checkedInputs) < 0) ) {
+ // Validate element values
+
$form.find('input,textarea,select').filter(':not([type="submit"],[type="button"])').each(function
() {
+ var $elem = $(this),
+ elementType = $elem.attr('type'),
+ isCheckboxOrRadioBtn = elementType === 'radio' || elementType ===
'checkbox',
+ elementName = $elem.attr('name');
- if( isCheckboxOrRadioBtn )
- checkedInputs.push(elementName);
+ if (!ignoreInput(elementName, elementType) && (!isCheckboxOrRadioBtn ||
$.inArray(elementName, checkedInputs) < 0)) {
- var validation = $.formUtils.validateInput(
- $elem,
- language,
- conf,
- $form,
- 'submit'
+ if (isCheckboxOrRadioBtn) {
+ checkedInputs.push(elementName);
+ }
+
+ var result = $.formUtils.validateInput(
+ $elem,
+ language,
+ conf,
+ $form,
+ 'submit'
);
- if(validation != null) {
- if(validation !== true) {
- addErrorMessage(validation, $elem);
- } else {
- $elem
- .valAttr('current-error', false)
- .addClass('valid')
- .parent()
- .addClass('has-success');
- }
- }
- }
+ if( result.shouldChangeDisplay ) {
+ if ( !result.isValid ) {
+ addErrorMessage(result.errorMsg, $elem);
+ } else if( result.isValid ) {
+ $elem
+ .valAttr('current-error', false)
+ .addClass('valid');
+
+ _getInputParentContainer($elem)
+ .addClass(conf.inputParentClassOnSuccess);
+ }
+ }
+ }
+ });
+
+ // Run validation callback
+ if (typeof conf.onValidate === 'function') {
+ var errors = conf.onValidate($form);
+ if ($.isArray(errors)) {
+ $.each(errors, function (i, err) {
+ addErrorMessage(err.message, err.element);
});
+ }
+ else if (errors && errors.element && errors.message) {
+ addErrorMessage(errors.message, errors.element);
+ }
+ }
- // Run validation callback
- if( typeof conf.onValidate == 'function' ) {
- var errors = conf.onValidate($form);
- if( $.isArray(errors) ) {
- $.each(errors, function(i, err) {
- addErrorMessage(err.message, err.element);
- });
- }
- else if( errors && errors.element && errors.message ) {
- addErrorMessage(errors.message, errors.element);
- }
+ // Reset form validation flag
+ $.formUtils.isValidatingEntireForm = false;
+
+ // Validation failed
+ if (!$.formUtils.haltValidation && errorInputs.length > 0) {
+
+ if (displayError) {
+ // display all error messages in top of form
+ if (conf.errorMessagePosition === 'top') {
+ _templateMessage($form, language.errorTitle, errorMessages, conf);
}
+ // Customize display message
+ else if (conf.errorMessagePosition === 'custom') {
+ if (typeof conf.errorMessageCustom === 'function') {
+ conf.errorMessageCustom($form, language.errorTitle, errorMessages,
conf);
+ }
+ }
+ // Display error message below input field or in defined container
+ else {
+ $.each(errorInputs, function (i, $input) {
+ _setInlineErrorMessage($input, $input.attr('current-error'), conf,
conf.errorMessagePosition);
+ });
+ }
- // Reset form validation flag
- $.formUtils.isValidatingEntireForm = false;
+ if (conf.scrollToTopOnError) {
+ $window.scrollTop($form.offset().top - 20);
+ }
+ }
- // Validation failed
- if ( !$.formUtils.haltValidation && errorInputs.length > 0 ) {
+ return false;
+ }
- if( displayError ) {
- // display all error messages in top of form
- if (conf.errorMessagePosition === 'top') {
- _templateMessage($form, language.errorTitle,
errorMessages, conf);
- }
- // Customize display message
- else if(conf.errorMessagePosition === 'custom') {
- if( typeof conf.errorMessageCustom === 'function' ) {
- conf.errorMessageCustom($form, language.errorTitle,
errorMessages, conf);
- }
- }
- // Display error message below input field or in defined
container
- else {
- $.each(errorInputs, function(i, $input) {
- _setInlineErrorMessage($input,
$input.attr('current-error'), conf, conf.errorMessagePosition);
- });
- }
+ if (!displayError && $.formUtils.haltValidation) {
+ $.formUtils.errorDisplayPreventedWhenHalted = true;
+ }
- if(conf.scrollToTopOnError) {
- $window.scrollTop($form.offset().top - 20);
- }
+ return !$.formUtils.haltValidation;
+ };
+
+ /**
+ * @deprecated
+ * @param language
+ * @param conf
+ */
+ $.fn.validateForm = function (language, conf) {
+ if (window.console && typeof window.console.warn === 'function') {
+ window.console.warn('Use of deprecated function $.validateForm, use
$.isValid instead');
+ }
+ return this.isValid(language, conf, true);
+ };
+
+ /**
+ * Plugin for displaying input length restriction
+ */
+ $.fn.restrictLength = function (maxLengthElement) {
+ new $.formUtils.lengthRestriction(this, maxLengthElement);
+ return this;
+ };
+
+ /**
+ * Add suggestion dropdown to inputs having data-suggestions with a comma
+ * separated string with suggestions
+ * @param {Array} [settings]
+ * @returns {jQuery}
+ */
+ $.fn.addSuggestions = function (settings) {
+ var sugs = false;
+ this.find('input').each(function () {
+ var $field = $(this);
+
+ sugs = $.split($field.attr('data-suggestions'));
+
+ if (sugs.length > 0 && !$field.hasClass('has-suggestions')) {
+ $.formUtils.suggest($field, sugs, settings);
+ $field.addClass('has-suggestions');
+ }
+ });
+ return this;
+ };
+
+ /**
+ * A bit smarter split function
+ * delimiter can be space, comma, dash or pipe
+ * @param {String} val
+ * @param {Function|String} [callback]
+ * @returns {Array|void}
+ */
+ $.split = function (val, callback) {
+ if (typeof callback !== 'function') {
+ // return array
+ if (!val) {
+ return [];
+ }
+ var values = [];
+ $.each(val.split(callback ? callback : /[,|\-\s]\s*/g),
+ function (i, str) {
+ str = $.trim(str);
+ if (str.length) {
+ values.push(str);
+ }
+ }
+ );
+ return values;
+ } else if (val) {
+ // exec callback func on each
+ $.each(val.split(/[,|\-\s]\s*/g),
+ function (i, str) {
+ str = $.trim(str);
+ if (str.length) {
+ return callback(str, i);
+ }
+ }
+ );
+ }
+ };
+
+ /**
+ * Short hand function that makes the validation setup require less code
+ * @param conf
+ */
+ $.validate = function (conf) {
+
+ var defaultConf = $.extend($.formUtils.defaultConfig(), {
+ form: 'form',
+ /*
+ * Enable custom event for validation
+ */
+ validateOnEvent: false,
+ validateOnBlur: true,
+ validateCheckboxRadioOnClick: true,
+ showHelpOnFocus: true,
+ addSuggestions: true,
+ modules: '',
+ onModulesLoaded: null,
+ language: false,
+ onSuccess: false,
+ onError: false,
+ onElementValidate: false,
+ });
+
+ conf = $.extend(defaultConf, conf || {});
+
+ if( conf.lang && conf.lang !== 'en' ) {
+ var langModule = 'lang/'+conf.lang+'.js';
+ conf.modules += conf.modules.length ? ','+langModule : langModule;
+ }
+
+ // Add validation to forms
+ $(conf.form).each(function (i, form) {
+
+ // Make a reference to the config for this form
+ form.validationConfig = conf;
+
+ // Trigger jQuery event that we're about to setup va
+ var $form = $(form);
+ $window.trigger('formValidationSetup', [$form, conf]);
+
+ // Remove classes and event handlers that might have been
+ // added by a previous call to $.validate
+ $form.find('.has-help-txt')
+ .unbind('focus.validation')
+ .unbind('blur.validation');
+
+ $form
+ .removeClass('has-validation-callback')
+ .unbind('submit.validation')
+ .unbind('reset.validation')
+ .find('input[data-validation],textarea[data-validation]')
+ .unbind('blur.validation');
+
+ // Validate when submitted
+ $form.bind('submit.validation', function () {
+
+ var $form = $(this);
+
+ if ($.formUtils.haltValidation) {
+ // pressing several times on submit button while validation is halted
+ return false;
+ }
+
+ if ($.formUtils.isLoadingModules) {
+ setTimeout(function () {
+ $form.trigger('submit.validation');
+ }, 200);
+ return false;
+ }
+
+ var valid = $form.isValid(conf.language, conf);
+
+ if ($.formUtils.haltValidation) {
+ // Validation got halted by one of the validators
+ return false;
+ } else {
+ if (valid && typeof conf.onSuccess === 'function') {
+ var callbackResponse = conf.onSuccess($form);
+ if (callbackResponse === false) {
+ return false;
}
-
+ } else if (!valid && typeof conf.onError === 'function') {
+ conf.onError($form);
return false;
+ } else {
+ return valid;
+ }
}
+ })
+ .bind('reset.validation', function () {
+ // remove messages
+ $(this).find('.' + conf.errorMessageClass + '.alert').remove();
+ _removeErrorStyle($(this).find('.' + conf.errorElementClass +
',.valid'), conf);
+ })
+ .addClass('has-validation-callback');
- if( !displayError && $.formUtils.haltValidation ) {
- $.formUtils.errorDisplayPreventedWhenHalted = true;
+ if (conf.showHelpOnFocus) {
+ $form.showHelpOnFocus();
+ }
+ if (conf.addSuggestions) {
+ $form.addSuggestions();
+ }
+ if (conf.validateOnBlur) {
+ $form.validateOnBlur(conf.language, conf);
+ $form.bind('html5ValidationAttrsFound', function () {
+ $form.validateOnBlur(conf.language, conf);
+ });
+ }
+ if (conf.validateOnEvent) {
+ $form.validateOnEvent(conf.language, conf);
+ }
+ });
+
+ if (conf.modules !== '') {
+ $.formUtils.loadModules(conf.modules, false, function() {
+ if (typeof conf.onModulesLoaded === 'function') {
+ conf.onModulesLoaded();
}
+ $window.trigger('validatorsLoaded', [typeof conf.form === 'string' ?
$(conf.form) : conf.form, conf]);
+ });
+ }
+ };
- return !$.formUtils.haltValidation;
- };
+ /**
+ * Object containing utility methods for this plugin
+ */
+ $.formUtils = {
/**
- * @deprecated
- * @param language
- * @param conf
+ * Default config for $(...).isValid();
*/
- $.fn.validateForm = function(language, conf) {
- if( window.console && typeof window.console.warn == 'function' ) {
- window.console.warn('Use of deprecated function $.validateForm,
use $.isValid instead');
- }
- return this.isValid(language, conf, true);
- }
+ defaultConfig: function () {
+ return {
+ ignore: [], // Names of inputs not to be validated even though node
attribute containing the validation rules tells us to
+ errorElementClass: 'error', // Class that will be put on elements
which value is invalid
+ borderColorOnError: '#b94a48', // Border color of elements which value
is invalid, empty string to not change border color
+ errorMessageClass: 'form-error', // class name of div containing error
messages when validation fails
+ validationRuleAttribute: 'data-validation', // name of the attribute
holding the validation rules
+ validationErrorMsgAttribute: 'data-validation-error-msg', // define
custom err msg inline with element
+ errorMessagePosition: 'element', // Can be either "top" or "element"
or "custom"
+ errorMessageTemplate: {
+ container: '<div class="{errorMessageClass} alert
alert-danger">{messages}</div>',
+ messages: '<strong>{errorTitle}</strong><ul>{fields}</ul>',
+ field: '<li>{msg}</li>'
+ },
+ errorMessageCustom: _templateMessage,
+ scrollToTopOnError: true,
+ dateFormat: 'yyyy-mm-dd',
+ addValidClassOnAll: false, // whether or not to apply class="valid"
even if the input wasn't validated
+ decimalSeparator: '.',
+ inputParentClassOnError: 'has-error', // twitter-bootstrap default
class name
+ inputParentClassOnSuccess: 'has-success', // twitter-bootstrap default
class name
+ validateHiddenInputs: false, // whether or not hidden inputs should be
validated
+ };
+ },
/**
- * Plugin for displaying input length restriction
- */
- $.fn.restrictLength = function(maxLengthElement) {
- new $.formUtils.lengthRestriction(this, maxLengthElement);
- return this;
- };
+ * Available validators
+ */
+ validators: {},
/**
- * Add suggestion dropdown to inputs having data-suggestions with a comma
- * separated string with suggestions
- * @param {Array} [settings]
- * @returns {jQuery}
+ * Events triggered by form validator
*/
- $.fn.addSuggestions = function(settings) {
- var sugs = false;
- this.find('input').each(function() {
- var $field = $(this);
+ _events: {load: [], valid: [], invalid: []},
- sugs = $.split($field.attr('data-suggestions'));
+ /**
+ * Setting this property to true during validation will
+ * stop further validation from taking place and form will
+ * not be sent
+ */
+ haltValidation: false,
- if( sugs.length > 0 && !$field.hasClass('has-suggestions') ) {
- $.formUtils.suggest($field, sugs, settings);
- $field.addClass('has-suggestions');
- }
- });
- return this;
- };
+ /**
+ * This variable will be true $.fn.isValid() is called
+ * and false when $.fn.validateOnBlur is called
+ */
+ isValidatingEntireForm: false,
/**
- * A bit smarter split function
- * delimiter can be space, comma, dash or pipe
- * @param {String} val
- * @param {Function|String} [func]
- * @returns {Array|void}
+ * Function for adding a validator
+ * @param {Object} validator
*/
- $.split = function(val, func) {
- if( typeof func != 'function' ) {
- // return array
- if( !val )
- return [];
- var values = [];
- $.each(val.split(func ? func: /[,|\-\s]\s*/g ),
- function(i,str) {
- str = $.trim(str);
- if( str.length )
- values.push(str);
- }
- );
- return values;
- } else if( val ) {
- // exec callback func on each
- $.each(val.split(/[,|\-\s]\s*/g),
- function(i, str) {
- str = $.trim(str);
- if( str.length )
- return func(str, i);
- }
- );
- }
- };
+ addValidator: function (validator) {
+ // prefix with "validate_" for backward compatibility reasons
+ var name = validator.name.indexOf('validate_') === 0 ? validator.name :
'validate_' + validator.name;
+ if (validator.validateOnKeyUp === undefined) {
+ validator.validateOnKeyUp = true;
+ }
+ this.validators[name] = validator;
+ },
/**
- * Short hand function that makes the validation setup require less code
- * @param conf
+ * @var {Boolean}
*/
- $.validate = function(conf) {
+ isLoadingModules: false,
- var defaultConf = $.extend($.formUtils.defaultConfig(), {
- form : 'form',
- /*
- * Enable custom event for validation
- */
- validateOnEvent : true,
- validateOnBlur : true,
- validateCheckboxRadioOnClick : true,
- showHelpOnFocus : true,
- addSuggestions : true,
- modules : '',
- onModulesLoaded : null,
- language : false,
- onSuccess : false,
- onError : false,
- onElementValidate : false,
- });
+ /**
+ * @var {Object}
+ */
+ loadedModules: {},
- conf = $.extend(defaultConf, conf || {});
+ /**
+ * @example
+ * $.formUtils.loadModules('date, security.dev');
+ *
+ * Will load the scripts date.js and security.dev.js from the
+ * directory where this script resides. If you want to load
+ * the modules from another directory you can use the
+ * path argument.
+ *
+ * The script will be cached by the browser unless the module
+ * name ends with .dev
+ *
+ * @param {String} modules - Comma separated string with module file names
(no directory nor file extension)
+ * @param {String} [path] - Optional, path where the module files is
located if their not in the same directory as the core modules
+ * @param {Boolean|function} [fireEvent] - Optional, whether or not to
fire event 'load' when modules finished loading
+ */
+ loadModules: function (modules, path, fireEvent) {
- // Add validation to forms
- $(conf.form).each(function(i, form) {
+ if (fireEvent === undefined) {
+ fireEvent = true;
+ }
- var $form = $(form);
- $window.trigger('formValidationSetup', [$form]);
+ if ($.formUtils.isLoadingModules) {
+ setTimeout(function () {
+ $.formUtils.loadModules(modules, path, fireEvent);
+ });
+ return;
+ }
- // Remove all event listeners previously added
- $form.find('.has-help-txt')
- .unbind('focus.validation')
- .unbind('blur.validation');
- $form
- .removeClass('has-validation-callback')
- .unbind('submit.validation')
- .unbind('reset.validation')
- .find('input[data-validation],textarea[data-validation]')
- .unbind('blur.validation');
+ var hasLoadedAnyModule = false,
+ loadModuleScripts = function (modules, path) {
- // Validate when submitted
- $form.bind('submit.validation', function() {
- var $form = $(this);
-
- if( $.formUtils.haltValidation ) {
- // pressing several times on submit button while
validation is halted
- return false;
+ var moduleList = $.split(modules),
+ numModules = moduleList.length,
+ moduleLoadedCallback = function () {
+ numModules--;
+ if (numModules === 0) {
+ $.formUtils.isLoadingModules = false;
+ if (fireEvent && hasLoadedAnyModule) {
+ if( typeof fireEvent === 'function' ) {
+ fireEvent();
+ } else {
+ $window.trigger('validatorsLoaded');
+ }
}
+ }
+ };
- if($.formUtils.isLoadingModules) {
- setTimeout(function() {
- $form.trigger('submit.validation');
- }, 200);
- return false;
- }
- var valid = $form.isValid(conf.language, conf);
+ if (numModules > 0) {
+ $.formUtils.isLoadingModules = true;
+ }
- if( $.formUtils.haltValidation ) {
- // Validation got halted by one of the validators
- return false;
- } else {
- if( valid && typeof conf.onSuccess == 'function') {
- var callbackResponse = conf.onSuccess($form);
- if( callbackResponse === false )
- return false;
- } else if ( !valid && typeof conf.onError == 'function' ) {
- conf.onError($form);
- return false;
- } else {
- return valid;
- }
- }
- })
- .bind('reset.validation', function() {
- // remove messages
- $(this).find('.'+conf.errorMessageClass+'.alert').remove();
-
_removeErrorStyle($(this).find('.'+conf.errorElementClass+',.valid'), conf);
- })
- .addClass('has-validation-callback');
+ var cacheSuffix = '?_=' + ( new Date().getTime() ),
+ appendToElement = document.getElementsByTagName('head')[0] ||
document.getElementsByTagName('body')[0];
- if( conf.showHelpOnFocus ) {
- $form.showHelpOnFocus();
+ $.each(moduleList, function (i, modName) {
+ modName = $.trim(modName);
+ if (modName.length === 0) {
+ moduleLoadedCallback();
}
- if( conf.addSuggestions ) {
- $form.addSuggestions();
+ else {
+ var scriptUrl = path + modName + (modName.slice(-3) === '.js' ?
'' : '.js'),
+ script = document.createElement('SCRIPT');
+
+ if (scriptUrl in $.formUtils.loadedModules) {
+ // already loaded
+ moduleLoadedCallback();
+ }
+ else {
+
+ // Remember that this script is loaded
+ $.formUtils.loadedModules[scriptUrl] = 1;
+ hasLoadedAnyModule = true;
+
+ // Load the script
+ script.type = 'text/javascript';
+ script.onload = moduleLoadedCallback;
+ script.src = scriptUrl + ( scriptUrl.slice(-7) === '.dev.js' ?
cacheSuffix : '' );
+ script.onerror = function() {
+ if( 'console' in window && window.console.log ) {
+ window.console.log('Unable to load form validation module
'+scriptUrl);
+ }
+ };
+ script.onreadystatechange = function () {
+ // IE 7 fix
+ if (this.readyState === 'complete' || this.readyState ===
'loaded') {
+ moduleLoadedCallback();
+ // Handle memory leak in IE
+ this.onload = null;
+ this.onreadystatechange = null;
+ }
+ };
+ appendToElement.appendChild(script);
+ }
}
- if( conf.validateOnBlur ) {
- $form.validateOnBlur(conf.language, conf);
- $form.bind('html5ValidationAttrsFound', function() {
- $form.validateOnBlur(conf.language, conf);
- })
+ });
+ };
+
+ if (path) {
+ loadModuleScripts(modules, path);
+ } else {
+ var findScriptPathAndLoadModules = function () {
+ var foundPath = false;
+ $('script[src*="form-validator"]').each(function () {
+ foundPath = this.src.substr(0, this.src.lastIndexOf('/')) + '/';
+ if (foundPath === '/') {
+ foundPath = '';
}
- if( conf.validateOnEvent ){
- $form.validateOnEvent(conf.language, conf);
- }
- });
+ return false;
+ });
- if( conf.modules != '' ) {
- if( typeof conf.onModulesLoaded == 'function' ) {
- $window.one('validatorsLoaded', conf.onModulesLoaded);
- }
- $.formUtils.loadModules(conf.modules);
+ if (foundPath !== false) {
+ loadModuleScripts(modules, foundPath);
+ return true;
+ }
+ return false;
+ };
+
+ if (!findScriptPathAndLoadModules()) {
+ $(findScriptPathAndLoadModules);
}
- };
+ }
+ },
/**
- * Object containing utility methods for this plugin
+ * Validate the value of given element according to the validation rules
+ * found in the attribute data-validation. Will return an object
representing
+ * a validation result, having the props shouldChangeDisplay, isValid and
errorMsg
+ * @param {jQuery} $elem
+ * @param {Object} language ($.formUtils.LANG)
+ * @param {Object} conf
+ * @param {jQuery} $form
+ * @param {String} [eventContext]
+ * @return {Object}
*/
- $.formUtils = {
+ validateInput: function ($elem, language, conf, $form, eventContext) {
- /**
- * Default config for $(...).isValid();
- */
- defaultConfig : function() {
- return {
- ignore : [], // Names of inputs not to be validated even
though node attribute containing the validation rules tells us to
- errorElementClass : 'error', // Class that will be put on
elements which value is invalid
- borderColorOnError : 'red', // Border color of elements which
value is invalid, empty string to not change border color
- errorMessageClass : 'form-error', // class name of div
containing error messages when validation fails
- validationRuleAttribute : 'data-validation', // name of the
attribute holding the validation rules
- validationErrorMsgAttribute : 'data-validation-error-msg', //
define custom err msg inline with element
- errorMessagePosition : 'element', // Can be either "top" or
"element" or "custom"
- errorMessageTemplate : {
- container: '<div class="{errorMessageClass} alert
alert-danger">{messages}</div>',
- messages: '<strong>{errorTitle}</strong><ul>{fields}</ul>',
- field: '<li>{msg}</li>'
- },
- errorMessageCustom: _templateMessage,
- scrollToTopOnError : true,
- dateFormat : 'yyyy-mm-dd',
- addValidClassOnAll : false, // whether or not to apply
class="valid" even if the input wasn't validated
- decimalSeparator : '.',
- inputParentClassOnError : 'has-error', // twitter-bootstrap
default class name
- inputParentClassOnSuccess : 'has-success' // twitter-bootstrap
default class name
- }
- },
+ $elem.trigger('beforeValidation');
+ conf = conf || $.formUtils.defaultConfig();
+ language = language || $.formUtils.LANG;
- /**
- * Available validators
- */
- validators : {},
+ var value = $elem.val() || '',
+ result = {isValid: true, shouldChangeDisplay:true, errorMsg:''},
+ optional = $elem.valAttr('optional'),
- /**
- * Events triggered by form validator
- */
- _events : {load : [], valid: [], invalid:[]},
+ // test if a checkbox forces this element to be validated
+ validationDependsOnCheckedInput = false,
+ validationDependentInputIsChecked = false,
+ validateIfCheckedElement = false,
- /**
- * Setting this property to true during validation will
- * stop further validation from taking place and form will
- * not be sent
- */
- haltValidation : false,
+ // get value of this element's attribute "... if-checked"
+ validateIfCheckedElementName = $elem.valAttr('if-checked'),
+ // get expected radio button value for "if-checked" optional
validation
+ validateIfCheckedElementValue = $elem.valAttr('if-checked-value');
- /**
- * This variable will be true $.fn.isValid() is called
- * and false when $.fn.validateOnBlur is called
- */
- isValidatingEntireForm : false,
- /**
- * Function for adding a validator
- * @param {Object} validator
- */
- addValidator : function(validator) {
- // prefix with "validate_" for backward compatibility reasons
- var name = validator.name.indexOf('validate_') === 0 ?
validator.name : 'validate_'+validator.name;
- if( validator.validateOnKeyUp === undefined )
- validator.validateOnKeyUp = true;
- this.validators[name] = validator;
- },
+ if ($elem.attr('disabled') || (!$elem.is(':visible') &&
!conf.validateHiddenInputs)) {
+ result.shouldChangeDisplay = false;
+ return result;
+ }
- /**
- * @var {Boolean}
- */
- isLoadingModules : false,
+ // make sure we can proceed
+ if (validateIfCheckedElementName != null) {
- /**
- * @var {Object}
- */
- loadedModules : {},
+ // Set the boolean telling us that the validation depends
+ // on another input being checked
+ validationDependsOnCheckedInput = true;
- /**
- * @example
- * $.formUtils.loadModules('date, security.dev');
- *
- * Will load the scripts date.js and security.dev.js from the
- * directory where this script resides. If you want to load
- * the modules from another directory you can use the
- * path argument.
- *
- * The script will be cached by the browser unless the module
- * name ends with .dev
- *
- * @param {String} modules - Comma separated string with module file
names (no directory nor file extension)
- * @param {String} [path] - Optional, path where the module files is
located if their not in the same directory as the core modules
- * @param {Boolean} [fireEvent] - Optional, whether or not to fire
event 'load' when modules finished loading
- */
- loadModules : function(modules, path, fireEvent) {
+ // select the checkbox type element in this form
+ validateIfCheckedElement = $form.find('input[name="' +
validateIfCheckedElementName + '"]');
- if( fireEvent === undefined )
- fireEvent = true;
-
- if( $.formUtils.isLoadingModules ) {
- setTimeout(function() {
- $.formUtils.loadModules(modules, path, fireEvent);
- });
- return;
+ // test if check input value
+ if (validateIfCheckedElementValue != null) {
+ validateIfCheckedElement.each(function(index, el) {
+ // test if it's property "checked" is checked and value equals
expected value
+ if ($(el).prop('checked') && $(el).val() ===
validateIfCheckedElementValue) {
+ validationDependentInputIsChecked = true;
}
+ });
+ }
+ else {
+ // test if it's property "checked" is checked
+ if (validateIfCheckedElement.prop('checked')) {
+ // set value for validation checkpoint
+ validationDependentInputIsChecked = true;
+ }
+ }
+ }
- var hasLoadedAnyModule = false,
- loadModuleScripts = function(modules, path) {
+ // validation checkpoint
+ // if empty AND optional attribute is present
+ // OR depending on a checkbox being checked AND checkbox is checked,
return true
+ var isInvalidNumberInput = !value && $elem[0].type === 'number';
+ if ((!value && optional === 'true' && !isInvalidNumberInput) ||
(validationDependsOnCheckedInput && !validationDependentInputIsChecked)) {
+ result.shouldChangeDisplay = conf.addValidClassOnAll;
+ return result;
+ }
- var moduleList = $.split(modules),
- numModules = moduleList.length,
- moduleLoadedCallback = function() {
- numModules--;
- if( numModules == 0 ) {
- $.formUtils.isLoadingModules = false;
- if( fireEvent && hasLoadedAnyModule ) {
- $window.trigger('validatorsLoaded');
- }
- }
- };
+ var validationRules = $elem.attr(conf.validationRuleAttribute),
- if( numModules > 0 ) {
- $.formUtils.isLoadingModules = true;
- }
+ // see if form element has inline err msg attribute
+ validationErrorMsg = true;
- var cacheSuffix = '?__='+( new Date().getTime() ),
- appendToElement =
document.getElementsByTagName('head')[0] ||
document.getElementsByTagName('body')[0];
+ if (!validationRules) {
+ result.shouldChangeDisplay = conf.addValidClassOnAll;
+ return result;
+ }
- $.each(moduleList, function(i, modName) {
- modName = $.trim(modName);
- if( modName.length == 0 ) {
- moduleLoadedCallback();
- }
- else {
- var scriptUrl = path + modName +
(modName.substr(-3) == '.js' ? '':'.js'),
- script = document.createElement('SCRIPT');
+ $.split(validationRules, function (rule) {
+ if (rule.indexOf('validate_') !== 0) {
+ rule = 'validate_' + rule;
+ }
- if( scriptUrl in $.formUtils.loadedModules ) {
- // already loaded
- moduleLoadedCallback();
- }
- else {
+ var validator = $.formUtils.validators[rule];
- // Remember that this script is loaded
- $.formUtils.loadedModules[scriptUrl] = 1;
- hasLoadedAnyModule = true;
+ if (validator && typeof validator.validatorFunction === 'function') {
- // Load the script
- script.type = 'text/javascript';
- script.onload = moduleLoadedCallback;
- script.src = scriptUrl + (
scriptUrl.substr(-7) == '.dev.js' ? cacheSuffix:'' );
- script.onreadystatechange = function() {
- // IE 7 fix
- if( this.readyState == 'complete' ||
this.readyState == 'loaded' ) {
- moduleLoadedCallback();
- // Handle memory leak in IE
- this.onload = null;
- this.onreadystatechange = null;
- }
- };
- appendToElement.appendChild( script );
- }
- }
- });
- };
+ // special change of element for checkbox_group rule
+ if (rule === 'validate_checkbox_group') {
+ // set element to first in group, so error msg attr doesn't need
to be set on all elements in group
+ $elem = $form.find('[name="' + $elem.attr('name') + '"]:eq(0)');
+ }
- if( path ) {
- loadModuleScripts(modules, path);
- } else {
- var findScriptPathAndLoadModules = function() {
- var foundPath = false;
- $('script[src*="form-validator"]').each(function() {
- foundPath = this.src.substr(0,
this.src.lastIndexOf('/')) + '/';
- if( foundPath == '/' )
- foundPath = '';
- return false;
- });
+ var isValid = null;
+ if (eventContext !== 'keyup' || validator.validateOnKeyUp) {
+ isValid = validator.validatorFunction(value, $elem, conf,
language, $form);
+ }
- if( foundPath !== false) {
- loadModuleScripts(modules, foundPath);
- return true;
- }
- return false;
- };
-
- if( !findScriptPathAndLoadModules() ) {
- $(findScriptPathAndLoadModules);
+ if (!isValid) {
+ validationErrorMsg = null;
+ if (isValid !== null) {
+ validationErrorMsg = $elem.attr(conf.validationErrorMsgAttribute
+ '-' + rule.replace('validate_', ''));
+ if (!validationErrorMsg) {
+ validationErrorMsg =
$elem.attr(conf.validationErrorMsgAttribute);
+ if (!validationErrorMsg) {
+ if (typeof validator.errorMessageKey !== 'function') {
+ validationErrorMsg = language[validator.errorMessageKey];
+ }
+ else {
+ validationErrorMsg =
language[validator.errorMessageKey(conf)];
+ }
+ if (!validationErrorMsg) {
+ validationErrorMsg = validator.errorMessage;
+ }
}
+ }
}
- },
+ return false; // break iteration
+ }
- /**
- * Validate the value of given element according to the validation rules
- * found in the attribute data-validation. Will return null if no
validation
- * should take place, returns true if valid or error message if not
valid
- *
- * @param {jQuery} $elem
- * @param {Object} language ($.formUtils.LANG)
- * @param {Object} conf
- * @param {jQuery} $form
- * @param {String} [eventContext]
- * @return {String|Boolean}
- */
- validateInput : function($elem, language, conf, $form, eventContext) {
+ } else {
+ throw new Error('Using undefined validator "' + rule + '"');
+ }
- if( $elem.attr('disabled') )
- return null; // returning null will prevent that the valid
class gets applied to the element
+ }, ' ');
- $elem.trigger('beforeValidation');
+ if (typeof validationErrorMsg === 'string') {
+ $elem.trigger('validation', false);
+ result.errorMsg = validationErrorMsg;
+ result.isValid = false;
+ result.shouldChangeDisplay = true;
+ } else if (validationErrorMsg === null) {
+ result.shouldChangeDisplay = conf.addValidClassOnAll;
+ } else {
+ $elem.trigger('validation', true);
+ result.shouldChangeDisplay = true;
+ }
- var value = $elem.val() || '',
- optional = $elem.valAttr('optional'),
+ // Run element validation callback
+ if (typeof conf.onElementValidate === 'function' && validationErrorMsg
!== null) {
+ conf.onElementValidate(result.isValid, $elem, $form,
validationErrorMsg);
+ }
- // test if a checkbox forces this element to be validated
- validationDependsOnCheckedInput = false,
- validationDependentInputIsChecked = false,
- validateIfCheckedElement = false,
+ return result;
+ },
- // get value of this element's attribute "... if-checked"
- validateIfCheckedElementName = $elem.valAttr("if-checked");
+ /**
+ * Is it a correct date according to given dateFormat. Will return false
if not, otherwise
+ * an array 0=>year 1=>month 2=>day
+ *
+ * @param {String} val
+ * @param {String} dateFormat
+ * @return {Array}|{Boolean}
+ */
+ parseDate: function (val, dateFormat) {
+ var divider = dateFormat.replace(/[a-zA-Z]/gi, '').substring(0, 1),
+ regexp = '^',
+ formatParts = dateFormat.split(divider || null),
+ matches, day, month, year;
- // make sure we can proceed
- if (validateIfCheckedElementName != null) {
+ $.each(formatParts, function (i, part) {
+ regexp += (i > 0 ? '\\' + divider : '') + '(\\d{' + part.length + '})';
+ });
- // Set the boolean telling us that the validation depends
- // on another input being checked
- validationDependsOnCheckedInput = true;
+ regexp += '$';
- // select the checkbox type element in this form
- validateIfCheckedElement = $form.find('input[name="' +
validateIfCheckedElementName + '"]');
+ matches = val.match(new RegExp(regexp));
+ if (matches === null) {
+ return false;
+ }
- // test if it's property "checked" is checked
- if ( validateIfCheckedElement.prop('checked') ) {
- // set value for validation checkpoint
- validationDependentInputIsChecked = true;
- }
- }
+ var findDateUnit = function (unit, formatParts, matches) {
+ for (var i = 0; i < formatParts.length; i++) {
+ if (formatParts[i].substring(0, 1) === unit) {
+ return $.formUtils.parseDateInt(matches[i + 1]);
+ }
+ }
+ return -1;
+ };
- // validation checkpoint
- // if empty AND optional attribute is present
- // OR depending on a checkbox being checked AND checkbox is
checked, return true
- if ((!value && optional === 'true') ||
(validationDependsOnCheckedInput && !validationDependentInputIsChecked)) {
- return conf.addValidClassOnAll ? true:null;
- }
+ month = findDateUnit('m', formatParts, matches);
+ day = findDateUnit('d', formatParts, matches);
+ year = findDateUnit('y', formatParts, matches);
- var validationRules = $elem.attr(conf.validationRuleAttribute),
+ if ((month === 2 && day > 28 && (year % 4 !== 0 || year % 100 === 0 &&
year % 400 !== 0)) ||
+ (month === 2 && day > 29 && (year % 4 === 0 || year % 100 !== 0 && year
% 400 === 0)) ||
+ month > 12 || month === 0) {
+ return false;
+ }
+ if ((this.isShortMonth(month) && day > 30) || (!this.isShortMonth(month)
&& day > 31) || day === 0) {
+ return false;
+ }
- // see if form element has inline err msg attribute
- validationErrorMsg = true;
+ return [year, month, day];
+ },
- if( !validationRules ) {
- return conf.addValidClassOnAll ? true:null;
- }
+ /**
+ * skum fix. är talet 05 eller lägre ger parseInt rätt int annars får man
0 när man kör parseInt?
+ *
+ * @param {String} val
+ * @param {Number}
+ */
+ parseDateInt: function (val) {
+ if (val.indexOf('0') === 0) {
+ val = val.replace('0', '');
+ }
+ return parseInt(val, 10);
+ },
- $.split(validationRules, function(rule) {
- if( rule.indexOf('validate_') !== 0 ) {
- rule = 'validate_' + rule;
- }
+ /**
+ * Has month only 30 days?
+ *
+ * @param {Number} m
+ * @return {Boolean}
+ */
+ isShortMonth: function (m) {
+ return (m % 2 === 0 && m < 7) || (m % 2 !== 0 && m > 7);
+ },
- var validator = $.formUtils.validators[rule];
+ /**
+ * Restrict input length
+ *
+ * @param {jQuery} $inputElement Jquery Html object
+ * @param {jQuery} $maxLengthElement jQuery Html Object
+ * @return void
+ */
+ lengthRestriction: function ($inputElement, $maxLengthElement) {
+ // read maxChars from counter display initial text value
+ var maxChars = parseInt($maxLengthElement.text(), 10),
+ charsLeft = 0,
- if( validator && typeof validator['validatorFunction'] ==
'function' ) {
-
- // special change of element for checkbox_group rule
- if ( rule == 'validate_checkbox_group' ) {
- // set element to first in group, so error msg attr
doesn't need to be set on all elements in group
- $elem = $("[name='"+$elem.attr('name')+"']:eq(0)");
- }
-
- var isValid = null;
- if( eventContext != 'keyup' || validator.validateOnKeyUp )
{
- isValid = validator.validatorFunction(value, $elem,
conf, language, $form);
- }
+ // internal function does the counting and sets display value
+ countCharacters = function () {
+ var numChars = $inputElement.val().length;
+ if (numChars > maxChars) {
+ // get current scroll bar position
+ var currScrollTopPos = $inputElement.scrollTop();
+ // trim value to max length
+ $inputElement.val($inputElement.val().substring(0, maxChars));
+ $inputElement.scrollTop(currScrollTopPos);
+ }
+ charsLeft = maxChars - numChars;
+ if (charsLeft < 0) {
+ charsLeft = 0;
+ }
- if(!isValid) {
- validationErrorMsg = null;
- if( isValid !== null ) {
- validationErrorMsg =
$elem.attr(conf.validationErrorMsgAttribute+'-'+rule.replace('validate_', ''));
- if( !validationErrorMsg ) {
- validationErrorMsg =
$elem.attr(conf.validationErrorMsgAttribute);
- if( !validationErrorMsg ) {
- validationErrorMsg =
language[validator.errorMessageKey];
- if( !validationErrorMsg )
- validationErrorMsg =
validator.errorMessage;
- }
- }
- }
- return false; // breaks the iteration
- }
+ // set counter text
+ $maxLengthElement.text(charsLeft);
+ };
- } else {
- throw new Error('Using undefined validator "'+rule+'"');
- }
+ // bind events to this element
+ // setTimeout is needed, cut or paste fires before val is available
+ $($inputElement).bind('keydown keyup keypress focus blur',
countCharacters)
+ .bind('cut paste', function () {
+ setTimeout(countCharacters, 100);
+ });
- }, ' ');
+ // count chars on pageload, if there are prefilled input-values
+ $(document).bind('ready', countCharacters);
+ },
- var result;
+ /**
+ * Test numeric against allowed range
+ *
+ * @param $value int
+ * @param $rangeAllowed str; (1-2, min1, max2, 10)
+ * @return array
+ */
+ numericRangeCheck: function (value, rangeAllowed) {
+ // split by dash
+ var range = $.split(rangeAllowed),
+ // min or max
+ minmax = parseInt(rangeAllowed.substr(3), 10);
- if( typeof validationErrorMsg == 'string' ) {
- $elem.trigger('validation', false);
- result = validationErrorMsg;
- } else if( validationErrorMsg === null && !conf.addValidClassOnAll
) {
- result = null;
- } else {
- $elem.trigger('validation', true);
- result = true;
- }
+ if( range.length === 1 && rangeAllowed.indexOf('min') === -1 &&
rangeAllowed.indexOf('max') === -1 ) {
+ range = [rangeAllowed, rangeAllowed]; // only a number, checking
agains an exact number of characters
+ }
- // Run element validation callback
- if( typeof conf.onElementValidate == 'function' && result !== null
) {
- conf.onElementValidate((result === true), $elem, $form,
validationErrorMsg);
- }
+ // range ?
+ if (range.length === 2 && (value < parseInt(range[0], 10) || value >
parseInt(range[1], 10) )) {
+ return [ 'out', range[0], range[1] ];
+ } // value is out of range
+ else if (rangeAllowed.indexOf('min') === 0 && (value < minmax )) // min
+ {
+ return ['min', minmax];
+ } // value is below min
+ else if (rangeAllowed.indexOf('max') === 0 && (value > minmax )) // max
+ {
+ return ['max', minmax];
+ } // value is above max
+ // since no other returns executed, value is in allowed range
+ return [ 'ok' ];
+ },
- return result;
- },
- /**
- * Is it a correct date according to given dateFormat. Will return
false if not, otherwise
- * an array 0=>year 1=>month 2=>day
- *
- * @param {String} val
- * @param {String} dateFormat
- * @return {Array}|{Boolean}
- */
- parseDate : function(val, dateFormat) {
- var divider = dateFormat.replace(/[a-zA-Z]/gi, '').substring(0,1),
- regexp = '^',
- formatParts = dateFormat.split(divider || null),
- matches, day, month, year;
+ _numSuggestionElements: 0,
+ _selectedSuggestion: null,
+ _previousTypedVal: null,
- $.each(formatParts, function(i, part) {
- regexp += (i > 0 ? '\\'+divider:'') + '(\\d{'+part.length+'})';
- });
-
- regexp += '$';
-
- matches = val.match(new RegExp(regexp));
- if (matches === null) {
- return false;
- }
-
- var findDateUnit = function(unit, formatParts, matches) {
- for(var i=0; i < formatParts.length; i++) {
- if(formatParts[i].substring(0,1) === unit) {
- return $.formUtils.parseDateInt(matches[i+1]);
- }
- }
- return -1;
- };
-
- month = findDateUnit('m', formatParts, matches);
- day = findDateUnit('d', formatParts, matches);
- year = findDateUnit('y', formatParts, matches);
-
- if ((month === 2 && day > 28 && (year % 4 !== 0 || year % 100 ===
0 && year % 400 !== 0))
- || (month === 2 && day > 29 && (year % 4 === 0 || year % 100
!== 0 && year % 400 === 0))
- || month > 12 || month === 0) {
- return false;
- }
- if ((this.isShortMonth(month) && day > 30) ||
(!this.isShortMonth(month) && day > 31) || day === 0) {
- return false;
- }
-
- return [year, month, day];
+ /**
+ * Utility function that can be used to create plugins that gives
+ * suggestions when inputs is typed into
+ * @param {jQuery} $elem
+ * @param {Array} suggestions
+ * @param {Object} settings - Optional
+ * @return {jQuery}
+ */
+ suggest: function ($elem, suggestions, settings) {
+ var conf = {
+ css: {
+ maxHeight: '150px',
@@ Diff output truncated at 153600 characters. @@
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Fmsystem-commits] [14419] API: update form-validator from upstream,
Sigurd Nes <=