mirror of
https://gitlab.com/JKANetwork/CheckServer.git
synced 2026-03-06 02:22:01 +01:00
Start again
This commit is contained in:
14
vendors/validator/.bower.json
vendored
Normal file
14
vendors/validator/.bower.json
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "validator",
|
||||
"homepage": "https://github.com/yairEO/validator",
|
||||
"version": "1.1.0",
|
||||
"_release": "1.1.0",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "1.1.0",
|
||||
"commit": "f855eb37c626f2ad712583d25afdd30147a40d8e"
|
||||
},
|
||||
"_source": "https://github.com/yairEO/validator.git",
|
||||
"_target": "^1.0.6",
|
||||
"_originalSource": "https://github.com/yairEO/validator.git"
|
||||
}
|
||||
22
vendors/validator/.gitattributes
vendored
Normal file
22
vendors/validator/.gitattributes
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
*.sln merge=union
|
||||
*.csproj merge=union
|
||||
*.vbproj merge=union
|
||||
*.fsproj merge=union
|
||||
*.dbproj merge=union
|
||||
|
||||
# Standard to msysgit
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
||||
163
vendors/validator/.gitignore
vendored
Normal file
163
vendors/validator/.gitignore
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
#################
|
||||
## Eclipse
|
||||
#################
|
||||
|
||||
*.pydevproject
|
||||
.project
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.classpath
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
|
||||
#################
|
||||
## Visual Studio
|
||||
#################
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.vspscc
|
||||
.builds
|
||||
*.dotCover
|
||||
|
||||
## TODO: If you have NuGet Package Restore enabled, uncomment this
|
||||
#packages/
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish
|
||||
|
||||
# Others
|
||||
[Bb]in
|
||||
[Oo]bj
|
||||
sql
|
||||
TestResults
|
||||
*.Cache
|
||||
ClientBin
|
||||
stylecop.*
|
||||
~$*
|
||||
*.dbmdl
|
||||
Generated_Code #added for RIA/Silverlight projects
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
|
||||
|
||||
|
||||
############
|
||||
## Windows
|
||||
############
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
|
||||
#############
|
||||
## Python
|
||||
#############
|
||||
|
||||
*.py[co]
|
||||
|
||||
# Packages
|
||||
*.egg
|
||||
*.egg-info
|
||||
dist
|
||||
build
|
||||
eggs
|
||||
parts
|
||||
bin
|
||||
var
|
||||
sdist
|
||||
develop-eggs
|
||||
.installed.cfg
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.tox
|
||||
|
||||
#Translations
|
||||
*.mo
|
||||
|
||||
#Mr Developer
|
||||
.mr.developer.cfg
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
159
vendors/validator/README.md
vendored
Normal file
159
vendors/validator/README.md
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
validator
|
||||
=========
|
||||
The javascript validation code is based on jQuery. The Validator is cross-browser and will give you the power to use future-proof input types such as ‘tel’, ‘email’, ‘number’, ‘date’, and ‘url’. I can sum this as a ‘template’ for creating web forms.
|
||||
|
||||
In the semantic point-of-view, I believe that this method is very clean and…appropriate. This is how forms should be, IMHO.
|
||||
|
||||
[DEMO PAGE](http://yaireo.github.io/validator)
|
||||
|
||||
### Why should you use this?
|
||||
|
||||
* Cross browser validation
|
||||
* Deals with all sorts of edge cases
|
||||
* Utilize new HTML5 types for unsupported browsers
|
||||
* Flexible error messaging system
|
||||
* Light-weight (10kb + comments)
|
||||
|
||||
## Validation types support
|
||||
HTML5 offers a wide selection of input types. I saw no need to support them all, for example, a checkbox should not be validated as ‘required’ because why wouldn’t it be checked in the first place when the form is rendered?
|
||||
|
||||
For a full list of all the available Types, visit the working draft page.
|
||||
These input types can be validated by the the JS for – `<input type='foo' name='bar' />`. (Support is synthesized)
|
||||
|
||||
* Text
|
||||
* Email
|
||||
* Password
|
||||
* Number
|
||||
* Date
|
||||
* URL
|
||||
* Search
|
||||
* File
|
||||
* Tel
|
||||
* Checkbox
|
||||
* Hidden – Hidden fields can also have the ‘required’ attribute
|
||||
|
||||
The below form elements are also supported:
|
||||
|
||||
* Select – Useing a ‘required’ class because there is no such attribute for ‘select’ element
|
||||
* Textarea
|
||||
|
||||
|
||||
## Basic semantics
|
||||
<form action="" method="post" novalidate>
|
||||
<fieldset>
|
||||
<div class="item">
|
||||
<label>
|
||||
<span>Name</span>
|
||||
<input data-validate-lengthRange="6" data-validate-words="2" name="name" placeholder="ex. John f. Kennedy" required="required" type="text" />
|
||||
</label>
|
||||
<div class='tooltip help'>
|
||||
<span>?</span>
|
||||
<div class='content'>
|
||||
<b></b>
|
||||
<p>Name must be at least 2 words</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>
|
||||
<span>email</span>
|
||||
<input name="email" required="required" type="email" />
|
||||
</label>
|
||||
</div>
|
||||
...
|
||||
|
||||
|
||||
### Explaining the DOM
|
||||
First, obviously, there is a Form element with the novalidate attribute to make sure to disable the native HTML5 validations (which currently suck). proceeding it there is a Fieldset element which is not a must, but acts as a “binding” box for a group of fields that are under the same “category”. For bigger forms there are many times field groups that are visually separated from each other for example. Now, we treat every form field element the user interacts with, whatsoever, as an “item”, and therefor these “items” will be wraped with `<div class='item'>`. This isolation gives great powers.
|
||||
Next, inside an item, there will typically be an input or select or something of the sort, so they are put inside a `<label>` element, to get rid of the (annoying) for attribute, on the label (which also require us to give an ID to the form field element), and now when a user clicks on the label, the field will get focused. great. Going back to the label’s text itself, we wrap it with a `<span>` to have control over it’s style.
|
||||
|
||||
The whole approach here is to define each form field (input, select, whatever) as much as possible with HTML5 attributes and also with custom attributes.
|
||||
|
||||
| Attribute | Purpose |
|
||||
|----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| required | Defines that this field should be validated (with JS by my implementation and not via native HTML5 browser defaults) |
|
||||
| placeholder | Writes some placeholder text which usually describes the fields with some example input (not supported in IE8 and below) |
|
||||
| pattern | Defines a pattern which the field is evaluated with. Available values are:<br>**numeric** - Allow only numbers<br>**alphanumeric** - Allow only numbers or letters. No special language characters<br>**phone** - Allow only numbers, spaces or dashes.<br><br>Alternatively, you may write your own custom regex here as well. |
|
||||
| data-validate-words | Defines the minimum amount of words for this field |
|
||||
| data-validate-length | Defines the length allowed for the field (after trim). Example value: `7,11` (field can only have 7 or 11 characters). you can add how many allowed lengths you wish |
|
||||
| data-validate-length-range | Defines the minimum and/or maximum number of chars in the field (after trim). value can be `4,8` for example, or just `4` to set minimum chars only |
|
||||
| data-validate-linked | Defines the field which the current field’s value (the attribute is set on) should be compared to |
|
||||
| data-validate-minmax | For type `number` only. Defines the minimum and/or maximum value that can be in that field |
|
||||
|
||||
|
||||
|
||||
|
||||
### Optional fields
|
||||
There is also support for optional fields, which are not validated, unless they have a value. The support for this feature is done by adding a class “optional” to a form element. Note that this should not be done along side the “required” attribute.
|
||||
|
||||
|
||||
|
||||
## Error messages
|
||||
The validator function holds a messages object called "message", which itself holds all the error messages being shown to the user for all sort of validation errors.
|
||||
|
||||
message = {
|
||||
invalid : 'invalid input',
|
||||
empty : 'please put something here',
|
||||
min : 'input is too short',
|
||||
max : 'input is too long',
|
||||
number_min : 'too low',
|
||||
number_max : 'too high',
|
||||
url : 'invalid URL',
|
||||
number : 'not a number',
|
||||
email : 'email address is invalid',
|
||||
email_repeat : 'emails do not match',
|
||||
password_repeat : 'passwords do not match',
|
||||
repeat : 'no match',
|
||||
complete : 'input is not complete',
|
||||
select : 'Please select an option'
|
||||
};
|
||||
|
||||
This object can be extended easily. The idea is to extend it with new keys which represent the name of the field you want the message to be linked to, and that custom message appear as the `general error` one. Default messages can be over-ride.
|
||||
Example: for a given type ‘date’ field, lets set a custom (general error) message like so:
|
||||
`validator.message['date'] = 'not a real date';`
|
||||
|
||||
Error messages can be disabled:
|
||||
`validator.defaults.alerts = false;`
|
||||
|
||||
## Binding the validation to a form
|
||||
|
||||
There are 2 ways to validate form fields, one is on the submit event of the form itself, then all the fields are evaluated one by one. The other method is by binding the ‘checkField’ function itself to each field, for events like “Blur”, “Change” or whatever event you wish (I prefer on Blur).
|
||||
|
||||
###Usage example - validate on submit
|
||||
|
||||
A generic callback function using jQuery to have the form validated on the **Submit** event. You can also include your own personal validations before the **checkAll()** call.
|
||||
|
||||
$('form').submit(function(e){
|
||||
e.preventDefault();
|
||||
var submit = true;
|
||||
// you can put your own custom validations below
|
||||
|
||||
// check all the rerquired fields
|
||||
if( !validator.checkAll( $(this) ) )
|
||||
submit = false;
|
||||
|
||||
if( submit )
|
||||
this.submit();
|
||||
|
||||
return false;
|
||||
})
|
||||
|
||||
###Usage example - validate on field blur event (out of focus)
|
||||
Check every field once it looses focus (onBlur) event
|
||||
|
||||
$('form').on('blur', 'input[required]', validator.checkField);
|
||||
|
||||
## Tooltips
|
||||
|
||||
The helper tooltips **<div class='tooltip help'>**, which work using pure CSS, are element which holds a small **'?'** icon and when hovered over with the mouse, reveals a text explaining what the field “item” is about or for example, what the allowed input format is.
|
||||
|
||||
## Classes
|
||||
`validator.defaults.classes` object can be modified with these classes:
|
||||
|
||||
item : 'item', // class for each input wrapper
|
||||
alert : 'alert', // call on the alert tooltip
|
||||
bad : 'bad' // classes for bad input
|
||||
|
||||
## Bonos – multifields
|
||||
|
||||
I have a cool feature I wrote which I call “multifields”. These are fields which are often use as to input a credit card or a serial number, and are actually a bunch of input fields which are “connected” to each other, and treated as one. You can see it in the demo page, and it’s included in ‘multifield.js’ file.
|
||||
123
vendors/validator/fv.css
vendored
Normal file
123
vendors/validator/fv.css
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
html, body{ height:100%; }
|
||||
/* body min-width is 992px because it's 960px grid + extra 16px from each side of the header */
|
||||
body{ min-width:960px; color:#444; background-color:#F1F1F1; font-size:12px; line-height:1.5em; font-family:Arial, Helvetica, sans-serif; }
|
||||
|
||||
html, body, div, span, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp,
|
||||
small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin:0;
|
||||
padding:0;
|
||||
border:0;
|
||||
vertical-align:baseline;
|
||||
}
|
||||
|
||||
small{ font-size:0.9em; }
|
||||
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display:block;
|
||||
}
|
||||
|
||||
h1{ font-size:2em; margin:0 0 50px 0; }
|
||||
button{ cursor:pointer; }
|
||||
p{ padding:5px 0; }
|
||||
|
||||
a{ text-decoration:none; }
|
||||
.btn{ margin:5px; font-size:1.3em; font-weight:bold; border:2px solid rgba(0,0,0,0.2); display:inline-block; box-shadow:0 -30px 30px -15px #00329B inset, 0 1px 0 rgba(255,255,255,0.3) inset; background:#0088CC; background-repeat:repeat-x; color:#FFF; text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25); border-radius:7px; padding:10px 20px; -webkit-transition:0.15s; transition:0.15s; }
|
||||
.btn:hover{ background:#0068BA; }
|
||||
.btn:active{ box-shadow:0 0 0 0 rgba(0, 0, 0, 0.3), 0 -30px 30px -15px #00329B inset, 0 0 6px #00243F inset; }
|
||||
.btn.github{ float:right; }
|
||||
|
||||
#wrap{ padding:50px; width:860px; background-color:#FFF; margin:20px auto; border:1px dashed #AAA; position:relative; }
|
||||
.options{ position:absolute; top:-1px; right:-1px; background-color:#F1F1F1; padding:4px 0; border-left:1px dashed #AAA; border-bottom:1px dashed #AAA; }
|
||||
.options label{ cursor:pointer; margin:0 10px; }
|
||||
|
||||
input, textarea{ border:1px solid #D1D1D1; }
|
||||
input, select{ font-size:inherit; margin:0; }
|
||||
input:focus, textarea:focus{ border-color:#AAA; }
|
||||
|
||||
input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance:none; margin:0; }
|
||||
input[type=checkbox]{ width:auto; border:none; bottom:-1px; cursor:pointer; margin:2px 8px 0 0; position:relative; transform:scale(1.2); }
|
||||
button[type=submit]{ font-size:1.1em; padding:5px 25px; }
|
||||
|
||||
/* Tooltips helpers */
|
||||
.item .tooltip{ float:left; top:2px; left:7px; position:relative; z-index:2; }
|
||||
.item .tooltip:hover{ z-index:3; }
|
||||
.item .tooltip > span{ display:inline-block; width:15px; height:15px; line-height:15px; font-size:0.9em; font-weight:bold; text-align:center; color:#FFF; cursor:help; background-color:#00AEEF; position:relative; border-radius:10px; }
|
||||
.item .tooltip .content{ opacity:0; width:200px; background-color:#333; color:#FFF; font-size:0.9em; position:absolute; top:0; left:20px; padding:8px; border-radius:6px; pointer-events:none; transition:0.2s cubic-bezier(0.1, 0.1, 0.25, 2); -webkit-transition:0.3s cubic-bezier(0.1, 0.2, 0.5, 2.2); -moz-transition:0.3s cubic-bezier(0.1, 0.2, 0.5, 2.2); }
|
||||
.item .tooltip p{ padding:0; }
|
||||
.item .tooltip.down .content{ left:auto; right:0; top:30px; }
|
||||
.item .tooltip:hover .content{ opacity:1; left:36px; }
|
||||
.item .tooltip .content b{ height:0; width:0; border-color:#333 #333 transparent transparent; border-style:solid; border-width:9px 7px; position:absolute; left:-14px; top:8px; }
|
||||
.item .tooltip.down .content b{ left:auto; right:6px; top:-10px; border-width:5px; border-color:transparent #333 #333 transparent; }
|
||||
|
||||
/* alerts (when validation fails) */
|
||||
.item .alert{ float:left; margin:-2px 0 0 20px; padding:3px 10px; color:#FFF; border-radius:3px 4px 4px 3px; background-color:#CE5454; max-width:170px; white-space:pre; position:relative; left:-15px; opacity:0; z-index:1; transition:0.15s ease-out; }
|
||||
.item .alert::after{ content:''; display:block; height:0; width:0; border-color:transparent #CE5454 transparent transparent; border-style:solid; border-width:11px 7px; position:absolute; left:-13px; top:1px; }
|
||||
.item.bad .alert{ left:0; opacity:1; }
|
||||
|
||||
|
||||
@keyframes shake{
|
||||
15%{ transform:translateX(-5px); }
|
||||
30%{ transform:translateX(5px); }
|
||||
45%{ transform:translateX(-3px); }
|
||||
60%{ transform:translateX(3px); }
|
||||
75%{ transform:translateX(2px); }
|
||||
100%{ transform:none; }
|
||||
}
|
||||
@-webkit-keyframes shake{
|
||||
25%{ -webkit-transform:translateX(-6px); }
|
||||
75%{ -webkit-transform:translateX(6px); }
|
||||
}
|
||||
|
||||
form fieldset{ clear:both; margin:0 0 10px 0; }
|
||||
form .item{ padding:5px 0; position:relative; height:2em; }
|
||||
form .item.items{ height:auto; }
|
||||
.item label, .item .label{ float:left; cursor:pointer; }
|
||||
.item label span, .item .label{ float:left; width:160px; text-transform:capitalize; line-height:2em; }
|
||||
.item input, .item textarea{ float:left; padding:3px 4px; width:210px; -webkit-transition:0.2s; -moz-transition:0.2s; transition:0.2s; }
|
||||
.item input[type=checkbox]{ width:auto; }
|
||||
|
||||
.label ~ label{ vertical-align:middle; margin:0.3em 1.2em 0 0; }
|
||||
|
||||
.item input.short{ width:90px; }
|
||||
.item input:focus:not([type="checkbox"]), .item textarea:focus{ box-shadow:0 0 4px #00AEEF; border:1px solid #00AEEF; }
|
||||
.item textarea{ }
|
||||
.item select{ float:left; width:220px; padding:2px 0; margin:0; border:1px solid #CCC; text-transform:capitalize; }
|
||||
.item select option{ padding:1px; }
|
||||
|
||||
.item > .extra{ float:left; font-size:0.9em; color:#999; line-height:2em; margin-left:13px; }
|
||||
|
||||
.item.multi .input{ float:left; }
|
||||
.item.multi input{ float:left; margin-right:5px; width:35px; text-align:center; }
|
||||
form .item.multi input:nth-last-child(-n+2){ margin:0; }
|
||||
.item.items input{ border-top:5px solid #E1E1E1; margin:0 0 0 160px; }
|
||||
|
||||
.bad input,
|
||||
.bad select,
|
||||
.bad textarea{ border:1px solid #CE5454; box-shadow:0 0 4px -2px #CE5454; position:relative; left:0; -moz-animation:.7s 1 shake linear; -webkit-animation:0.7s 1 shake linear; }
|
||||
|
||||
|
||||
/* mode2 - where the label's text is above the field and not next to it
|
||||
--------------------------------------------------------------------------- */
|
||||
.mode2 .item{ float:left; clear:left; margin-bottom:30px; height:auto; padding:0; zoom:1; }
|
||||
.mode2 .item.bad{ margin-bottom:8px; }
|
||||
.mode2 .item::before, .mode2 .item::after{ content:''; display:table; }
|
||||
.mode2 .item::after{ clear:both; }
|
||||
.mode2 .item label{ }
|
||||
.mode2 .item label span{ float:none; display:block; line-height:inherit; }
|
||||
.mode2 .item input:not(type="checkbox"), .item textarea{ width:250px; margin:0; }
|
||||
.mode2 .item textarea{ width:350px; margin:0; }
|
||||
.mode2 .item select{ width:260px; float:none; }
|
||||
.mode2 .item.multi label{ float:none; }
|
||||
.mode2 .item.multi input{ float:left; margin-right:5px; width:35px; text-align:center; }
|
||||
.mode2 .item .tooltip{ left:auto; position:absolute; right:-22px; top:19px; }
|
||||
.mode2 .item .alert::after{ display:none; }
|
||||
.mode2 .item .alert{ float:none; clear:left; margin:0; padding:0 5px; border-radius:0 0 3px 3px; max-width:100%; height:22px; line-height:1.8em; }
|
||||
.mode2 .item > .extra{ position:absolute; right:0; }
|
||||
258
vendors/validator/index.html
vendored
Normal file
258
vendors/validator/index.html
vendored
Normal file
@@ -0,0 +1,258 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Total Form Validation</title>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no">
|
||||
<link rel="stylesheet" href="fv.css" type="text/css" />
|
||||
<!--[if IE]>
|
||||
<style>
|
||||
.item .tooltip .content{ display:none; opacity:1; }
|
||||
.item .tooltip:hover .content{ display:block; }
|
||||
</style>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<a class='btn github' href='https://github.com/yairEO/validator'>Github</a>
|
||||
<div id='wrap'>
|
||||
<div class='options'>
|
||||
<label>
|
||||
<input type='checkbox' id='vfields' />
|
||||
Vertical orientation
|
||||
</label>
|
||||
<label>
|
||||
<input type='checkbox' id='alerts' />
|
||||
Disable alerts
|
||||
</label>
|
||||
</div>
|
||||
<h1 title='how forms should be done.'>Forms: validation, styling & semantics</h1>
|
||||
<section class='form'>
|
||||
<form action="" method="post" novalidate>
|
||||
<fieldset>
|
||||
<div class="item">
|
||||
<label>
|
||||
<span>Name</span>
|
||||
<input data-validate-length-range="6" data-validate-words="2" name="name" placeholder="ex. John f. Kennedy" required="required" />
|
||||
</label>
|
||||
<div class='tooltip help'>
|
||||
<span>?</span>
|
||||
<div class='content'>
|
||||
<b></b>
|
||||
<p>Name must be at least 2 words</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>
|
||||
<span>Occupation</span>
|
||||
<input class='optional' name="occupation" data-validate-length-range="5,20" type="text" />
|
||||
</label>
|
||||
<div class='tooltip help'>
|
||||
<span>?</span>
|
||||
<div class='content'>
|
||||
<b></b>
|
||||
<p>An optional field. This field is only validated when it has a value.<br /><em>Minimum 5 chars for this example.</em></p>
|
||||
</div>
|
||||
</div>
|
||||
<span class='extra'>(optional)</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>
|
||||
<span>HTML5 Regex</span>
|
||||
<!--<input required="required" type="text" pattern='\d+' />-->
|
||||
<input type="text" data-validate-length-range="2,6" required="required" placeholder="eg. 123456" pattern="alphanumeric" />
|
||||
</label>
|
||||
<div class='tooltip help'>
|
||||
<span>?</span>
|
||||
<div class='content'>
|
||||
<b></b>
|
||||
<p>This field uses HTML5 "pattern" attribute to be validated.<br /><em>"<strong>\d+</strong>" - only digits are allowed</em></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>
|
||||
<span>email</span>
|
||||
<input name="email" class='email' required="required" type="email" />
|
||||
</label>
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>
|
||||
<span>Confirm email address</span>
|
||||
<input type="email" class='email' name="confirm_email" data-validate-linked='email' required='required'>
|
||||
</label>
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>
|
||||
<span>Number</span>
|
||||
<input type="number" class='number' name="number" data-validate-minmax="10,100" required='required'>
|
||||
</label>
|
||||
<div class='tooltip help'>
|
||||
<span>?</span>
|
||||
<div class='content'>
|
||||
<b></b>
|
||||
<p>Number must be between 10 and 100</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>
|
||||
<span>Date</span>
|
||||
<input class='date' type="date" name="date" required='required'>
|
||||
</label>
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>
|
||||
<span>Password</span>
|
||||
<input type="password" name="password" data-validate-length="6,8" required='required'>
|
||||
</label>
|
||||
<div class='tooltip help'>
|
||||
<span>?</span>
|
||||
<div class='content'>
|
||||
<b></b>
|
||||
<p>Should be of length 6 OR 8 characters</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>
|
||||
<span>Repeat password</span>
|
||||
<input type="password" name="password2" data-validate-linked='password' required='required'>
|
||||
</label>
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>
|
||||
<span>Telephone</span>
|
||||
<input type="tel" class='tel' name="phone" required='required' data-validate-length-range="8,20">
|
||||
</label>
|
||||
<div class='tooltip help'>
|
||||
<span>?</span>
|
||||
<div class='content'>
|
||||
<b></b>
|
||||
<p>Notice that for a phone number user can input a '+' sign, a dash '-' or a space ' '</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>
|
||||
<span>Drop down selection</span>
|
||||
<select class="required" name="dropdown">
|
||||
<option value="">-- none --</option>
|
||||
<option value="o1">Option 1</option>
|
||||
<option value="o2">Option 2</option>
|
||||
<option value="o3">Option 3</option>
|
||||
</select>
|
||||
</label>
|
||||
<div class='tooltip help'>
|
||||
<span>?</span>
|
||||
<div class='content'>
|
||||
<b></b>
|
||||
<p>Choose something or choose not. what shall it be?</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>
|
||||
<span>url</span>
|
||||
<input name="url" placeholder="http://www.website.com" required="required" type="url" />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="item">
|
||||
<label>
|
||||
<span>Checkboxes</span>
|
||||
<label><input required="required" type="checkbox" />I agree</label>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="item multi required">
|
||||
<label for='multi_first'>
|
||||
<span>Multifield</span>
|
||||
</label>
|
||||
<div class='input'>
|
||||
<input type="text" name="multi1" maxlength='4' id='multi_first'>
|
||||
<input type="text" name="multi2" maxlength='4'>
|
||||
<input type="text" name="multi3" maxlength='4'>
|
||||
<input type="text" name="multi4" maxlength='4'>
|
||||
<input type="text" name="multi5" maxlength='4'>
|
||||
<input type="text" name="multi6" maxlength='4'>
|
||||
<input data-validate-length-range="24" data-validate-pattern="alphanumeric" id="serial" name="serial" type="hidden" required='required' />
|
||||
</div>
|
||||
<div class='tooltip help'>
|
||||
<span>?</span>
|
||||
<div class='content'>
|
||||
<b></b>
|
||||
<p>This is a multifield, which let the user input a serial number or credit card number for example, and the trick is to validate the combined result, which is stored in a hidden field</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>
|
||||
<span>File upload</span>
|
||||
<input type='file' required>
|
||||
</label>
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>
|
||||
<span>message</span>
|
||||
<textarea required="required" name='message'></textarea>
|
||||
</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<p>There is a hidden "Required" form field below, notice it will not be validated due to its lack of visibility. The reason for this is that sometimes there is a section in a form that is not visible until some action is taken, but you do not want to change all those fields' "required" attributes on-the-fly, so that is why.</p>
|
||||
<input name="somethingHidden" required="required" type="text" style='display:none' />
|
||||
</fieldset>
|
||||
<button id='send' type='submit'>Submit</button>
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
||||
<script src="multifield.js"></script>
|
||||
<script src="validator.js"></script>
|
||||
<script>
|
||||
// initialize the validator function
|
||||
validator.message['date'] = 'not a real date';
|
||||
|
||||
// validate a field on "blur" event, a 'select' on 'change' event & a '.reuired' classed multifield on 'keyup':
|
||||
$('form')
|
||||
.on('blur', 'input[required], input.optional, select.required', validator.checkField)
|
||||
.on('change', 'select.required', validator.checkField)
|
||||
.on('keypress', 'input[required][pattern]', validator.keypress);
|
||||
|
||||
$('.multi.required')
|
||||
.on('keyup blur', 'input', function(){
|
||||
validator.checkField.apply( $(this).siblings().last()[0] );
|
||||
});
|
||||
|
||||
// bind the validation to the form submit event
|
||||
//$('#send').click('submit');//.prop('disabled', true);
|
||||
|
||||
$('form').submit(function(e){
|
||||
e.preventDefault();
|
||||
var submit = true;
|
||||
|
||||
// Validate the form using generic validaing
|
||||
if( !validator.checkAll( $(this) ) ){
|
||||
submit = false;
|
||||
}
|
||||
|
||||
if( submit )
|
||||
this.submit();
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
/* FOR DEMO ONLY */
|
||||
$('#vfields').change(function(){
|
||||
$('form').toggleClass('mode2');
|
||||
}).prop('checked',false);
|
||||
|
||||
$('#alerts').change(function(){
|
||||
validator.defaults.alerts = (this.checked) ? false : true;
|
||||
if( this.checked )
|
||||
$('form .alert').remove();
|
||||
}).prop('checked',false);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
60
vendors/validator/multifield.js
vendored
Normal file
60
vendors/validator/multifield.js
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// multifield - connects several input fields to each-other
|
||||
// By Yair Even Or / 2011 / dropthebit.com
|
||||
;(function(){
|
||||
var fixedEvent = 0;
|
||||
|
||||
function funnel(e){
|
||||
fixedEvent++;
|
||||
var that = this;
|
||||
setTimeout(function(){
|
||||
keypress.call(that, e);
|
||||
fixedEvent = 0;
|
||||
},0);
|
||||
}
|
||||
|
||||
function keypress(e){
|
||||
var nextPrevField,
|
||||
sel = [this.selectionStart, this.selectionEnd];
|
||||
|
||||
if( !e.charCode && e.keyCode != 37 && e.keyCode != 39 && e.keyCode != 8 )
|
||||
return;
|
||||
|
||||
// if hit Backspace key when caret was at the beginning, or if the 'left' arrow key was pressed and the caret was at the start -> go back to previous field
|
||||
if( (e.keyCode == 8 && sel[1] == 0) || (e.keyCode == 37 && sel[1] == 0) )
|
||||
setCaret( $(this).prev(':text')[0], 100);
|
||||
|
||||
// if the 'right' arrow key was pressed and caret was at the end -> advance to the next field
|
||||
else if( e.keyCode == 39 && sel[1] == this.value.length )
|
||||
setCaret( $(this).next(':text')[0], 0);
|
||||
|
||||
// automatically move to the next field once user has filled the current one completely
|
||||
else if( e.charCode && sel[1] == sel[0] && sel[0] == this.maxLength )
|
||||
setCaret( $(this).next(':text')[0], 100);
|
||||
|
||||
function setCaret(input, pos){
|
||||
if( !input ) return;
|
||||
if (input.setSelectionRange){
|
||||
input.focus();
|
||||
input.setSelectionRange(pos, pos);
|
||||
}
|
||||
else if( input.createTextRange ){
|
||||
var range = input.createTextRange();
|
||||
range.collapse(true);
|
||||
range.moveEnd('character', pos);
|
||||
range.moveStart('character', pos);
|
||||
range.select();
|
||||
}
|
||||
}
|
||||
|
||||
combine.apply(this);
|
||||
};
|
||||
// After each 'change' event of any of the fields, combine all the values to the hidden input.
|
||||
function combine(){
|
||||
var hidden = $(this).siblings('input[type=hidden]').val('')[0];
|
||||
$(this.parentNode).find(':text').each( function(){
|
||||
hidden.value += this.value;
|
||||
});
|
||||
}
|
||||
|
||||
$('div.multi').on({'keydown.multifeild':funnel, 'keypress.multifeild':funnel, 'change.multifeild':combine}, 'input');
|
||||
})();
|
||||
30
vendors/validator/validator.jquery.json
vendored
Normal file
30
vendors/validator/validator.jquery.json
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "validator",
|
||||
"title": "validator",
|
||||
"description": "The Validator is cross-browser and will give you the power to use future-proof input types such as 'tel', 'email', 'number', 'date', and 'url'. I can sum this as a 'template' for creating web forms. It uses the power of custom 'data' to achieve high flexibility",
|
||||
"keywords": ["validator", "validation", "form", "input"],
|
||||
"version": "1.0.6",
|
||||
"author": {
|
||||
"name": "Yair Even Or",
|
||||
"url": "http://dropthebit.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Yair Even Or",
|
||||
"email": "vsync.design@gmail.com"
|
||||
}
|
||||
],
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT",
|
||||
"url": "http://opensource.org/licenses/MIT"
|
||||
}
|
||||
],
|
||||
"bugs": "https://github.com/yairEO/validator/issues",
|
||||
"homepage": "https://github.com/yairEO/validator",
|
||||
"docs": "https://github.com/yairEO/validator",
|
||||
"download": "https://github.com/yairEO/validator",
|
||||
"dependencies": {
|
||||
"jquery": ">=1.5"
|
||||
}
|
||||
}
|
||||
411
vendors/validator/validator.js
vendored
Normal file
411
vendors/validator/validator.js
vendored
Normal file
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
Validator v1.1.0
|
||||
(c) Yair Even Or
|
||||
https://github.com/yairEO/validator
|
||||
|
||||
MIT-style license.
|
||||
*/
|
||||
|
||||
var validator = (function($){
|
||||
var message, tests, checkField, validate, mark, unmark, field, minmax, defaults,
|
||||
validateWords, lengthRange, lengthLimit, pattern, alertTxt, data,
|
||||
email_illegalChars = /[\(\)\<\>\,\;\:\\\/\"\[\]]/,
|
||||
email_filter = /^.+@.+\..{2,6}$/; // exmaple email "steve@s-i.photo"
|
||||
|
||||
/* general text messages
|
||||
*/
|
||||
message = {
|
||||
invalid : 'invalid input',
|
||||
checked : 'must be checked',
|
||||
empty : 'please put something here',
|
||||
min : 'input is too short',
|
||||
max : 'input is too long',
|
||||
number_min : 'too low',
|
||||
number_max : 'too high',
|
||||
url : 'invalid URL',
|
||||
number : 'not a number',
|
||||
email : 'email address is invalid',
|
||||
email_repeat : 'emails do not match',
|
||||
password_repeat : 'passwords do not match',
|
||||
repeat : 'no match',
|
||||
complete : 'input is not complete',
|
||||
select : 'Please select an option'
|
||||
};
|
||||
|
||||
if(!window.console){
|
||||
console={};
|
||||
console.log=console.warn=function(){ return; }
|
||||
}
|
||||
|
||||
// defaults
|
||||
defaults = {
|
||||
alerts : true,
|
||||
classes : {
|
||||
item : 'item',
|
||||
alert : 'alert',
|
||||
bad : 'bad'
|
||||
}
|
||||
};
|
||||
|
||||
/* Tests for each type of field (including Select element)
|
||||
*/
|
||||
tests = {
|
||||
sameAsPlaceholder : function(a){
|
||||
return $.fn.placeholder && a.attr('placeholder') !== undefined && data.val == a.prop('placeholder');
|
||||
},
|
||||
hasValue : function(a){
|
||||
if( !a ){
|
||||
alertTxt = message.empty;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 'linked' is a special test case for inputs which their values should be equal to each other (ex. confirm email or retype password)
|
||||
linked : function(a,b){
|
||||
if( b != a ){
|
||||
// choose a specific message or a general one
|
||||
alertTxt = message[data.type + '_repeat'] || message.no_match;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
email : function(a){
|
||||
if ( !email_filter.test( a ) || a.match( email_illegalChars ) ){
|
||||
alertTxt = a ? message.email : message.empty;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// a "skip" will skip some of the tests (needed for keydown validation)
|
||||
text : function(a, skip){
|
||||
// make sure there are at least X number of words, each at least 2 chars long.
|
||||
// for example 'john F kenedy' should be at least 2 words and will pass validation
|
||||
if( validateWords ){
|
||||
var words = a.split(' ');
|
||||
// iterrate on all the words
|
||||
var wordsLength = function(len){
|
||||
for( var w = words.length; w--; )
|
||||
if( words[w].length < len )
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
if( words.length < validateWords || !wordsLength(2) ){
|
||||
alertTxt = message.complete;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if( !skip && lengthRange && a.length < lengthRange[0] ){
|
||||
alertTxt = message.min;
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if there is max length & field length is greater than the allowed
|
||||
if( lengthRange && lengthRange[1] && a.length > lengthRange[1] ){
|
||||
alertTxt = message.max;
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if the field's value should obey any length limits, and if so, make sure the length of the value is as specified
|
||||
if( lengthLimit && lengthLimit.length ){
|
||||
while( lengthLimit.length ){
|
||||
if( lengthLimit.pop() == a.length ){
|
||||
alertTxt = message.complete;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( pattern ){
|
||||
var regex, jsRegex;
|
||||
switch( pattern ){
|
||||
case 'alphanumeric' :
|
||||
regex = /^[a-zA-Z0-9]+$/i;
|
||||
break;
|
||||
case 'numeric' :
|
||||
regex = /^[0-9]+$/i;
|
||||
break;
|
||||
case 'phone' :
|
||||
regex = /^\+?([0-9]|[-|' '])+$/i;
|
||||
break;
|
||||
default :
|
||||
regex = pattern;
|
||||
}
|
||||
try{
|
||||
jsRegex = new RegExp(regex).test(a);
|
||||
if( a && !jsRegex )
|
||||
return false;
|
||||
}
|
||||
catch(err){
|
||||
console.log(err, field, 'regex is invalid');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
number : function(a){
|
||||
// if not not a number
|
||||
if( isNaN(parseFloat(a)) && !isFinite(a) ){
|
||||
alertTxt = message.number;
|
||||
return false;
|
||||
}
|
||||
// not enough numbers
|
||||
else if( lengthRange && a.length < lengthRange[0] ){
|
||||
alertTxt = message.min;
|
||||
return false;
|
||||
}
|
||||
// check if there is max length & field length is greater than the allowed
|
||||
else if( lengthRange && lengthRange[1] && a.length > lengthRange[1] ){
|
||||
alertTxt = message.max;
|
||||
return false;
|
||||
}
|
||||
else if( minmax[0] && (a|0) < minmax[0] ){
|
||||
alertTxt = message.number_min;
|
||||
return false;
|
||||
}
|
||||
else if( minmax[1] && (a|0) > minmax[1] ){
|
||||
alertTxt = message.number_max;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// Date is validated in European format (day,month,year)
|
||||
date : function(a){
|
||||
var day, A = a.split(/[-./]/g), i;
|
||||
// if there is native HTML5 support:
|
||||
if( field[0].valueAsNumber )
|
||||
return true;
|
||||
|
||||
for( i = A.length; i--; ){
|
||||
if( isNaN(parseFloat(a)) && !isFinite(a) )
|
||||
return false;
|
||||
}
|
||||
try{
|
||||
day = new Date(A[2], A[1]-1, A[0]);
|
||||
if( day.getMonth()+1 == A[1] && day.getDate() == A[0] )
|
||||
return day;
|
||||
return false;
|
||||
}
|
||||
catch(er){
|
||||
console.log('date test: ', err);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
url : function(a){
|
||||
// minimalistic URL validation
|
||||
function testUrl(url){
|
||||
return /^(https?:\/\/)?([\w\d\-_]+\.+[A-Za-z]{2,})+\/?/.test( url );
|
||||
}
|
||||
if( !testUrl( a ) ){
|
||||
alertTxt = a ? message.url : message.empty;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
hidden : function(a){
|
||||
if( lengthRange && a.length < lengthRange[0] ){
|
||||
alertTxt = message.min;
|
||||
return false;
|
||||
}
|
||||
if( pattern ){
|
||||
var regex;
|
||||
if( pattern == 'alphanumeric' ){
|
||||
regex = /^[a-z0-9]+$/i;
|
||||
if( !regex.test(a) ){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
select : function(a){
|
||||
if( !tests.hasValue(a) ){
|
||||
alertTxt = message.select;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/* marks invalid fields
|
||||
*/
|
||||
mark = function( field, text ){
|
||||
if( !text || !field || !field.length )
|
||||
return false;
|
||||
|
||||
// check if not already marked as a 'bad' record and add the 'alert' object.
|
||||
// if already is marked as 'bad', then make sure the text is set again because i might change depending on validation
|
||||
var item = field.closest('.' + defaults.classes.item),
|
||||
warning;
|
||||
|
||||
if( item.hasClass(defaults.classes.bad) ){
|
||||
if( defaults.alerts )
|
||||
item.find('.'+defaults.classes.alert).html(text);
|
||||
}
|
||||
|
||||
|
||||
else if( defaults.alerts ){
|
||||
warning = $('<div class="'+ defaults.classes.alert +'">').html( text );
|
||||
item.append( warning );
|
||||
}
|
||||
|
||||
item.removeClass(defaults.classes.bad);
|
||||
// a delay so the "alert" could be transitioned via CSS
|
||||
setTimeout(function(){
|
||||
item.addClass(defaults.classes.bad);
|
||||
}, 0);
|
||||
};
|
||||
/* un-marks invalid fields
|
||||
*/
|
||||
unmark = function( field ){
|
||||
if( !field || !field.length ){
|
||||
console.warn('no "field" argument, null or DOM object not found');
|
||||
return false;
|
||||
}
|
||||
|
||||
field.closest('.' + defaults.classes.item)
|
||||
.removeClass(defaults.classes.bad)
|
||||
.find('.'+ defaults.classes.alert).remove();
|
||||
};
|
||||
|
||||
function testByType(type, value){
|
||||
if( type == 'tel' )
|
||||
pattern = pattern || 'phone';
|
||||
|
||||
if( !type || type == 'password' || type == 'tel' || type == 'search' || type == 'file' )
|
||||
type = 'text';
|
||||
|
||||
|
||||
return tests[type] ? tests[type](value, true) : true;
|
||||
}
|
||||
|
||||
function prepareFieldData(el){
|
||||
field = $(el);
|
||||
|
||||
field.data( 'valid', true ); // initialize validity of field
|
||||
field.data( 'type', field.attr('type') ); // every field starts as 'valid=true' until proven otherwise
|
||||
pattern = field.attr('pattern');
|
||||
}
|
||||
|
||||
/* Validations per-character keypress
|
||||
*/
|
||||
function keypress(e){
|
||||
prepareFieldData(this);
|
||||
// String.fromCharCode(e.charCode)
|
||||
|
||||
if( e.charCode ){
|
||||
return testByType( this.type, this.value );
|
||||
}
|
||||
}
|
||||
|
||||
/* Checks a single form field by it's type and specific (custom) attributes
|
||||
*/
|
||||
function checkField(){
|
||||
// skip testing fields whom their type is not HIDDEN but they are HIDDEN via CSS.
|
||||
if( this.type !='hidden' && $(this).is(':hidden') )
|
||||
return true;
|
||||
|
||||
prepareFieldData(this);
|
||||
|
||||
field.data( 'val', field[0].value.replace(/^\s+|\s+$/g, "") ); // cache the value of the field and trim it
|
||||
data = field.data();
|
||||
|
||||
// Check if there is a specific error message for that field, if not, use the default 'invalid' message
|
||||
alertTxt = message[field.prop('name')] || message.invalid;
|
||||
|
||||
// Special treatment
|
||||
if( field[0].nodeName.toLowerCase() === "select" ){
|
||||
data.type = 'select';
|
||||
}
|
||||
else if( field[0].nodeName.toLowerCase() === "textarea" ){
|
||||
data.type = 'text';
|
||||
}
|
||||
/* Gather Custom data attributes for specific validation:
|
||||
*/
|
||||
validateWords = data['validateWords'] || 0;
|
||||
lengthRange = data['validateLengthRange'] ? (data['validateLengthRange']+'').split(',') : [1];
|
||||
lengthLimit = data['validateLength'] ? (data['validateLength']+'').split(',') : false;
|
||||
minmax = data['validateMinmax'] ? (data['validateMinmax']+'').split(',') : ''; // for type 'number', defines the minimum and/or maximum for the value as a number.
|
||||
|
||||
data.valid = tests.hasValue(data.val);
|
||||
|
||||
if( field.hasClass('optional') && !data.valid )
|
||||
data.valid = true;
|
||||
|
||||
|
||||
// for checkboxes
|
||||
if( field[0].type === "checkbox" ){
|
||||
data.valid = field[0].checked;
|
||||
alertTxt = message.checked;
|
||||
}
|
||||
|
||||
// check if field has any value
|
||||
else if( data.valid ){
|
||||
/* Validate the field's value is different than the placeholder attribute (and attribute exists)
|
||||
* this is needed when fixing the placeholders for older browsers which does not support them.
|
||||
* in this case, make sure the "placeholder" jQuery plugin was even used before proceeding
|
||||
*/
|
||||
if( tests.sameAsPlaceholder(field) ){
|
||||
alertTxt = message.empty;
|
||||
data.valid = false;
|
||||
}
|
||||
|
||||
// if this field is linked to another field (their values should be the same)
|
||||
if( data.validateLinked ){
|
||||
var linkedTo = data['validateLinked'].indexOf('#') == 0 ? $(data['validateLinked']) : $(':input[name=' + data['validateLinked'] + ']');
|
||||
data.valid = tests.linked( data.val, linkedTo.val() );
|
||||
}
|
||||
/* validate by type of field. use 'attr()' is proffered to get the actual value and not what the browsers sees for unsupported types.
|
||||
*/
|
||||
else if( data.valid || data.type == 'select' )
|
||||
data.valid = testByType(data.type, data.val);
|
||||
|
||||
}
|
||||
|
||||
// mark / unmark the field, and set the general 'submit' flag accordingly
|
||||
if( data.valid )
|
||||
unmark( field );
|
||||
else{
|
||||
mark( field, alertTxt );
|
||||
submit = false;
|
||||
}
|
||||
|
||||
return data.valid;
|
||||
}
|
||||
|
||||
/* vaildates all the REQUIRED fields prior to submiting the form
|
||||
*/
|
||||
function checkAll( $form ){
|
||||
$form = $($form);
|
||||
|
||||
if( $form.length == 0 ){
|
||||
console.warn('element not found');
|
||||
return false;
|
||||
}
|
||||
|
||||
var that = this,
|
||||
submit = true, // save the scope
|
||||
// get all the input/textareas/select fields which are required or optional (meaning, they need validation only if they were filled)
|
||||
fieldsToCheck = $form.find(':input').filter('[required=required], .required, .optional').not('[disabled=disabled]');
|
||||
|
||||
fieldsToCheck.each(function(){
|
||||
// use an AND operation, so if any of the fields returns 'false' then the submitted result will be also FALSE
|
||||
submit = submit * checkField.apply(this);
|
||||
});
|
||||
|
||||
return !!submit; // casting the variable to make sure it's a boolean
|
||||
}
|
||||
|
||||
return {
|
||||
defaults : defaults,
|
||||
checkField : checkField,
|
||||
keypress : keypress,
|
||||
checkAll : checkAll,
|
||||
mark : mark,
|
||||
unmark : unmark,
|
||||
message : message,
|
||||
tests : tests
|
||||
}
|
||||
})(jQuery);
|
||||
Reference in New Issue
Block a user