[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. @@
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Fmsystem-commits] [14432] validator: update from upstream,
Sigurd Nes <=