fmsystem-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Fmsystem-commits] [14432] validator: update from upstream


From: Sigurd Nes
Subject: [Fmsystem-commits] [14432] validator: update from upstream
Date: Fri, 20 Nov 2015 09:31:33 +0000

Revision: 14432
          http://svn.sv.gnu.org/viewvc/?view=rev&root=fmsystem&revision=14432
Author:   sigurdne
Date:     2015-11-20 09:31:32 +0000 (Fri, 20 Nov 2015)
Log Message:
-----------
validator: update from upstream

Modified Paths:
--------------
    branches/dev-syncromind/phpgwapi/inc/class.jquery.inc.php
    branches/dev-syncromind/phpgwapi/js/jquery/validator/date.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/file.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/html5.js
    
branches/dev-syncromind/phpgwapi/js/jquery/validator/jquery.form-validator.min.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/location.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/security.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/sweden.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/uk.js

Added Paths:
-----------
    branches/dev-syncromind/phpgwapi/js/jquery/validator/README.md
    branches/dev-syncromind/phpgwapi/js/jquery/validator/brazil.js
    
branches/dev-syncromind/phpgwapi/js/jquery/validator/jquery.form-validator.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/jsconf.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/lang/
    branches/dev-syncromind/phpgwapi/js/jquery/validator/lang/cz.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/lang/de.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/lang/es.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/lang/fr.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/lang/it.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/lang/no.dev.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/lang/no.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/lang/pl.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/lang/pt.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/lang/ro.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/lang/ru.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/lang/sv.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/sanitize.js
    branches/dev-syncromind/phpgwapi/js/jquery/validator/theme-default.css
    branches/dev-syncromind/phpgwapi/js/jquery/validator/toggleDisabled.js

Modified: branches/dev-syncromind/phpgwapi/inc/class.jquery.inc.php
===================================================================
--- branches/dev-syncromind/phpgwapi/inc/class.jquery.inc.php   2015-11-20 
08:20:45 UTC (rev 14431)
+++ branches/dev-syncromind/phpgwapi/inc/class.jquery.inc.php   2015-11-20 
09:31:32 UTC (rev 14432)
@@ -83,8 +83,9 @@
                                        (
                                        "js/jquery-2.1.1{$_type}",
                                        
"validator/jquery.form-validator{$_type}"
+//                                     "validator/jquery.form-validator"
                                );
-                               
$GLOBALS['phpgw']->css->add_external_file("phpgwapi/js/jquery/validator/css/main.css");
+                               
$GLOBALS['phpgw']->css->add_external_file("phpgwapi/js/jquery/validator/theme-default.css");
                                break;
                        
                        case 'menu':
@@ -203,8 +204,107 @@
                        $errorMessagePosition = "'top'";
                }
 
+               $translation = '';
+               if(!$times_loaded)//first time only
+               {
+                       //TODO: use translations from the package
+                       
if($GLOBALS['phpgw_info']['user']['preferences']['common']['lang'] == 'no')
+                       {
+                               $translation = <<<JS
+
+                               var validateLanguage = {
+                                       errorTitle: 'innsending av skjema 
mislyktes!',
+                                       requiredField: 'Dette er et 
obligatorisk felt',
+                                       requiredFields: 'Du har ikke svart på 
alle obligatoriske felter',
+                                       badTime: 'Du har ikke angitt en gyldig 
tid',
+                                       badEmail: 'Du har ikke angitt en gyldig 
e-postadresse',
+                                       badTelephone: 'Du har ikke angitt et 
gyldig telefonnummer',
+                                       badSecurityAnswer: 'Du har ikke gitt 
korrekt svar på sikkerhetsspørsmålet',
+                                       badDate: 'Du har ikke gitt en gyldig 
dato',
+                                       lengthBadStart: 'Inputverdien må være 
mellom ',
+                                       lengthBadEnd: ' karakterer',
+                                       lengthTooLongStart: 'Inputverdien er 
lengre enn ',
+                                       lengthTooShortStart: 'Inputverdien er 
kortere enn ',
+                                       notConfirmed: 'Inputverdiene kunne ikke 
bekreftes',
+                                       badDomain: 'Feilaktig domene verdi',
+                                       badUrl: 'Inputverdiene er ikke et 
riktig nettadresse',
+                                       badCustomVal: 'Inputverdien er feil',
+                                       andSpaces: ' og mellomrom ',
+                                       badInt: 'Du har ikke angitt et tall',
+                                       badSecurityNumber: 'Personnummeret 
validerer ikke',
+                                       badUKVatAnswer: 'Feil britisk 
moms-kode',
+                                       badStrength: 'Passordet er ikke sterk 
nok',
+                                       badNumberOfSelectedOptionsStart: 'Du må 
velge minst ',
+                                       badNumberOfSelectedOptionsEnd: ' svar',
+                                       badAlphaNumeric: 'Inputverdiene kan 
bare inneholde alfanumeriske tegn ',
+                                       badAlphaNumericExtra: ' og ',
+                                       wrongFileSize: 'Filen du prøver å laste 
opp er for stor (max %s)',
+                                       wrongFileType: 'Bare filer av type %s 
er mulig',
+                                       groupCheckedRangeStart: 'Vennligst velg 
mellom ',
+                                       groupCheckedTooFewStart: 'Vennligst 
velg minst ',
+                                       groupCheckedTooManyStart: 'Vennligst 
velg maksimum ',
+                                       groupCheckedEnd: ' alternativ',
+                                       badCreditCard: 'Kredittkortnummeret er 
ikke gyldig',
+                                       badCVV: 'CVV-nummer ikke var gyldig',
+                                       wrongFileDim : 'Feil bildedimensjoner,',
+                                       imageTooTall : 'bildet kan ikke være 
høyere enn',
+                                       imageTooWide : 'bildet kan ikke være 
bredere enn',
+                                       imageTooSmall : 'bildet var for liten',
+                                       min : 'minimum',
+                                       max : 'maximum',
+                                       imageRatioNotAccepted : 'Bildeforholdet 
kan ikke aksepteres',
+                                       badBrazilTelephoneAnswer: 
'Telefonnummeret er ugyldig',
+                                       badBrazilCEPAnswer: 'CEP er ugyldig',
+                                       badBrazilCPFAnswer: 'CPF er ugyldig'
+                                  };
+JS;
+
+                       }
+                       else
+                       {
+
+                               $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
-                       $(document).ready(function () 
+
+                       {$translation}
+
+                       $(document).ready(function ()
                        {
                                $.validate({
                                        lang: 
'{$GLOBALS['phpgw_info']['user']['preferences']['common']['lang']}', // 
(supported languages are fr, de, se, sv, en, pt, no)

Added: branches/dev-syncromind/phpgwapi/js/jquery/validator/README.md
===================================================================
--- branches/dev-syncromind/phpgwapi/js/jquery/validator/README.md              
                (rev 0)
+++ branches/dev-syncromind/phpgwapi/js/jquery/validator/README.md      
2015-11-20 09:31:32 UTC (rev 14432)
@@ -0,0 +1,386 @@
+# jQuery Form Validator
+
+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 available at http://formvalidator.net/**
+
+*Usage example*
+
+```html
+<form action="" method="POST">
+  <p>
+    Name (4 characters minimum):
+    <input name="user" data-validation="length" data-validation-length="min4" 
/>
+  </p>
+  <p>
+    Birthdate (yyyy-mm-dd):
+    <input name="birth" data-validation="birthdate" />
+  </p>
+  <p>
+    Website:
+    <input name="website" data-validation="url" />
+  </p>
+  <p>
+    <input type="submit" />
+  </p>
+</form>
+<script src="js/jquery.min.js"></script>
+<script src="js/form-validator/jquery.form-validator.min.js"></script>
+<script>
+/* important to locate this script AFTER the closing form element, so form 
object is loaded in DOM before setup is called */
+    $.validate({
+        modules : 'date, security'
+    });
+</script>
+```
+
+### 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 declaration and you can use the following native features:
+
+**Attributes**: require, pattern, maxlength, min, max, placeholder
+
+**Input types**: url, date, time, email, number
+
+**Elements**: Use the element `datalist` to create input suggestions
+
+
+### Default validators and features (no module needed)
+ * **url**
+ * **email**
+ * **domain** — *domain.com*
+ * **number** — *float/negative/positive/range/step*
+ * **date** — *yyyy-mm-dd (format can be customized, more information below)*
+ * **alphanumeric** — *with support for defining additional characters*
+ * **length** — *min/max/range*
+ * **required** — *no validation except that a value has to be given*
+ * **custom** — *Validate value against regexp*
+ * **checkboxgroup** — *ensure at least 1 checkbox in group has been selected*
+ * Show help information automatically when input is focused
+ * Validate given values immediately when input looses focus.
+ * Make validation optional by adding attribute 
data-validation-optional="true" to the element. This means
+ that the validation defined in data-validation only will take place in case a 
value is given.
+ * Make validation dependent on another input of type checkbox being checked 
by adding attribute
+ data-validation-if-checked="name of checkbox input"
+ * Create input suggestions with ease, no jquery-ui needed
+ * to apply multiple validators to an input element, separate the validator 
names using a space (ex: required email)
+
+Read the documentation for the default features at 
[http://formvalidator.net/#default-validators](http://formvalidator.net/#default-validators)
+
+### Module: security
+ * **spamcheck**
+ * **confirmation**
+ * **creditcard**
+ * **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)
+
+### Module: date
+ * **time** — *hh:mm*
+ * **birthdate** — *yyyy-mm-dd, not allowing dates in the future or dates 
that's older than 122 years (format can be customized, more information below)*
+
+Read the documentation for the date module at 
[http://formvalidator.net/#date-validators](http://formvalidator.net/#date-validators)
+
+### Module: location
+ * **country**
+ * **federatestate**
+ * **longlat**
+ * Suggest countries (english only)
+ * Suggest states in the US
+
+Read the documentation for the location module at 
[http://formvalidator.net/#location-validators](http://formvalidator.net/#location-validators)
+
+### Module: file
+ * **mime**
+ * **extension**
+ * **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)
+
+### Module: sweden
+ * **swemob** — *validate that the value is a swedish mobile telephone number*
+ * **swesec** — *validate swedish social security number*
+ * **county** - *validate that the value is an existing county in Sweden*
+ * **municipality** - *validate that the value is an existing municipality in 
Sweden*
+ * Suggest county
+ * Suggest municipality
+
+Read the documentation for the Swedish module at 
[http://formvalidator.net/#sweden-validators](http://formvalidator.net/#sweden-validators)
+
+### Module: uk
+ * **ukvatnumber**
+
+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.
+
+```html
+<form action="" method="POST">
+    <p>
+        <input type="text" data-validation="even" />
+    </p>
+    ...
+</form>
+<script src="js/jquery.min.js"></script>
+<script src="js/form-validator/jquery.form-validator.min.js"></script>
+<script>
+
+    // Add validator
+    $.formUtils.addValidator({
+        name : 'even',
+        validatorFunction : function(value, $el, config, language, $form) {
+            return parseInt(value, 10) % 2 === 0;
+        },
+        errorMessage : 'You have to answer an even number',
+        errorMessageKey: 'badEvenNumber'
+    });
+
+    // Initiate form validation
+    $.validate();
+
+</script>
+```
+
+### Required properties passed into $.formUtils.addValidator
+
+*name* - The name of the validator, which is used in the validation attribute 
of the input element.
+
+*validatorFunction* - Callback function that validates the input. Should 
return a boolean telling if the value is considered valid or not.
+
+*errorMessageKey* - Name of language property that is used in case the value 
of the input is invalid.
+
+*errorMessage* - An alternative error message that is used if errorMessageKey 
is left with an empty value or isn't defined
+in the language object. Note that you also can use [inline error 
messages](http://formvalidator.net/#localization) in your form.
+
+
+The validation function takes these five arguments:
+- value — the value of the input thats being validated
+- $el — jQuery object referring to the input element being validated
+- config — Object containing the configuration of this form validation
+- language — Object with error dialogs
+- $form — jQuery object referring to the form element being validated
+
+## Creating a custom module
+
+A "module" is basically a javascript file containing one or more calls to 
[$.formUtils.addValidator()](#writing-a-custom-validator). The module file
+should either have the file extension *.js* (as an ordinary javascript file) 
or *.dev.js*.
+
+Using the file extension **.dev.js** will tell *$.formUtils.loadModules* to 
always append a timestamp to the end of the
+URL, so that the browser never caches the file. You should of course never use 
*.dev.js* on a production website.
+
+### Loading your module ###
+
+```html
+<html>
+<head>
+    <script src="js/form-validator/jquery.form-validator.min.js"></script>
+    <script>
+        $.formUtils.loadModules('mymodule.dev', 'js/validation-modules/');
+    </script>
+</head>
+</html>
+...
+```
+
+The first argument of $.formUtils.loadModules is a comma separated string with 
names of module files, without
+file extension (add .dev if the file name is for example mymodule.dev.js, this 
will insure that the browser never
+caches the javascript).
+
+The second argument is the path where the module files is located. This 
argument is optional, if not given
+the module files has to be located in the same directory as the core modules 
shipped together with this jquery plugin
+(js/form-validator/)
+
+## Show help information
+It is possible to display help information for each input. The information 
will fade in when input is focused and fade out when input looses focus.
+
+```html
+<form action="" id="my_form">
+       <p>
+         <strong>Why not:</strong>
+         <textarea name="why" data-validation-help="Please give us some more 
information" data-validation="required"></textarea>
+       </p>
+       ...
+```
+
+## Fully customizable
+
+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 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)
+
+## 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
+rule assigned to the input element. If a validation fails, error messages are 
assigned and displayed
+as configured. If **validateOnBlur** is set to true, jQ finds all form input 
elements with the
+data-validation attribute and binds their onBlur event to call the function 
**validateInputOnBlur**.
+it calls jQ func **$.formUtils.validateInput** to validate the single input 
when blurred.
+
+
+## Changelog
+
+#### 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.
+* Use a template for error messages when having errorMessagePosition set to top
+* Added validation of credit card number and CVV to the security module
+* Event onElementValidate added
+* 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
+* Deprecated function $.validationSetup is now removed, use $.validate() 
instead
+* You can now return an array with errors using the event `onValidate`
+* You can now declare an element where all error messages should be placed 
(config.errorMessagePosition)
+
+#### 2.1.36
+* Now possible to use the native reset() function to clear error messages and 
error styling of the input elements
+
+#### 2.1.34
+* General improvements and bug fixes
+* Added events "beforeValidation" and "validation" (see 
http://formvalidator.net/#configuration_callbacks for more info)
+
+#### 2.1.27
+ * E-mail validation support .eu top domain
+ * Improvements in server validation
+ * Now possible to re-initiate the validation. This makes it possible to 
dynamically change the form and then call $.validate() again to refresh the 
validation (issue #59)
+ * Number validation now supports range
+
+#### 2.1.15
+ * E-mail addresses can now contain + symbol
+ * Correction of the US states in validation "federatestate"
+ * Fixed bug in server validation
+
+#### 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.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.06
+ * Modules can now be loaded from remote websites
+
+#### 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
+
+#### 2.1
+ * Code refactoring and some functions renamed
+ * Validator "checkbox_group" added
+
+#### 2.0.7
+ * Now possible to validate file size, extension and mime type (using the file 
module)
+
+#### 2.0
+ * [min|max]_length is removed (now merged with length validation).
+ * The number, int and float validation is merged together, all three variants 
is now validated by the number validation.
+ * Phone validation is moved to "sweden" module and renamed to swephone.
+ * The attribute to be used when defining the regular expression for custom 
validations is now moved to its own attribute (data-validation-regexp)
+ * Length validation now looks at attribute data-validation-length (eg. min5, 
max200, 3-12).
+ * The validation rule no longer needs to be prefixed with "validate_" (it's 
still possible to use the prefix but it's considered deprecated).
+ * Some validation functions is moved to modules (see the function reference 
over at http://formvalidator.net).
+ * Added function $.validationSetup() to reduce the amount of code that has to 
be written when initiating the form validation.
+
+
+## Credits
+
+#### Maintainer
+
+[Victor Jonsson](https://github.com/victorjonsson)
+
+#### Contributors
+<a href="http://stevewasiura.waztech.com"; target="_blank">Steve Wasiura</a><br 
/>
+<a href="http://lagden.github.com"; target="_blank">Thiago Lagden</a><br />
+<a href="https://github.com/robamaton"; target="_blank">Joel Sutherland</a><br 
/>
+<a href="https://github.com/mattclements"; target="_blank">Matt Clements</a><br 
/>
+<a href="http://www.joshtoft.com/"; target="_blank">Josh Toft</a><br/>
+<a href="https://github.com/dfcplc"; target="_blank">@dfcplc</a><br />
+<a href="https://github.com/coffein"; target="_blank">Andree Wendel</a><br />
+<a href="http://www.huotmedia.com"; target="_blank">Nicholas Huot</a><br />
+<a href="https://github.com/Repkit"; target="_blank">@repkit</a><br />
+<a href="https://github.com/aL3xa"; target="_blank">Alexandar Blagotic</a><br />
+<a href="http://thekindof.me/"; target="_blank">Yasith Fernando</a><br />
+<a href="https://github.com/S0L4R1S"; target="_blank">@S0L4R1S</a><br />
+<a href="http://lisangan.com/";>Erick Lisangan</a><br />
+<a href="https://github.com/kirbs-";>@kirbs</a>
+<a href="https://github.com/hslee87";>hslee87</a>
+
+#### Additional credits
+
+<a href="http://projects.scottsplayground.com/iri/"; target="_blank">Scott 
Gonzales</a> (URL regexp)<br />
+<a href="http://www.mypocket-technologies.com"; target="_blank">Darren 
Mason</a> (Password strength meter)<br />
+<a href="http://stevewasiura.waztech.com"; target="_blank">Steve Wasiura</a> 
(Checkbox group)

Added: branches/dev-syncromind/phpgwapi/js/jquery/validator/brazil.js
===================================================================
--- branches/dev-syncromind/phpgwapi/js/jquery/validator/brazil.js              
                (rev 0)
+++ branches/dev-syncromind/phpgwapi/js/jquery/validator/brazil.js      
2015-11-20 09:31:32 UTC (rev 14432)
@@ -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/jquery/validator/date.js
===================================================================
--- branches/dev-syncromind/phpgwapi/js/jquery/validator/date.js        
2015-11-20 08:20:45 UTC (rev 14431)
+++ branches/dev-syncromind/phpgwapi/js/jquery/validator/date.js        
2015-11-20 09:31:32 UTC (rev 14432)
@@ -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);
\ No newline at end of file
+/**
+ *  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/jquery/validator/file.js
===================================================================
--- branches/dev-syncromind/phpgwapi/js/jquery/validator/file.js        
2015-11-20 08:20:45 UTC (rev 14431)
+++ branches/dev-syncromind/phpgwapi/js/jquery/validator/file.js        
2015-11-20 09:31:32 UTC (rev 14432)
@@ -1 +1,8 @@
-(function($,window){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},_log=function(msg){if(window.console&&window.console.log){window.console.log(msg)}};$.formUtils.addValidator({name:"mime",validatorFunction:function(str,$input){var
 files=$input.get(0).files||[];if(SUPPORTS_FILE_READER){var 
valid=true,mime="",allowedTypes=_getTypes($input);$.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")}return valid}else{_log("FileReader not 
supported by browser, will check file extension");return 
$.formUtils.validators.validate_extension.validatorFunction(str,$input)}},errorMessage:"The
 file you are trying to upload is of wrong 
type",errorMessageKey:"wrongFileType"});$.formUtils.addValidator({name:"extension",validatorFunction:function(value,$input){var
 
valid=true,types=_getTypes($input);$.each($input.get(0).files||[],function(i,file){var
 
val=file.value,ext=val.substr(val.lastIndexOf(".")+1);if($.inArray(ext.toLowerCase(),types)==-1){valid=false;return
 false}});return valid},errorMessage:"The file you are trying to upload is of 
wrong 
type",errorMessageKey:"wrongFileType"});$.formUtils.addValidator({name:"size",validatorFunction:function(val,$input){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});return valid},errorMessage:"The file you are trying to upload is too 
large",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);
\ No newline at end of file
+/**
+ *  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

Modified: branches/dev-syncromind/phpgwapi/js/jquery/validator/html5.js
===================================================================
--- branches/dev-syncromind/phpgwapi/js/jquery/validator/html5.js       
2015-11-20 08:20:45 UTC (rev 14431)
+++ branches/dev-syncromind/phpgwapi/js/jquery/validator/html5.js       
2015-11-20 09:31:32 UTC (rev 14432)
@@ -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);
\ No newline at end of file
+/**
+ *  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

Added: 
branches/dev-syncromind/phpgwapi/js/jquery/validator/jquery.form-validator.js
===================================================================
--- 
branches/dev-syncromind/phpgwapi/js/jquery/validator/jquery.form-validator.js   
                            (rev 0)
+++ 
branches/dev-syncromind/phpgwapi/js/jquery/validator/jquery.form-validator.js   
    2015-11-20 09:31:32 UTC (rev 14432)
@@ -0,0 +1,1831 @@
+/**
+ * jQuery Form Validator
+ * ------------------------------------------
+ * Created by Victor Jonsson <http://www.victorjonsson.se>
+ *
+ * @website http://formvalidator.net/
+ * @license MIT
+ * @version 2.2.83
+ */
+(function ($) {
+
+  'use strict';
+
+  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');
+
+      _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);
+
+        _setInlineErrorMessage($this, '', conf, conf.errorMessagePosition);
+
+        $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 = {};
+
+      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');
+
+        if ($mess.length === 0) {
+          $mess = 
$('<span></span>').addClass('help-block').addClass(conf.errorMessageClass);
+          $mess.appendTo($parent);
+        }
+
+        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 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;
+  };
+
+  /**
+   * 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';
+    }
+
+    // Remove previously added event listeners
+    this.find('.has-help-txt')
+      .valAttr('has-keyup-event', false)
+      .removeClass('has-help-txt');
+
+    // 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);
+
+      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();
+
+              $elem.after($help);
+            }
+            $help.fadeIn();
+          })
+          .unbind('blur.help')
+          .bind('blur.help', function () {
+            $(this)
+              .parent()
+              .find('.' + className)
+              .fadeOut('slow');
+          });
+      }
+    });
+
+    return this;
+  };
+
+  /**
+   * @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 || 
{};
+
+      $elem.one('validation', function(evt, isValid) {
+        if ( typeof cb === 'function' ) {
+          cb(isValid, this, evt);
+        }
+      });
+
+      $elem.validateInputOnBlur(
+          language,
+          $.extend({}, formDefaultConfig, conf || {}),
+          true
+        );
+    });
+  };
+
+  /**
+   * 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;
+  };
+
+  /**
+   * 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) {
+
+    $.formUtils.eventType = eventType;
+
+    if ( this.willPostponeValidation() ) {
+      // This validation has to be postponed
+      var _self = this,
+          postponeTime = this.valAttr('postpone') || 200;
+
+      window.postponedValidation = function () {
+        _self.validateInputOnBlur(language, conf, attachKeyupEvent, eventType);
+        window.postponedValidation = false;
+      };
+
+      setTimeout(function () {
+        if (window.postponedValidation) {
+          window.postponedValidation();
+        }
+      }, postponeTime);
+
+      return this;
+    }
+
+    language = $.extend({}, $.formUtils.LANG, language || {});
+    _removeErrorStyle(this, conf);
+    var $elem = this,
+        $form = $elem.closest('form'),
+        result = $.formUtils.validateInput(
+                    $elem,
+                    language,
+                    conf,
+                    $form,
+                    eventType
+                  );
+
+    if ( result.isValid ) {
+      if( result.shouldChangeDisplay ) {
+          $elem.addClass('valid');
+          _getInputParentContainer($elem)
+            .addClass(conf.inputParentClassOnSuccess);
+      }
+    }
+    else if (!result.isValid) {
+
+      _applyErrorStyle($elem, conf);
+      _setInlineErrorMessage($elem, result.errorMsg, conf, 
conf.errorMessagePosition);
+
+      if (attachKeyupEvent) {
+        $elem
+          .unbind('keyup.validation')
+          .bind('keyup.validation', function () {
+            $(this).validateInputOnBlur(language, conf, false, 'keyup');
+          });
+      }
+    }
+
+    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);
+    }
+  };
+
+  /**
+   * 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 ($.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 = [],
+
+        /** Input elements which value was not valid */
+        errorInputs = [],
+
+        /** 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);
+    }
+
+    // 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 (!ignoreInput(elementName, elementType) && (!isCheckboxOrRadioBtn || 
$.inArray(elementName, checkedInputs) < 0)) {
+
+        if (isCheckboxOrRadioBtn) {
+          checkedInputs.push(elementName);
+        }
+
+        var result = $.formUtils.validateInput(
+                              $elem,
+                              language,
+                              conf,
+                              $form,
+                              'submit'
+                            );
+
+        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);
+      }
+    }
+
+    // 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);
+          });
+        }
+
+        if (conf.scrollToTopOnError) {
+          $window.scrollTop($form.offset().top - 20);
+        }
+      }
+
+      return false;
+    }
+
+    if (!displayError && $.formUtils.haltValidation) {
+      $.formUtils.errorDisplayPreventedWhenHalted = true;
+    }
+
+    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 (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]);
+      });
+    }
+  };
+
+  /**
+   * Object containing utility methods for this plugin
+   */
+  $.formUtils = {
+
+    /**
+     * 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: '#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
+      };
+    },
+
+    /**
+     * Available validators
+     */
+    validators: {},
+
+    /**
+     * Events triggered by form validator
+     */
+    _events: {load: [], valid: [], invalid: []},
+
+    /**
+     * Setting this property to true during validation will
+     * stop further validation from taking place and form will
+     * not be sent
+     */
+    haltValidation: false,
+
+    /**
+     * 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;
+    },
+
+    /**
+     * @var {Boolean}
+     */
+    isLoadingModules: false,
+
+    /**
+     * @var {Object}
+     */
+    loadedModules: {},
+
+    /**
+     * @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) {
+
+      if (fireEvent === undefined) {
+        fireEvent = true;
+      }
+
+      if ($.formUtils.isLoadingModules) {
+        setTimeout(function () {
+          $.formUtils.loadModules(modules, path, fireEvent);
+        });
+        return;
+      }
+
+      var hasLoadedAnyModule = false,
+        loadModuleScripts = function (modules, path) {
+
+          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 (numModules > 0) {
+            $.formUtils.isLoadingModules = true;
+          }
+
+          var cacheSuffix = '?_=' + ( new Date().getTime() ),
+            appendToElement = document.getElementsByTagName('head')[0] || 
document.getElementsByTagName('body')[0];
+
+          $.each(moduleList, function (i, modName) {
+            modName = $.trim(modName);
+            if (modName.length === 0) {
+              moduleLoadedCallback();
+            }
+            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 (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;
+          });
+
+          if (foundPath !== false) {
+            loadModuleScripts(modules, foundPath);
+            return true;
+          }
+          return false;
+        };
+
+        if (!findScriptPathAndLoadModules()) {
+          $(findScriptPathAndLoadModules);
+        }
+      }
+    },
+
+    /**
+     * 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}
+     */
+    validateInput: function ($elem, language, conf, $form, eventContext) {
+
+      $elem.trigger('beforeValidation');
+      conf = conf || $.formUtils.defaultConfig();
+      language = language || $.formUtils.LANG;
+
+      var value = $elem.val() || '',
+          result = {isValid: true, shouldChangeDisplay:true, errorMsg:''},
+          optional = $elem.valAttr('optional'),
+
+          // test if a checkbox forces this element to be validated
+          validationDependsOnCheckedInput = false,
+          validationDependentInputIsChecked = false,
+          validateIfCheckedElement = 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');
+
+
+      if ($elem.attr('disabled') || (!$elem.is(':visible') && 
!conf.validateHiddenInputs)) {
+        result.shouldChangeDisplay = false;
+        return result;
+      }
+
+      // make sure we can proceed
+      if (validateIfCheckedElementName != null) {
+
+        // Set the boolean telling us that the validation depends
+        // on another input being checked
+        validationDependsOnCheckedInput = true;
+
+        // select the checkbox type element in this form
+        validateIfCheckedElement = $form.find('input[name="' + 
validateIfCheckedElementName + '"]');
+
+        // 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;
+          }
+        }
+      }
+
+      // 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 validationRules = $elem.attr(conf.validationRuleAttribute),
+
+        // see if form element has inline err msg attribute
+        validationErrorMsg = true;
+
+      if (!validationRules) {
+        result.shouldChangeDisplay = conf.addValidClassOnAll;
+        return result;
+      }
+
+      $.split(validationRules, function (rule) {
+        if (rule.indexOf('validate_') !== 0) {
+          rule = 'validate_' + rule;
+        }
+
+        var validator = $.formUtils.validators[rule];
+
+        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 = $form.find('[name="' + $elem.attr('name') + '"]:eq(0)');
+          }
+
+          var isValid = null;
+          if (eventContext !== 'keyup' || validator.validateOnKeyUp) {
+            isValid = validator.validatorFunction(value, $elem, conf, 
language, $form);
+          }
+
+          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
+          }
+
+        } else {
+          throw new Error('Using undefined validator "' + rule + '"');
+        }
+
+      }, ' ');
+
+      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;
+      }
+
+      // Run element validation callback
+      if (typeof conf.onElementValidate === 'function' && validationErrorMsg 
!== null) {
+        conf.onElementValidate(result.isValid, $elem, $form, 
validationErrorMsg);
+      }
+
+      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;
+
+      $.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];
+    },
+
+    /**
+     * 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);
+    },
+
+    /**
+     * Has month only 30 days?
+     *
+     * @param {Number} m
+     * @return {Boolean}
+     */
+    isShortMonth: function (m) {
+      return (m % 2 === 0 && m < 7) || (m % 2 !== 0 && m > 7);
+    },
+
+    /**
+     * 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,
+
+      // 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;
+          }
+
+          // set counter text
+          $maxLengthElement.text(charsLeft);
+        };
+
+      // 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);
+    },
+
+    /**
+     * 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( range.length === 1 && rangeAllowed.indexOf('min') === -1 && 
rangeAllowed.indexOf('max') === -1 ) {
+        range = [rangeAllowed, rangeAllowed]; // only a number, checking 
agains an exact number of characters
+      }
+
+      // 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' ];
+    },
+
+
+    _numSuggestionElements: 0,
+    _selectedSuggestion: null,
+    _previousTypedVal: null,
+
+    /**
+     * 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',
+            background: '#FFF',
+            lineHeight: '150%',
+            textDecoration: 'underline',
+            overflowX: 'hidden',
+            overflowY: 'auto',
+            border: '#CCC solid 1px',
+            borderTop: 'none',
+            cursor: 'pointer'
+          },
+          activeSuggestionCSS: {
+            background: '#E9E9E9'
+          }
+        },
+        setSuggsetionPosition = function ($suggestionContainer, $input) {
+          var offset = $input.offset();
+          $suggestionContainer.css({
+            width: $input.outerWidth(),
+            left: offset.left + 'px',
+            top: (offset.top + $input.outerHeight()) + 'px'
+          });
+        };
+
+      if (settings) {
+        $.extend(conf, settings);
+      }
+
+      conf.css.position = 'absolute';
+      conf.css['z-index'] = 9999;
+      $elem.attr('autocomplete', 'off');
+
+      if (this._numSuggestionElements === 0) {
+        // Re-position suggestion container if window size changes
+        $window.bind('resize', function () {
+          $('.jquery-form-suggestions').each(function () {
+            var $container = $(this),
+              suggestID = $container.attr('data-suggest-container');
+            setSuggsetionPosition($container, $('.suggestions-' + 
suggestID).eq(0));
+          });
+        });
+      }
+
+      this._numSuggestionElements++;
+
+      var onSelectSuggestion = function ($el) {
+        var suggestionId = $el.valAttr('suggestion-nr');
+        $.formUtils._selectedSuggestion = null;
+        $.formUtils._previousTypedVal = null;
+        $('.jquery-form-suggestion-' + suggestionId).fadeOut('fast');
+      };
+
+      $elem
+        .data('suggestions', suggestions)
+        .valAttr('suggestion-nr', this._numSuggestionElements)
+        .unbind('focus.suggest')
+        .bind('focus.suggest', function () {
+          $(this).trigger('keyup');
+          $.formUtils._selectedSuggestion = null;
+        })
+        .unbind('keyup.suggest')
+        .bind('keyup.suggest', function () {
+          var $input = $(this),
+            foundSuggestions = [],
+            val = $.trim($input.val()).toLocaleLowerCase();
+
+          if (val === $.formUtils._previousTypedVal) {
+            return;
+          }
+          else {
+            $.formUtils._previousTypedVal = val;
+          }
+
+          var hasTypedSuggestion = false,
+            suggestionId = $input.valAttr('suggestion-nr'),
+            $suggestionContainer = $('.jquery-form-suggestion-' + 
suggestionId);
+
+          $suggestionContainer.scrollTop(0);
+
+          // Find the right suggestions
+          if (val !== '') {
+            var findPartial = val.length > 2;
+            $.each($input.data('suggestions'), function (i, suggestion) {
+              var lowerCaseVal = suggestion.toLocaleLowerCase();
+              if (lowerCaseVal === val) {
+                foundSuggestions.push('<strong>' + suggestion + '</strong>');
+                hasTypedSuggestion = true;
+                return false;
+              } else if (lowerCaseVal.indexOf(val) === 0 || (findPartial && 
lowerCaseVal.indexOf(val) > -1)) {
+                foundSuggestions.push(suggestion.replace(new RegExp(val, 
'gi'), '<strong>$&</strong>'));
+              }
+            });
+          }
+
+          // Hide suggestion container
+          if (hasTypedSuggestion || (foundSuggestions.length === 0 && 
$suggestionContainer.length > 0)) {
+            $suggestionContainer.hide();
+          }
+
+          // Create suggestion container if not already exists
+          else if (foundSuggestions.length > 0 && $suggestionContainer.length 
=== 0) {
+            $suggestionContainer = 
$('<div></div>').css(conf.css).appendTo('body');
+            $elem.addClass('suggestions-' + suggestionId);
+            $suggestionContainer
+              .attr('data-suggest-container', suggestionId)
+              .addClass('jquery-form-suggestions')
+              .addClass('jquery-form-suggestion-' + suggestionId);
+          }
+
+          // Show hidden container
+          else if (foundSuggestions.length > 0 && 
!$suggestionContainer.is(':visible')) {
+            $suggestionContainer.show();
+          }
+
+          // add suggestions
+          if (foundSuggestions.length > 0 && val.length !== 
foundSuggestions[0].length) {
+
+            // put container in place every time, just in case
+            setSuggsetionPosition($suggestionContainer, $input);
+
+            // Add suggestions HTML to container
+            $suggestionContainer.html('');
+            $.each(foundSuggestions, function (i, text) {
+              $('<div></div>')
+                .append(text)
+                .css({
+                  overflow: 'hidden',
+                  textOverflow: 'ellipsis',
+                  whiteSpace: 'nowrap',
+                  padding: '5px'
+                })
+                .addClass('form-suggest-element')
+                .appendTo($suggestionContainer)
+                .click(function () {
+                  $input.focus();
+                  $input.val($(this).text());
+                  onSelectSuggestion($input);
+                });
+            });
+          }
+        })
+        .unbind('keydown.validation')
+        .bind('keydown.validation', function (e) {
+          var code = (e.keyCode ? e.keyCode : e.which),
+            suggestionId,
+            $suggestionContainer,
+            $input = $(this);
+
+          if (code === 13 && $.formUtils._selectedSuggestion !== null) {
+            suggestionId = $input.valAttr('suggestion-nr');
+            $suggestionContainer = $('.jquery-form-suggestion-' + 
suggestionId);
+            if ($suggestionContainer.length > 0) {
+              var newText = 
$suggestionContainer.find('div').eq($.formUtils._selectedSuggestion).text();
+              $input.val(newText);
+              onSelectSuggestion($input);
+              e.preventDefault();
+            }
+          }
+          else {
+            suggestionId = $input.valAttr('suggestion-nr');
+            $suggestionContainer = $('.jquery-form-suggestion-' + 
suggestionId);
+            var $suggestions = $suggestionContainer.children();
+            if ($suggestions.length > 0 && $.inArray(code, [38, 40]) > -1) {
+              if (code === 38) { // key up
+                if ($.formUtils._selectedSuggestion === null) {
+                  $.formUtils._selectedSuggestion = $suggestions.length - 1;
+                }
+                else{
+                  $.formUtils._selectedSuggestion--;
+                }
+                if ($.formUtils._selectedSuggestion < 0) {
+                  $.formUtils._selectedSuggestion = $suggestions.length - 1;
+                }
+              }
+              else if (code === 40) { // key down
+                if ($.formUtils._selectedSuggestion === null) {
+                  $.formUtils._selectedSuggestion = 0;
+                }
+                else {
+                  $.formUtils._selectedSuggestion++;
+                }
+                if ($.formUtils._selectedSuggestion > ($suggestions.length - 
1)) {
+                  $.formUtils._selectedSuggestion = 0;
+                }
+              }
+
+              // Scroll in suggestion window
+              var containerInnerHeight = $suggestionContainer.innerHeight(),
+                containerScrollTop = $suggestionContainer.scrollTop(),
+                suggestionHeight = 
$suggestionContainer.children().eq(0).outerHeight(),
+                activeSuggestionPosY = suggestionHeight * 
($.formUtils._selectedSuggestion);
+
+              if (activeSuggestionPosY < containerScrollTop || 
activeSuggestionPosY > (containerScrollTop + containerInnerHeight)) {
+                $suggestionContainer.scrollTop(activeSuggestionPosY);
+              }
+
+              $suggestions
+                .removeClass('active-suggestion')
+                .css('background', 'none')
+                .eq($.formUtils._selectedSuggestion)
+                .addClass('active-suggestion')
+                .css(conf.activeSuggestionCSS);
+
+              e.preventDefault();
+              return false;
+            }
+          }
+        })
+        .unbind('blur.suggest')
+        .bind('blur.suggest', function () {
+          onSelectSuggestion($(this));
+        });
+
+      return $elem;
+    },
+
+    /**
+     * Error dialogs
+     *
+     * @var {Object}
+     */
+    LANG: {
+      errorTitle: 'Form submission failed!',
+      requiredField: 'This is a required field',
+      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: 'The input value must be between ',
+      lengthBadEnd: ' characters',
+      lengthTooLongStart: 'The input value is longer than ',
+      lengthTooShortStart: 'The input value is shorter than ',
+      notConfirmed: 'Input values could not be confirmed',
+      badDomain: 'Incorrect domain value',
+      badUrl: 'The input value is not a correct URL',
+      badCustomVal: 'The input value is incorrect',
+      andSpaces: ' and spaces ',
+      badInt: 'The input value 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 input value can only contain alphanumeric 
characters ',
+      badAlphaNumericExtra: ' and ',
+      wrongFileSize: 'The file you are trying to upload is too large (max %s)',
+      wrongFileType: 'Only files of type %s is allowed',
+      groupCheckedRangeStart: 'Please choose between ',
+      groupCheckedTooFewStart: 'Please choose at least ',
+      groupCheckedTooManyStart: 'Please choose a maximum of ',
+      groupCheckedEnd: ' item(s)',
+      badCreditCard: 'The credit card number is not correct',
+      badCVV: 'The CVV number was not correct',
+      wrongFileDim : 'Incorrect image dimensions,',
+      imageTooTall : 'the image can not be taller than',
+      imageTooWide : 'the image can not be wider than',
+      imageTooSmall : 'the image was too small',
+      min : 'min',
+      max : 'max',
+      imageRatioNotAccepted : 'Image ratio is not be accepted',
+      badBrazilTelephoneAnswer: 'The phone number entered is invalid',
+      badBrazilCEPAnswer: 'The CEP entered is invalid',
+      badBrazilCPFAnswer: 'The CPF entered is invalid'
+    }
+  };
+
+
+  /* * * * * * * * * * * * * * * * * * * * * *
+   CORE VALIDATORS
+   * * * * * * * * * * * * * * * * * * * * */
+
+
+  /*
+   * Validate email
+   */
+  $.formUtils.addValidator({
+    name: 'email',
+    validatorFunction: function (email) {
+
+      var emailParts = email.toLowerCase().split('@'),
+          localPart = emailParts[0],
+          domain = emailParts[1];
+
+      if (localPart && domain) {
+
+        if( localPart.indexOf('"') === 0 ) {
+          var len = localPart.length;
+          localPart = localPart.replace(/\"/g, '');
+          if( localPart.length !== (len-2) ) {
+            return false; // It was not allowed to have more than two 
apostrophes
+          }
+        }
+
+        return 
$.formUtils.validators.validate_domain.validatorFunction(emailParts[1]) &&
+              localPart.indexOf('.') !== 0 &&
+              localPart.substring(localPart.length-1, localPart.length) !== 
'.' &&
+              localPart.indexOf('..') === -1 &&
+              !(/[^\w\+\.\-\#\-\_\~\!\$\&\'\(\)\*\+\,\;\=\:]/.test(localPart));
+      }
+
+      return false;
+    },
+    errorMessage: '',
+    errorMessageKey: 'badEmail'
+  });
+
+  /*
+   * Validate domain name
+   */
+  $.formUtils.addValidator({
+    name: 'domain',
+    validatorFunction: function (val) {
+      return val.length > 0 &&
+        val.length <= 253 && // Including sub domains
+        !(/[^a-zA-Z0-9]/.test(val.slice(-2))) && 
!(/[^a-zA-Z0-9]/.test(val.substr(0, 1))) && !(/[^a-zA-Z0-9\.\-]/.test(val)) &&
+        val.split('..').length === 1 &&
+        val.split('.').length > 1;
+    },
+    errorMessage: '',
+    errorMessageKey: 'badDomain'
+  });
+
+  /*
+   * Validate required
+   */
+  $.formUtils.addValidator({
+    name: 'required',
+    validatorFunction: function (val, $el, config, language, $form) {
+      switch ($el.attr('type')) {
+        case 'checkbox':
+          return $el.is(':checked');
+        case 'radio':
+          return $form.find('input[name="' + $el.attr('name') + 
'"]').filter(':checked').length > 0;
+        default:
+          return $.trim(val) !== '';
+      }
+    },
+    errorMessage: '',
+    errorMessageKey: function(config) {
+      if (config.errorMessagePosition === 'top' || config.errorMessagePosition 
=== 'custom') {
+        return 'requiredFields';
+      }
+      else {
+        return 'requiredField';
+      }
+    }
+  });
+
+  /*
+   * Validate length range
+   */
+  $.formUtils.addValidator({
+    name: 'length',
+    validatorFunction: function (val, $el, conf, lang) {
+      var lengthAllowed = $el.valAttr('length'),
+        type = $el.attr('type');
+
+      if (lengthAllowed === undefined) {
+        alert('Please add attribute "data-validation-length" to ' + 
$el[0].nodeName + ' named ' + $el.attr('name'));
+        return true;
+      }
+
+      // check if length is above min, below max or within range.
+      var len = type === 'file' && $el.get(0).files !== undefined ? 
$el.get(0).files.length : val.length,
+        lengthCheckResults = $.formUtils.numericRangeCheck(len, lengthAllowed),
+        checkResult;
+
+      switch (lengthCheckResults[0]) {   // outside of allowed range
+        case 'out':
+          this.errorMessage = lang.lengthBadStart + lengthAllowed + 
lang.lengthBadEnd;
+          checkResult = false;
+          break;
+        // too short
+        case 'min':
+          this.errorMessage = lang.lengthTooShortStart + lengthCheckResults[1] 
+ lang.lengthBadEnd;
+          checkResult = false;
+          break;
+        // too long
+        case 'max':
+          this.errorMessage = lang.lengthTooLongStart + lengthCheckResults[1] 
+ lang.lengthBadEnd;
+          checkResult = false;
+          break;
+        // ok
+        default:
+          checkResult = true;
+      }
+
+      return checkResult;
+    },
+    errorMessage: '',
+    errorMessageKey: ''
+  });
+
+  /*
+   * Validate url
+   */
+  $.formUtils.addValidator({
+    name: 'url',
+    validatorFunction: function (url) {
+      // written by Scott Gonzalez: http://projects.scottsplayground.com/iri/
+      // - Victor Jonsson added support for arrays in the url ?arg[]=sdfsdf
+      // - General improvements made by Stéphane Moureau 
<https://github.com/TraderStf>
+
+      var urlFilter = 
/^(https?|ftp):\/\/((((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])(\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])(\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/(((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|\[|\]|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#(((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i;
+      if (urlFilter.test(url)) {
+        var domain = url.split('://')[1],
+          domainSlashPos = domain.indexOf('/');
+
+        if (domainSlashPos > -1) {
+          domain = domain.substr(0, domainSlashPos);
+        }
+
+        return 
$.formUtils.validators.validate_domain.validatorFunction(domain); // todo: add 
support for IP-addresses
+      }
+      return false;
+    },
+    errorMessage: '',
+    errorMessageKey: 'badUrl'
+  });
+
+  /*
+   * Validate number (floating or integer)
+   */
+  $.formUtils.addValidator({
+    name: 'number',
+    validatorFunction: function (val, $el, conf) {
+      if (val !== '') {
+        var allowing = $el.valAttr('allowing') || '',
+          decimalSeparator = $el.valAttr('decimal-separator') || 
conf.decimalSeparator,
+          allowsRange = false,
+          begin, end,
+          steps = $el.valAttr('step') || '',
+          allowsSteps = false;
+
+        if (allowing.indexOf('number') === -1) {
+          allowing += ',number';
+        }
+
+        if (allowing.indexOf('negative') === -1 && val.indexOf('-') === 0) {
+          return false;
+        }
+
+        if (allowing.indexOf('range') > -1) {
+          begin = parseFloat(allowing.substring(allowing.indexOf('[') + 1, 
allowing.indexOf(';')));
+          end = parseFloat(allowing.substring(allowing.indexOf(';') + 1, 
allowing.indexOf(']')));
+          allowsRange = true;
+        }
+
+        if (steps !== '') {
+          allowsSteps = true;
+        }
+
+        if (decimalSeparator === ',') {
+          if (val.indexOf('.') > -1) {
+            return false;
+          }
+          // Fix for checking range with floats using ,
+          val = val.replace(',', '.');
+        }
+
+        if (allowing.indexOf('number') > -1 && val.replace(/[0-9-]/g, '') === 
'' && (!allowsRange || (val >= begin && val <= end)) && (!allowsSteps || (val % 
steps === 0))) {
+          return true;
+        }
+        if (allowing.indexOf('float') > -1 && val.match(new 
RegExp('^([0-9-]+)\\.([0-9]+)$')) !== null && (!allowsRange || (val >= begin && 
val <= end)) && (!allowsSteps || (val % steps === 0))) {
+          return true;
+        }
+      }
+      return false;
+    },
+    errorMessage: '',
+    errorMessageKey: 'badInt'
+  });
+
+  /*
+   * Validate alpha numeric
+   */
+  $.formUtils.addValidator({
+    name: 'alphanumeric',
+    validatorFunction: function (val, $el, conf, language) {
+      var patternStart = '^([a-zA-Z0-9',
+        patternEnd = ']+)$',
+        additionalChars = $el.valAttr('allowing'),
+        pattern = '';
+
+      if (additionalChars) {
+        pattern = patternStart + additionalChars + patternEnd;
+        var extra = additionalChars.replace(/\\/g, '');
+        if (extra.indexOf(' ') > -1) {
+          extra = extra.replace(' ', '');
+          extra += language.andSpaces || $.formUtils.LANG.andSpaces;
+        }
+        this.errorMessage = language.badAlphaNumeric + 
language.badAlphaNumericExtra + extra;
+      } else {
+        pattern = patternStart + patternEnd;
+        this.errorMessage = language.badAlphaNumeric;
+      }
+
+      return new RegExp(pattern).test(val);
+    },
+    errorMessage: '',
+    errorMessageKey: ''
+  });
+
+  /*
+   * Validate against regexp
+   */
+  $.formUtils.addValidator({
+    name: 'custom',
+    validatorFunction: function (val, $el) {
+      var regexp = new RegExp($el.valAttr('regexp'));
+      return regexp.test(val);
+    },
+    errorMessage: '',
+    errorMessageKey: 'badCustomVal'
+  });
+
+  /*
+   * Validate date
+   */
+  $.formUtils.addValidator({
+    name: 'date',
+    validatorFunction: function (date, $el, conf) {
+      var dateFormat = $el.valAttr('format') || conf.dateFormat || 
'yyyy-mm-dd';
+      return $.formUtils.parseDate(date, dateFormat) !== false;
+    },
+    errorMessage: '',
+    errorMessageKey: 'badDate'
+  });
+
+
+  /*
+   * Validate group of checkboxes, validate qty required is checked
+   * written by Steve Wasiura : http://stevewasiura.waztech.com
+   * element attrs
+   *    data-validation="checkbox_group"
+   *    data-validation-qty="1-2"  // min 1 max 2
+   *    data-validation-error-msg="chose min 1, max of 2 checkboxes"
+   */
+  $.formUtils.addValidator({
+    name: 'checkbox_group',
+    validatorFunction: function (val, $el, conf, lang, $form) {
+      // preset return var
+      var isValid = true,
+        // get name of element. since it is a checkbox group, all checkboxes 
will have same name
+        elname = $el.attr('name'),
+        // get checkboxes and count the checked ones
+        $checkBoxes = $('input[type=checkbox][name^="' + elname + '"]', $form),
+        checkedCount = $checkBoxes.filter(':checked').length,
+        // get el attr that specs qty required / allowed
+        qtyAllowed = $el.valAttr('qty');
+
+      if (qtyAllowed === undefined) {
+        var elementType = $el.get(0).nodeName;
+        alert('Attribute "data-validation-qty" is missing from ' + elementType 
+ ' named ' + $el.attr('name'));
+      }
+
+      // call Utility function to check if count is above min, below max, 
within range etc.
+      var qtyCheckResults = $.formUtils.numericRangeCheck(checkedCount, 
qtyAllowed);
+
+      // results will be array, [0]=result str, [1]=qty int
+      switch (qtyCheckResults[0]) {
+        // outside allowed range
+        case 'out':
+          this.errorMessage = lang.groupCheckedRangeStart + qtyAllowed + 
lang.groupCheckedEnd;
+          isValid = false;
+          break;
+        // below min qty
+        case 'min':
+          this.errorMessage = lang.groupCheckedTooFewStart + 
qtyCheckResults[1] + lang.groupCheckedEnd;
+          isValid = false;
+          break;
+        // above max qty
+        case 'max':
+          this.errorMessage = lang.groupCheckedTooManyStart + 
qtyCheckResults[1] + lang.groupCheckedEnd;
+          isValid = false;
+          break;
+        // ok
+        default:
+          isValid = true;
+      }
+
+      if( !isValid ) {
+        var _triggerOnBlur = function() {
+          $checkBoxes.unbind('click', _triggerOnBlur);
+          $checkBoxes.filter('*[data-validation]').validateInputOnBlur(lang, 
conf, false, 'blur');
+        };
+        $checkBoxes.bind('click', _triggerOnBlur);
+      }
+
+      return isValid;
+    }
+    //   errorMessage : '', // set above in switch statement
+    //   errorMessageKey: '' // not used
+  });
+
+})(jQuery);

Modified: 
branches/dev-syncromind/phpgwapi/js/jquery/validator/jquery.form-validator.min.js
===================================================================
--- 
branches/dev-syncromind/phpgwapi/js/jquery/validator/jquery.form-validator.min.js
   2015-11-20 08:20:45 UTC (rev 14431)
+++ 
branches/dev-syncromind/phpgwapi/js/jquery/validator/jquery.form-validator.min.js
   2015-11-20 09:31:32 UTC (rev 14432)
@@ -1,11 +1,8 @@
 /**
-* 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.13
-*/
-(function($){"use strict";var 
$window=$(window),_applyErrorStyle=function($elem,conf){var 
$parent=$elem.parent();$elem.addClass(conf.errorElementClass).removeClass("valid");if($parent.hasClass("input-group"))$parent=$parent.parent();$parent.addClass("has-error").removeClass("has-success");if(conf.borderColorOnError!==""){$elem.css("border-color",conf.borderColorOnError)}},_removeErrorStyle=function($elem,conf){$elem.each(function(){_setInlineErrorMessage($(this),"",conf,conf.errorMessagePosition);var
 
$parent=$(this).parent();if($parent.hasClass("input-group"))$parent=$parent.parent();$(this).removeClass("valid").removeClass(conf.errorElementClass).css("border-color","");$parent.removeClass("has-error").removeClass("has-success").find("."+conf.errorMessageClass).remove()})},_setInlineErrorMessage=function($input,mess,conf,$messageContainer){var
 custom=_getInlineErrorElement($input);var 
$parent=$input.parent();if($parent.hasClass("input-group"))$parent=$parent.parent();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
 
$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)};$.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")});return
 
this};$.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.attr("data-validation-event");if(etype){$el.bind(etype+".validation",function(){$(this).validateInputOnBlur(language,settings,true,etype)})}});return
 
this};$.fn.showHelpOnFocus=function(attrName){if(!attrName){attrName="data-validation-help"}this.find(".has-help-txt").valAttr("has-keyup-event",false).removeClass("has-help-txt");this.find("textarea,input").each(function(){var
 
$elem=$(this),className="jquery_form_help_"+($elem.attr("name")||"").replace(/(:|\.|\[|\])/g,""),help=$elem.attr(attrName);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").text(help).hide();$elem.after($help)}$help.fadeIn()}).unbind("blur.help").bind("blur.help",function(){$(this).parent().find("."+className).fadeOut("slow")})}});return
 
this};$.fn.validateInputOnBlur=function(language,conf,attachKeyupEvent,eventType){$.formUtils.eventType=eventType;if((this.valAttr("suggestion-nr")||this.valAttr("postpone")||this.hasClass("hasDatepicker"))&&!window.postponedValidation){var
 
_self=this,postponeTime=this.valAttr("postpone")||200;window.postponedValidation=function(){_self.validateInputOnBlur(language,conf,attachKeyupEvent,eventType);window.postponedValidation=false};setTimeout(function(){if(window.postponedValidation){window.postponedValidation()}},postponeTime);return
 
this}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("has-success")}else
 
if(validation!==null){_applyErrorStyle($elem,conf);_setInlineErrorMessage($elem,validation,conf,conf.errorMessagePosition);if(attachKeyupEvent){$elem.unbind("keyup.validation").bind("keyup.validation",function(){$(this).validateInputOnBlur(language,conf,false,"keyup")})}}return
 this};$.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)}};$.fn.isValid=function(language,conf,displayError){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;$.formUtils.isValidatingEntireForm=true;$.formUtils.haltValidation=false;var
 
addErrorMessage=function(mess,$elem){if(mess!==null){if($.inArray(mess,errorMessages)<0){errorMessages.push(mess)}errorInputs.push($elem);$elem.attr("current-error",mess);if(displayError)_applyErrorStyle($elem,conf)}},errorMessages=[],errorInputs=[],$form=this,ignoreInput=function(name,type){if(type==="submit"||type==="button"||type=="reset"){return
 true}return 
$.inArray(name,conf.ignore||[])>-1};if(displayError){$form.find("."+conf.errorMessageClass+".alert").remove();_removeErrorStyle($form.find("."+conf.errorElementClass+",.valid"),conf)}$form.find("input,textarea,select").filter(':not([type="submit"],[type="button"])').each(function(){var
 $elem=$(this);var 
elementType=$elem.attr("type");if(!ignoreInput($elem.attr("name"),elementType)){var
 
validation=$.formUtils.validateInput($elem,language,conf,$form,"submit");if(typeof
 
conf.onElementValidate=="function"){conf.onElementValidate(validation===true,$elem,$form,validation)}if(validation!==true){addErrorMessage(validation,$elem)}else{$elem.valAttr("current-error",false).addClass("valid").parent().addClass("has-success")}}});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)}}$.formUtils.isValidatingEntireForm=false;if(!$.formUtils.haltValidation&&errorInputs.length>0){if(displayError){if(conf.errorMessagePosition==="top"){_templateMessage($form,language.errorTitle,errorMessages,conf)}else
 if(conf.errorMessagePosition==="custom"){if(typeof 
conf.errorMessageCustom==="function"){conf.errorMessageCustom($form,language.errorTitle,errorMessages,conf)}}else{$.each(errorInputs,function(i,$input){_setInlineErrorMessage($input,$input.attr("current-error"),conf,conf.errorMessagePosition)})}if(conf.scrollToTopOnError){$window.scrollTop($form.offset().top-20)}}return
 
false}return!$.formUtils.haltValidation};$.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)};$.fn.restrictLength=function(maxLengthElement){new
 $.formUtils.lengthRestriction(this,maxLengthElement);return 
this};$.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};$.split=function(val,func,delim){if(typeof 
func!="function"){if(!val)return[];var 
values=[];$.each(val.split(func?func:","),function(i,str){str=$.trim(str);if(str.length)values.push(str)});return
 values}else 
if(val){if(!delim)delim=",";$.each(val.split(delim),function(i,str){str=$.trim(str);if(str.length)return
 func(str,i)})}};$.validate=function(conf){var 
defaultConf=$.extend($.formUtils.defaultConfig(),{form:"form",validateOnEvent:true,validateOnBlur:true,showHelpOnFocus:true,addSuggestions:true,modules:"",onModulesLoaded:null,language:false,onSuccess:false,onError:false,onElementValidate:false});conf=$.extend(defaultConf,conf||{});$(conf.form).each(function(i,form){var
 
$form=$(form);$window.trigger("formValidationSetup",[$form]);$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");$form.bind("submit.validation",function(){var
 
$form=$(this);if($.formUtils.isLoadingModules){setTimeout(function(){$form.trigger("submit.validation")},200);return
 false}var valid=$form.isValid(conf.language,conf);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(){$(this).find("."+conf.errorMessageClass+".alert").remove();_removeErrorStyle($(this).find("."+conf.errorElementClass+",.valid"),conf)}).addClass("has-validation-callback");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!=""){if(typeof
 
conf.onModulesLoaded=="function"){$window.one("validatorsLoaded",conf.onModulesLoaded)}$.formUtils.loadModules(conf.modules)}};$.formUtils={defaultConfig:function(){return{ignore:[],errorElementClass:"error",borderColorOnError:"red",errorMessageClass:"form-error",validationRuleAttribute:"data-validation",validationErrorMsgAttribute:"data-validation-error-msg",errorMessagePosition:"element",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,decimalSeparator:"."}},validators:{},_events:{load:[],valid:[],invalid:[]},haltValidation:false,isValidatingEntireForm:false,addValidator:function(validator){var
 
name=validator.name.indexOf("validate_")===0?validator.name:"validate_"+validator.name;if(validator.validateOnKeyUp===undefined)validator.validateOnKeyUp=true;this.validators[name]=validator},isLoadingModules:false,loadedModules:{},loadModules:function(modules,path,fireEvent){if(fireEvent===undefined)fireEvent=true;if($.formUtils.isLoadingModules){setTimeout(function(){$.formUtils.loadModules(modules,path,fireEvent)});return}var
 hasLoadedAnyModule=false,loadModuleScripts=function(modules,path){var 
moduleList=$.split(modules),numModules=moduleList.length,moduleLoadedCallback=function(){numModules--;if(numModules==0){$.formUtils.isLoadingModules=false;if(fireEvent&&hasLoadedAnyModule){$window.trigger("validatorsLoaded")}}};if(numModules>0){$.formUtils.isLoadingModules=true}var
 cacheSuffix="?__="+(new 
Date).getTime(),appendToElement=document.getElementsByTagName("head")[0]||document.getElementsByTagName("body")[0];$.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");if(scriptUrl
 in 
$.formUtils.loadedModules){moduleLoadedCallback()}else{$.formUtils.loadedModules[scriptUrl]=1;hasLoadedAnyModule=true;script.type="text/javascript";script.onload=moduleLoadedCallback;script.src=scriptUrl+(scriptUrl.substr(-7)==".dev.js"?cacheSuffix:"");script.onreadystatechange=function(){if(this.readyState=="complete"||this.readyState=="loaded"){moduleLoadedCallback();this.onload=null;this.onreadystatechange=null}};appendToElement.appendChild(script)}}})};if(path){loadModuleScripts(modules,path)}else{var
 findScriptPathAndLoadModules=function(){var 
foundPath=false;$("script").each(function(){if(this.src){var 
scriptName=this.src.substr(this.src.lastIndexOf("/")+1,this.src.length);if(scriptName.indexOf("jquery.form-validator.js")>-1||scriptName.indexOf("jquery.form-validator.min.js")>-1){foundPath=this.src.substr(0,this.src.lastIndexOf("/"))+"/";if(foundPath=="/")foundPath="";return
 false}}});if(foundPath!==false){loadModuleScripts(modules,foundPath);return 
true}return 
false};if(!findScriptPathAndLoadModules()){$(findScriptPathAndLoadModules)}}},validateInput:function($elem,language,conf,$form,eventContext){if($elem.attr("disabled"))return
 null;$elem.trigger("beforeValidation");var 
value=$elem.val()||"",optional=$elem.valAttr("optional"),validationDependsOnCheckedInput=false,validationDependentInputIsChecked=false,validateIfCheckedElement=false,validateIfCheckedElementName=$elem.valAttr("if-checked");if(validateIfCheckedElementName!=null){validationDependsOnCheckedInput=true;validateIfCheckedElement=$form.find('input[name="'+validateIfCheckedElementName+'"]');if(validateIfCheckedElement.prop("checked")){validationDependentInputIsChecked=true}}if(!value&&optional==="true"||validationDependsOnCheckedInput&&!validationDependentInputIsChecked){return
 conf.addValidClassOnAll?true:null}var 
validationRules=$elem.attr(conf.validationRuleAttribute),validationErrorMsg=true;if(!validationRules){return
 
conf.addValidClassOnAll?true:null}$.split(validationRules,function(rule){if(rule.indexOf("validate_")!==0){rule="validate_"+rule}var
 validator=$.formUtils.validators[rule];if(validator&&typeof 
validator["validatorFunction"]=="function"){if(rule=="validate_checkbox_group"){$elem=$("[name='"+$elem.attr("name")+"']:eq(0)")}var
 
isValid=null;if(eventContext!="keyup"||validator.validateOnKeyUp){isValid=validator.validatorFunction(value,$elem,conf,language,$form)}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}}else{throw new Error('Using undefined validator "'+rule+'"')}}," 
");if(typeof 
validationErrorMsg=="string"){$elem.trigger("validation",false);return 
validationErrorMsg}else 
if(validationErrorMsg===null&&!conf.addValidClassOnAll){return 
null}else{$elem.trigger("validation",true);return 
true}},parseDate:function(val,dateFormat){var 
divider=dateFormat.replace(/[a-zA-Z]/gi,"").substring(0,1),regexp="^",formatParts=dateFormat.split(divider),matches,day,month,year;$.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]},parseDateInt:function(val){if(val.indexOf("0")===0){val=val.replace("0","")}return
 parseInt(val,10)},isShortMonth:function(m){return 
m%2===0&&m<7||m%2!==0&&m>7},lengthRestriction:function($inputElement,$maxLengthElement){var
 
maxChars=parseInt($maxLengthElement.text(),10),charsLeft=0,countCharacters=function(){var
 numChars=$inputElement.val().length;if(numChars>maxChars){var 
currScrollTopPos=$inputElement.scrollTop();$inputElement.val($inputElement.val().substring(0,maxChars));$inputElement.scrollTop(currScrollTopPos)}charsLeft=maxChars-numChars;if(charsLeft<0)charsLeft=0;$maxLengthElement.text(charsLeft)};$($inputElement).bind("keydown
 keyup keypress focus blur",countCharacters).bind("cut 
paste",function(){setTimeout(countCharacters,100)});$(document).bind("ready",countCharacters)},numericRangeCheck:function(value,rangeAllowed){var
 range=$.split(rangeAllowed,"-");var 
minmax=parseInt(rangeAllowed.substr(3),10);if(range.length==2&&(value<parseInt(range[0],10)||value>parseInt(range[1],10))){return["out",range[0],range[1]]}else
 if(rangeAllowed.indexOf("min")===0&&value<minmax){return["min",minmax]}else 
if(rangeAllowed.indexOf("max")===0&&value>minmax){return["max",minmax]}return["ok"]},_numSuggestionElements:0,_selectedSuggestion:null,_previousTypedVal:null,suggest:function($elem,suggestions,settings){var
 
conf={css:{maxHeight:"150px",background:"#FFF",lineHeight:"150%",textDecoration:"underline",overflowX:"hidden",overflowY:"auto",border:"#CCC
 solid 
1px",borderTop:"none",cursor:"pointer"},activeSuggestionCSS:{background:"#E9E9E9"}},setSuggsetionPosition=function($suggestionContainer,$input){var
 
offset=$input.offset();$suggestionContainer.css({width:$input.outerWidth(),left:offset.left+"px",top:offset.top+$input.outerHeight()+"px"})};if(settings)$.extend(conf,settings);conf.css["position"]="absolute";conf.css["z-index"]=9999;$elem.attr("autocomplete","off");if(this._numSuggestionElements===0){$window.bind("resize",function(){$(".jquery-form-suggestions").each(function(){var
 
$container=$(this),suggestID=$container.attr("data-suggest-container");setSuggsetionPosition($container,$(".suggestions-"+suggestID).eq(0))})})}this._numSuggestionElements++;var
 onSelectSuggestion=function($el){var 
suggestionId=$el.valAttr("suggestion-nr");$.formUtils._selectedSuggestion=null;$.formUtils._previousTypedVal=null;$(".jquery-form-suggestion-"+suggestionId).fadeOut("fast")};$elem.data("suggestions",suggestions).valAttr("suggestion-nr",this._numSuggestionElements).unbind("focus.suggest").bind("focus.suggest",function(){$(this).trigger("keyup");$.formUtils._selectedSuggestion=null}).unbind("keyup.suggest").bind("keyup.suggest",function(){var
 
$input=$(this),foundSuggestions=[],val=$.trim($input.val()).toLocaleLowerCase();if(val==$.formUtils._previousTypedVal){return}else{$.formUtils._previousTypedVal=val}var
 
hasTypedSuggestion=false,suggestionId=$input.valAttr("suggestion-nr"),$suggestionContainer=$(".jquery-form-suggestion-"+suggestionId);$suggestionContainer.scrollTop(0);if(val!=""){var
 
findPartial=val.length>2;$.each($input.data("suggestions"),function(i,suggestion){var
 
lowerCaseVal=suggestion.toLocaleLowerCase();if(lowerCaseVal==val){foundSuggestions.push("<strong>"+suggestion+"</strong>");hasTypedSuggestion=true;return
 false}else 
if(lowerCaseVal.indexOf(val)===0||findPartial&&lowerCaseVal.indexOf(val)>-1){foundSuggestions.push(suggestion.replace(new
 
RegExp(val,"gi"),"<strong>$&</strong>"))}})}if(hasTypedSuggestion||foundSuggestions.length==0&&$suggestionContainer.length>0){$suggestionContainer.hide()}else
 
if(foundSuggestions.length>0&&$suggestionContainer.length==0){$suggestionContainer=$("<div></div>").css(conf.css).appendTo("body");$elem.addClass("suggestions-"+suggestionId);$suggestionContainer.attr("data-suggest-container",suggestionId).addClass("jquery-form-suggestions").addClass("jquery-form-suggestion-"+suggestionId)}else
 
if(foundSuggestions.length>0&&!$suggestionContainer.is(":visible")){$suggestionContainer.show()}if(foundSuggestions.length>0&&val.length!=foundSuggestions[0].length){setSuggsetionPosition($suggestionContainer,$input);$suggestionContainer.html("");$.each(foundSuggestions,function(i,text){$("<div></div>").append(text).css({overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",padding:"5px"}).addClass("form-suggest-element").appendTo($suggestionContainer).click(function(){$input.focus();$input.val($(this).text());onSelectSuggestion($input)})})}}).unbind("keydown.validation").bind("keydown.validation",function(e){var
 
code=e.keyCode?e.keyCode:e.which,suggestionId,$suggestionContainer,$input=$(this);if(code==13&&$.formUtils._selectedSuggestion!==null){suggestionId=$input.valAttr("suggestion-nr");$suggestionContainer=$(".jquery-form-suggestion-"+suggestionId);if($suggestionContainer.length>0){var
 
newText=$suggestionContainer.find("div").eq($.formUtils._selectedSuggestion).text();$input.val(newText);onSelectSuggestion($input);e.preventDefault()}}else{suggestionId=$input.valAttr("suggestion-nr");$suggestionContainer=$(".jquery-form-suggestion-"+suggestionId);var
 
$suggestions=$suggestionContainer.children();if($suggestions.length>0&&$.inArray(code,[38,40])>-1){if(code==38){if($.formUtils._selectedSuggestion===null)$.formUtils._selectedSuggestion=$suggestions.length-1;else
 
$.formUtils._selectedSuggestion--;if($.formUtils._selectedSuggestion<0)$.formUtils._selectedSuggestion=$suggestions.length-1}else
 
if(code==40){if($.formUtils._selectedSuggestion===null)$.formUtils._selectedSuggestion=0;else
 
$.formUtils._selectedSuggestion++;if($.formUtils._selectedSuggestion>$suggestions.length-1)$.formUtils._selectedSuggestion=0}var
 
containerInnerHeight=$suggestionContainer.innerHeight(),containerScrollTop=$suggestionContainer.scrollTop(),suggestionHeight=$suggestionContainer.children().eq(0).outerHeight(),activeSuggestionPosY=suggestionHeight*$.formUtils._selectedSuggestion;if(activeSuggestionPosY<containerScrollTop||activeSuggestionPosY>containerScrollTop+containerInnerHeight){$suggestionContainer.scrollTop(activeSuggestionPosY)}$suggestions.removeClass("active-suggestion").css("background","none").eq($.formUtils._selectedSuggestion).addClass("active-suggestion").css(conf.activeSuggestionCSS);e.preventDefault();return
 
false}}}).unbind("blur.suggest").bind("blur.suggest",function(){onSelectSuggestion($(this))});return
 $elem},LANG:{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:"The input value must be between ",lengthBadEnd:" 
characters",lengthTooLongStart:"The input value is longer than 
",lengthTooShortStart:"The input value is shorter than ",notConfirmed:"Input 
values could not be confirmed",badDomain:"Incorrect domain value",badUrl:"The 
input value is not a correct URL",badCustomVal:"The input value is 
incorrect",badInt:"The input value 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 input 
value can only contain 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)",badCreditCard:"The credit card number is not correct",badCVV:"The CVV 
number was not 
correct"}};$.formUtils.addValidator({name:"email",validatorFunction:function(email){var
 emailParts=email.toLowerCase().split("@");if(emailParts.length==2){return 
$.formUtils.validators.validate_domain.validatorFunction(emailParts[1])&&!/[^\w\+\.\-]/.test(emailParts[0])}return
 
false},errorMessage:"",errorMessageKey:"badEmail"});$.formUtils.addValidator({name:"domain",validatorFunction:function(val,$input){var
 
topDomains=[".ac",".ad",".ae",".aero",".af",".ag",".ai",".al",".am",".an",".ao",".aq",".ar",".arpa",".as",".asia",".at",".au",".aw",".ax",".az",".ba",".bb",".bd",".be",".bf",".bg",".bh",".bi",".bike",".biz",".bj",".bm",".bn",".bo",".br",".bs",".bt",".bv",".bw",".by",".bz",".ca",".camera",".cat",".cc",".cd",".cf",".cg",".ch",".ci",".ck",".cl",".clothing",".cm",".cn",".co",".com",".construction",".contractors",".coop",".cr",".cu",".cv",".cw",".cx",".cy",".cz",".de",".diamonds",".directory",".dj",".dk",".dm",".do",".dz",".ec",".edu",".ee",".eg",".enterprises",".equipment",".er",".es",".estate",".et",".eu",".fi",".fj",".fk",".fm",".fo",".fr",".ga",".gallery",".gb",".gd",".ge",".gf",".gg",".gh",".gi",".gl",".gm",".gn",".gov",".gp",".gq",".gr",".graphics",".gs",".gt",".gu",".guru",".gw",".gy",".hk",".hm",".hn",".holdings",".hr",".ht",".hu",".id",".ie",".il",".im",".in",".info",".int",".io",".iq",".ir",".is",".it",".je",".jm",".jo",".jobs",".jp",".ke",".kg",".kh",".ki",".kitchen",".km",".kn",".kp",".kr",".kw",".ky",".kz",".la",".land",".lb",".lc",".li",".lighting",".lk",".lr",".ls",".lt",".lu",".lv",".ly",".ma",".mc",".md",".me",".menu",".mg",".mh",".mil",".mk",".ml",".mm",".mn",".mo",".mobi",".mp",".mq",".mr",".ms",".mt",".mu",".museum",".mv",".mw",".mx",".my",".mz",".na",".name",".nc",".ne",".net",".nf",".ng",".ni",".nl",".no",".np",".nr",".nu",".nz",".om",".org",".pa",".pe",".pf",".pg",".ph",".photography",".pk",".pl",".plumbing",".pm",".pn",".post",".pr",".pro",".ps",".pt",".pw",".py",".qa",".re",".ro",".rs",".ru",".rw",".sa",".sb",".sc",".sd",".se",".sexy",".sg",".sh",".si",".singles",".sj",".sk",".sl",".sm",".sn",".so",".sr",".st",".su",".sv",".sx",".sy",".sz",".tattoo",".tc",".td",".technology",".tel",".tf",".tg",".th",".tips",".tj",".tk",".tl",".tm",".tn",".to",".today",".tp",".tr",".travel",".tt",".tv",".tw",".tz",".ua",".ug",".uk",".uno",".us",".uy",".uz",".va",".vc",".ve",".ventures",".vg",".vi",".vn",".voyage",".vu",".wf",".ws",".xn--3e0b707e",".xn--45brj9c",".xn--80ao21a",".xn--80asehdb",".xn--80aswg",".xn--90a3ac",".xn--clchc0ea0b2g2a9gcd",".xn--fiqs8s",".xn--fiqz9s",".xn--fpcrj9c3d",".xn--fzc2c9e2c",".xn--gecrj9c",".xn--h2brj9c",".xn--j1amh",".xn--j6w193g",".xn--kprw13d",".xn--kpry57d",".xn--l1acc",".xn--lgbbat1ad8j",".xn--mgb9awbf",".xn--mgba3a4f16a",".xn--mgbaam7a8h",".xn--mgbayh7gpa",".xn--mgbbh1a71e",".xn--mgbc0a9azcg",".xn--mgberp4a5d4ar",".xn--mgbx4cd0ab",".xn--ngbc5azd",".xn--o3cw4h",".xn--ogbpf8fl",".xn--p1ai",".xn--pgbs0dh",".xn--q9jyb4c",".xn--s9brj9c",".xn--unup4y",".xn--wgbh1c",".xn--wgbl6a",".xn--xkc2al3hye2a",".xn--xkc2dl3a5ee0h",".xn--yfro4i67o",".xn--ygbi2ammx",".xxx",".ye",".yt",".za",".zm",".zw"],ukTopDomains=["co","me","ac","gov","judiciary","ltd","mod","net","nhs","nic","org","parliament","plc","police","sch","bl","british-library","jet","nls"],dot=val.lastIndexOf("."),domain=val.substring(0,dot),ext=val.substring(dot,val.length),hasTopDomain=false;for(var
 i=0;i<topDomains.length;i++){if(topDomains[i]===ext){if(ext===".uk"){var 
domainParts=val.split(".");var tld2=domainParts[domainParts.length-2];for(var 
j=0;j<ukTopDomains.length;j++){if(ukTopDomains[j]===tld2){hasTopDomain=true;break}}if(hasTopDomain)break}else{hasTopDomain=true;break}}}if(!hasTopDomain){return
 false}else if(dot<2||dot>57){return 
$.inArray(val,["i.net","q.com","q.net","x.com","x.org","z.com","w.org"])>-1}else{var
 
firstChar=domain.substring(0,1),lastChar=domain.substring(domain.length-1,domain.length);if(firstChar==="-"||firstChar==="."||lastChar==="-"||lastChar==="."){return
 false}if(domain.split("..").length>1){return 
false}if(domain.replace(/[-\da-z\.]/g,"")!==""){return false}}if(typeof 
$input!=="undefined"){$input.val(val)}return 
true},errorMessage:"",errorMessageKey:"badDomain"});$.formUtils.addValidator({name:"required",validatorFunction:function(val,$el,config,language,$form){switch($el.attr("type")){case"checkbox":return
 $el.is(":checked");case"radio":return 
$form.find('input[name="'+$el.attr("name")+'"]').filter(":checked").length>0;default:return
 
$.trim(val)!==""}},errorMessage:"",errorMessageKey:"requiredFields"});$.formUtils.addValidator({name:"length",validatorFunction:function(val,$el,conf,lang){var
 
lengthAllowed=$el.valAttr("length"),type=$el.attr("type");if(lengthAllowed==undefined){var
 elementType=$el.get(0).nodeName;alert('Please add attribute 
"data-validation-length" to '+elementType+" named "+$el.attr("name"));return 
true}var 
len=type=="file"&&$el.get(0).files!==undefined?$el.get(0).files.length:val.length,lengthCheckResults=$.formUtils.numericRangeCheck(len,lengthAllowed),checkResult;switch(lengthCheckResults[0]){case"out":this.errorMessage=lang.lengthBadStart+lengthAllowed+lang.lengthBadEnd;checkResult=false;break;case"min":this.errorMessage=lang.lengthTooShortStart+lengthCheckResults[1]+lang.lengthBadEnd;checkResult=false;break;case"max":this.errorMessage=lang.lengthTooLongStart+lengthCheckResults[1]+lang.lengthBadEnd;checkResult=false;break;default:checkResult=true}return
 
checkResult},errorMessage:"",errorMessageKey:""});$.formUtils.addValidator({name:"url",validatorFunction:function(url){var
 
urlFilter=/^(https?|ftp):\/\/((((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])(\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])(\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/(((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|\[|\]|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#(((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i;if(urlFilter.test(url)){var
 domain=url.split("://")[1];var 
domainSlashPos=domain.indexOf("/");if(domainSlashPos>-1)domain=domain.substr(0,domainSlashPos);return
 $.formUtils.validators.validate_domain.validatorFunction(domain)}return 
false},errorMessage:"",errorMessageKey:"badUrl"});$.formUtils.addValidator({name:"number",validatorFunction:function(val,$el,conf){if(val!==""){var
 
allowing=$el.valAttr("allowing")||"",decimalSeparator=$el.valAttr("decimal-separator")||conf.decimalSeparator,allowsRange=false,begin,end,steps=$el.valAttr("step")||"",allowsSteps=false;if(allowing.indexOf("number")==-1)allowing+=",number";if(allowing.indexOf("negative")>-1&&val.indexOf("-")===0){val=val.substr(1)}if(allowing.indexOf("range")>-1){begin=parseFloat(allowing.substring(allowing.indexOf("[")+1,allowing.indexOf(";")));end=parseFloat(allowing.substring(allowing.indexOf(";")+1,allowing.indexOf("]")));allowsRange=true}if(steps!=""){allowsSteps=true}if(decimalSeparator==","){if(val.indexOf(".")>-1){return
 
false}val=val.replace(",",".")}if(allowing.indexOf("number")>-1&&val.replace(/[0-9]/g,"")===""&&(!allowsRange||val>=begin&&val<=end)&&(!allowsSteps||val%steps==0)){return
 true}if(allowing.indexOf("float")>-1&&val.match(new 
RegExp("^([0-9]+)\\.([0-9]+)$"))!==null&&(!allowsRange||val>=begin&&val<=end)&&(!allowsSteps||val%steps==0)){return
 true
-}}return 
false},errorMessage:"",errorMessageKey:"badInt"});$.formUtils.addValidator({name:"alphanumeric",validatorFunction:function(val,$el,conf,language){var
 
patternStart="^([a-zA-Z0-9",patternEnd="]+)$",additionalChars=$el.attr("data-validation-allowing"),pattern="";if(additionalChars){pattern=patternStart+additionalChars+patternEnd;var
 extra=additionalChars.replace(/\\/g,"");if(extra.indexOf(" 
")>-1){extra=extra.replace(" ","");extra+=" and spaces 
"}this.errorMessage=language.badAlphaNumeric+language.badAlphaNumericExtra+extra}else{pattern=patternStart+patternEnd;this.errorMessage=language.badAlphaNumeric}return
 new 
RegExp(pattern).test(val)},errorMessage:"",errorMessageKey:""});$.formUtils.addValidator({name:"custom",validatorFunction:function(val,$el,conf){var
 regexp=new RegExp($el.valAttr("regexp"));return 
regexp.test(val)},errorMessage:"",errorMessageKey:"badCustomVal"});$.formUtils.addValidator({name:"date",validatorFunction:function(date,$el,conf){var
 
dateFormat="yyyy-mm-dd";if($el.valAttr("format")){dateFormat=$el.valAttr("format")}else
 if(conf.dateFormat){dateFormat=conf.dateFormat}return 
$.formUtils.parseDate(date,dateFormat)!==false},errorMessage:"",errorMessageKey:"badDate"});$.formUtils.addValidator({name:"checkbox_group",validatorFunction:function(val,$el,conf,lang,$form){var
 checkResult=true;var elname=$el.attr("name");var 
checkedCount=$("input[type=checkbox][name^='"+elname+"']:checked",$form).length;var
 qtyAllowed=$el.valAttr("qty");if(qtyAllowed==undefined){var 
elementType=$el.get(0).nodeName;alert('Attribute "data-validation-qty" is 
missing from '+elementType+" named "+$el.attr("name"))}var 
qtyCheckResults=$.formUtils.numericRangeCheck(checkedCount,qtyAllowed);switch(qtyCheckResults[0]){case"out":this.errorMessage=lang.groupCheckedRangeStart+qtyAllowed+lang.groupCheckedEnd;checkResult=false;break;case"min":this.errorMessage=lang.groupCheckedTooFewStart+qtyCheckResults[1]+lang.groupCheckedEnd;checkResult=false;break;case"max":this.errorMessage=lang.groupCheckedTooManyStart+qtyCheckResults[1]+lang.groupCheckedEnd;checkResult=false;break;default:checkResult=true}return
 checkResult}})})(jQuery);
\ No newline at end of file
+ *  JQUERY-FORM-VALIDATOR
+ *
+ *  @website by 
+ *  @license MIT
+ *  @version 2.2.83
+ */

@@ Diff output truncated at 153600 characters. @@



reply via email to

[Prev in Thread] Current Thread [Next in Thread]