upgraded validator plug-in

This commit is contained in:
pratik 2020-01-06 17:13:26 +05:30
parent f0106934c9
commit 4fb515d0b7
13 changed files with 1275 additions and 6947 deletions

View File

@ -50,7 +50,7 @@
"jquery.inputmask": "^3.3.1",
"jquery-knob": "^1.2.13",
"cropper": "^2.3.0",
"validator": "https://github.com/yairEO/validator.git#^1.0.6",
"validator": "https://github.com/yairEO/validator.git#^3.3.5",
"jQuery-Smart-Wizard": "^3.3.1",
"dropzone": "^4.3.0",
"pnotify": "^3.0.0",

5948
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -33,10 +33,10 @@
"devDependencies": {
"browser-sync": "^2.26.7",
"gulp": "^4.0.2",
"gulp-autoprefixer": "^3.1.0",
"gulp-concat": "^2.6.0",
"gulp-rename": "^1.4.0",
"gulp-ruby-sass": "^2.0.6",
"gulp-uglify": "^1.5.3"
"gulp-autoprefixer": "^7.0.1",
"gulp-concat": "^2.6.1",
"gulp-rename": "^2.0.0",
"gulp-ruby-sass": "^4.0.0",
"gulp-uglify": "^3.0.2"
}
}

View File

@ -1,423 +1,462 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- Meta, title, CSS, favicons, etc. -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Gentelella Alela! | </title>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- Meta, title, CSS, favicons, etc. -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap -->
<link href="../vendors/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Font Awesome -->
<link href="../vendors/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<!-- NProgress -->
<link href="../vendors/nprogress/nprogress.css" rel="stylesheet">
<!-- Custom Theme Style -->
<link href="../build/css/custom.min.css" rel="stylesheet">
</head>
<title>Gentelella Alela! | </title>
<body class="nav-md">
<div class="container body">
<div class="main_container">
<div class="col-md-3 left_col">
<div class="left_col scroll-view">
<div class="navbar nav_title" style="border: 0;">
<a href="index.html" class="site_title"><i class="fa fa-paw"></i> <span>Gentelella Alela!</span></a>
</div>
<!-- Bootstrap -->
<link href="../vendors/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Font Awesome -->
<link href="../vendors/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<!-- NProgress -->
<link href="../vendors/nprogress/nprogress.css" rel="stylesheet">
<div class="clearfix"></div>
<!-- Custom Theme Style -->
<link href="../build/css/custom.min.css" rel="stylesheet">
</head>
<!-- menu profile quick info -->
<div class="profile clearfix">
<div class="profile_pic">
<img src="images/img.jpg" alt="..." class="img-circle profile_img">
</div>
<div class="profile_info">
<span>Welcome,</span>
<h2>John Doe</h2>
</div>
</div>
<!-- /menu profile quick info -->
<br />
<!-- sidebar menu -->
<div id="sidebar-menu" class="main_menu_side hidden-print main_menu">
<div class="menu_section">
<h3>General</h3>
<ul class="nav side-menu">
<li><a><i class="fa fa-home"></i> Home <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a href="index.html">Dashboard</a></li>
<li><a href="index2.html">Dashboard2</a></li>
<li><a href="index3.html">Dashboard3</a></li>
</ul>
</li>
<li><a><i class="fa fa-edit"></i> Forms <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a href="form.html">General Form</a></li>
<li><a href="form_advanced.html">Advanced Components</a></li>
<li><a href="form_validation.html">Form Validation</a></li>
<li><a href="form_wizards.html">Form Wizard</a></li>
<li><a href="form_upload.html">Form Upload</a></li>
<li><a href="form_buttons.html">Form Buttons</a></li>
</ul>
</li>
<li><a><i class="fa fa-desktop"></i> UI Elements <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a href="general_elements.html">General Elements</a></li>
<li><a href="media_gallery.html">Media Gallery</a></li>
<li><a href="typography.html">Typography</a></li>
<li><a href="icons.html">Icons</a></li>
<li><a href="glyphicons.html">Glyphicons</a></li>
<li><a href="widgets.html">Widgets</a></li>
<li><a href="invoice.html">Invoice</a></li>
<li><a href="inbox.html">Inbox</a></li>
<li><a href="calendar.html">Calendar</a></li>
</ul>
</li>
<li><a><i class="fa fa-table"></i> Tables <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a href="tables.html">Tables</a></li>
<li><a href="tables_dynamic.html">Table Dynamic</a></li>
</ul>
</li>
<li><a><i class="fa fa-bar-chart-o"></i> Data Presentation <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a href="chartjs.html">Chart JS</a></li>
<li><a href="chartjs2.html">Chart JS2</a></li>
<li><a href="morisjs.html">Moris JS</a></li>
<li><a href="echarts.html">ECharts</a></li>
<li><a href="other_charts.html">Other Charts</a></li>
</ul>
</li>
<li><a><i class="fa fa-clone"></i>Layouts <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a href="fixed_sidebar.html">Fixed Sidebar</a></li>
<li><a href="fixed_footer.html">Fixed Footer</a></li>
</ul>
</li>
</ul>
</div>
<div class="menu_section">
<h3>Live On</h3>
<ul class="nav side-menu">
<li><a><i class="fa fa-bug"></i> Additional Pages <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a href="e_commerce.html">E-commerce</a></li>
<li><a href="projects.html">Projects</a></li>
<li><a href="project_detail.html">Project Detail</a></li>
<li><a href="contacts.html">Contacts</a></li>
<li><a href="profile.html">Profile</a></li>
</ul>
</li>
<li><a><i class="fa fa-windows"></i> Extras <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a href="page_403.html">403 Error</a></li>
<li><a href="page_404.html">404 Error</a></li>
<li><a href="page_500.html">500 Error</a></li>
<li><a href="plain_page.html">Plain Page</a></li>
<li><a href="login.html">Login Page</a></li>
<li><a href="pricing_tables.html">Pricing Tables</a></li>
</ul>
</li>
<li><a><i class="fa fa-sitemap"></i> Multilevel Menu <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a href="#level1_1">Level One</a>
<li><a>Level One<span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li class="sub_menu"><a href="level2.html">Level Two</a>
</li>
<li><a href="#level2_1">Level Two</a>
</li>
<li><a href="#level2_2">Level Two</a>
</li>
</ul>
</li>
<li><a href="#level1_2">Level One</a>
</li>
</ul>
</li>
<li><a href="javascript:void(0)"><i class="fa fa-laptop"></i> Landing Page <span class="label label-success pull-right">Coming Soon</span></a></li>
</ul>
</div>
</div>
<!-- /sidebar menu -->
<!-- /menu footer buttons -->
<div class="sidebar-footer hidden-small">
<a data-toggle="tooltip" data-placement="top" title="Settings">
<span class="glyphicon glyphicon-cog" aria-hidden="true"></span>
</a>
<a data-toggle="tooltip" data-placement="top" title="FullScreen">
<span class="glyphicon glyphicon-fullscreen" aria-hidden="true"></span>
</a>
<a data-toggle="tooltip" data-placement="top" title="Lock">
<span class="glyphicon glyphicon-eye-close" aria-hidden="true"></span>
</a>
<a data-toggle="tooltip" data-placement="top" title="Logout" href="login.html">
<span class="glyphicon glyphicon-off" aria-hidden="true"></span>
</a>
</div>
<!-- /menu footer buttons -->
<body class="nav-md">
<div class="container body">
<div class="main_container">
<div class="col-md-3 left_col">
<div class="left_col scroll-view">
<div class="navbar nav_title" style="border: 0;">
<a href="index.html" class="site_title"><i class="fa fa-paw"></i> <span>Gentelella Alela!</span></a>
</div>
</div>
<!-- top navigation -->
<div class="top_nav">
<div class="nav_menu">
<div class="nav toggle">
<a id="menu_toggle"><i class="fa fa-bars"></i></a>
<div class="clearfix"></div>
<!-- menu profile quick info -->
<div class="profile clearfix">
<div class="profile_pic">
<img src="images/img.jpg" alt="..." class="img-circle profile_img">
</div>
<div class="profile_info">
<span>Welcome,</span>
<h2>John Doe</h2>
</div>
</div>
<!-- /menu profile quick info -->
<br />
<!-- sidebar menu -->
<div id="sidebar-menu" class="main_menu_side hidden-print main_menu">
<div class="menu_section">
<h3>General</h3>
<ul class="nav side-menu">
<li><a><i class="fa fa-home"></i> Home <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a href="index.html">Dashboard</a></li>
<li><a href="index2.html">Dashboard2</a></li>
<li><a href="index3.html">Dashboard3</a></li>
</ul>
</li>
<li><a><i class="fa fa-edit"></i> Forms <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a href="form.html">General Form</a></li>
<li><a href="form_advanced.html">Advanced Components</a></li>
<li><a href="form_validation.html">Form Validation</a></li>
<li><a href="form_wizards.html">Form Wizard</a></li>
<li><a href="form_upload.html">Form Upload</a></li>
<li><a href="form_buttons.html">Form Buttons</a></li>
</ul>
</li>
<li><a><i class="fa fa-desktop"></i> UI Elements <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a href="general_elements.html">General Elements</a></li>
<li><a href="media_gallery.html">Media Gallery</a></li>
<li><a href="typography.html">Typography</a></li>
<li><a href="icons.html">Icons</a></li>
<li><a href="glyphicons.html">Glyphicons</a></li>
<li><a href="widgets.html">Widgets</a></li>
<li><a href="invoice.html">Invoice</a></li>
<li><a href="inbox.html">Inbox</a></li>
<li><a href="calendar.html">Calendar</a></li>
</ul>
</li>
<li><a><i class="fa fa-table"></i> Tables <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a href="tables.html">Tables</a></li>
<li><a href="tables_dynamic.html">Table Dynamic</a></li>
</ul>
</li>
<li><a><i class="fa fa-bar-chart-o"></i> Data Presentation <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a href="chartjs.html">Chart JS</a></li>
<li><a href="chartjs2.html">Chart JS2</a></li>
<li><a href="morisjs.html">Moris JS</a></li>
<li><a href="echarts.html">ECharts</a></li>
<li><a href="other_charts.html">Other Charts</a></li>
</ul>
</li>
<li><a><i class="fa fa-clone"></i>Layouts <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a href="fixed_sidebar.html">Fixed Sidebar</a></li>
<li><a href="fixed_footer.html">Fixed Footer</a></li>
</ul>
</li>
</ul>
</div>
<div class="menu_section">
<h3>Live On</h3>
<ul class="nav side-menu">
<li><a><i class="fa fa-bug"></i> Additional Pages <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a href="e_commerce.html">E-commerce</a></li>
<li><a href="projects.html">Projects</a></li>
<li><a href="project_detail.html">Project Detail</a></li>
<li><a href="contacts.html">Contacts</a></li>
<li><a href="profile.html">Profile</a></li>
</ul>
</li>
<li><a><i class="fa fa-windows"></i> Extras <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a href="page_403.html">403 Error</a></li>
<li><a href="page_404.html">404 Error</a></li>
<li><a href="page_500.html">500 Error</a></li>
<li><a href="plain_page.html">Plain Page</a></li>
<li><a href="login.html">Login Page</a></li>
<li><a href="pricing_tables.html">Pricing Tables</a></li>
</ul>
</li>
<li><a><i class="fa fa-sitemap"></i> Multilevel Menu <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a href="#level1_1">Level One</a>
<li><a>Level One<span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li class="sub_menu"><a href="level2.html">Level Two</a>
</li>
<li><a href="#level2_1">Level Two</a>
</li>
<li><a href="#level2_2">Level Two</a>
</li>
</ul>
</li>
<li><a href="#level1_2">Level One</a>
</li>
</ul>
</li>
<li><a href="javascript:void(0)"><i class="fa fa-laptop"></i> Landing Page <span
class="label label-success pull-right">Coming Soon</span></a></li>
</ul>
</div>
</div>
<!-- /sidebar menu -->
<!-- /menu footer buttons -->
<div class="sidebar-footer hidden-small">
<a data-toggle="tooltip" data-placement="top" title="Settings">
<span class="glyphicon glyphicon-cog" aria-hidden="true"></span>
</a>
<a data-toggle="tooltip" data-placement="top" title="FullScreen">
<span class="glyphicon glyphicon-fullscreen" aria-hidden="true"></span>
</a>
<a data-toggle="tooltip" data-placement="top" title="Lock">
<span class="glyphicon glyphicon-eye-close" aria-hidden="true"></span>
</a>
<a data-toggle="tooltip" data-placement="top" title="Logout" href="login.html">
<span class="glyphicon glyphicon-off" aria-hidden="true"></span>
</a>
</div>
<!-- /menu footer buttons -->
</div>
</div>
<!-- top navigation -->
<div class="top_nav">
<div class="nav_menu">
<div class="nav toggle">
<a id="menu_toggle"><i class="fa fa-bars"></i></a>
</div>
<nav class="nav navbar-nav">
<ul class=" navbar-right">
<li class="nav-item dropdown open" style="padding-left: 15px;">
<a href="javascript:;" class="user-profile dropdown-toggle" aria-haspopup="true" id="navbarDropdown"
data-toggle="dropdown" aria-expanded="false">
<img src="images/img.jpg" alt="">John Doe
</a>
<div class="dropdown-menu dropdown-usermenu pull-right" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="javascript:;"> Profile</a>
<a class="dropdown-item" href="javascript:;">
<span class="badge bg-red pull-right">50%</span>
<span>Settings</span>
</a>
<a class="dropdown-item" href="javascript:;">Help</a>
<a class="dropdown-item" href="login.html"><i class="fa fa-sign-out pull-right"></i> Log Out</a>
</div>
<nav class="nav navbar-nav">
<ul class=" navbar-right">
<li class="nav-item dropdown open" style="padding-left: 15px;">
<a href="javascript:;" class="user-profile dropdown-toggle" aria-haspopup="true" id="navbarDropdown" data-toggle="dropdown" aria-expanded="false">
<img src="images/img.jpg" alt="">John Doe
</li>
<li role="presentation" class="nav-item dropdown open">
<a href="javascript:;" class="dropdown-toggle info-number" id="navbarDropdown1" data-toggle="dropdown"
aria-expanded="false">
<i class="fa fa-envelope-o"></i>
<span class="badge bg-green">6</span>
</a>
<ul class="dropdown-menu list-unstyled msg_list" role="menu" aria-labelledby="navbarDropdown1">
<li class="nav-item">
<a class="dropdown-item">
<span class="image"><img src="images/img.jpg" alt="Profile Image" /></span>
<span>
<span>John Smith</span>
<span class="time">3 mins ago</span>
</span>
<span class="message">
Film festivals used to be do-or-die moments for movie makers. They were where...
</span>
</a>
<div class="dropdown-menu dropdown-usermenu pull-right" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="javascript:;"> Profile</a>
<a class="dropdown-item" href="javascript:;">
<span class="badge bg-red pull-right">50%</span>
<span>Settings</span>
</a>
<a class="dropdown-item" href="javascript:;">Help</a>
<a class="dropdown-item" href="login.html"><i class="fa fa-sign-out pull-right"></i> Log Out</a>
</li>
<li class="nav-item">
<a class="dropdown-item">
<span class="image"><img src="images/img.jpg" alt="Profile Image" /></span>
<span>
<span>John Smith</span>
<span class="time">3 mins ago</span>
</span>
<span class="message">
Film festivals used to be do-or-die moments for movie makers. They were where...
</span>
</a>
</li>
<li class="nav-item">
<a class="dropdown-item">
<span class="image"><img src="images/img.jpg" alt="Profile Image" /></span>
<span>
<span>John Smith</span>
<span class="time">3 mins ago</span>
</span>
<span class="message">
Film festivals used to be do-or-die moments for movie makers. They were where...
</span>
</a>
</li>
<li class="nav-item">
<a class="dropdown-item">
<span class="image"><img src="images/img.jpg" alt="Profile Image" /></span>
<span>
<span>John Smith</span>
<span class="time">3 mins ago</span>
</span>
<span class="message">
Film festivals used to be do-or-die moments for movie makers. They were where...
</span>
</a>
</li>
<li class="nav-item">
<div class="text-center">
<a class="dropdown-item">
<strong>See All Alerts</strong>
<i class="fa fa-angle-right"></i>
</a>
</div>
</li>
<li role="presentation" class="nav-item dropdown open">
<a href="javascript:;" class="dropdown-toggle info-number" id="navbarDropdown1" data-toggle="dropdown" aria-expanded="false">
<i class="fa fa-envelope-o"></i>
<span class="badge bg-green">6</span>
</a>
<ul class="dropdown-menu list-unstyled msg_list" role="menu" aria-labelledby="navbarDropdown1">
<li class="nav-item">
<a class="dropdown-item">
<span class="image"><img src="images/img.jpg" alt="Profile Image" /></span>
<span>
<span>John Smith</span>
<span class="time">3 mins ago</span>
</span>
<span class="message">
Film festivals used to be do-or-die moments for movie makers. They were where...
</span>
</a>
</li>
<li class="nav-item">
<a class="dropdown-item">
<span class="image"><img src="images/img.jpg" alt="Profile Image" /></span>
<span>
<span>John Smith</span>
<span class="time">3 mins ago</span>
</span>
<span class="message">
Film festivals used to be do-or-die moments for movie makers. They were where...
</span>
</a>
</li>
<li class="nav-item">
<a class="dropdown-item">
<span class="image"><img src="images/img.jpg" alt="Profile Image" /></span>
<span>
<span>John Smith</span>
<span class="time">3 mins ago</span>
</span>
<span class="message">
Film festivals used to be do-or-die moments for movie makers. They were where...
</span>
</a>
</li>
<li class="nav-item">
<a class="dropdown-item">
<span class="image"><img src="images/img.jpg" alt="Profile Image" /></span>
<span>
<span>John Smith</span>
<span class="time">3 mins ago</span>
</span>
<span class="message">
Film festivals used to be do-or-die moments for movie makers. They were where...
</span>
</a>
</li>
<li class="nav-item">
<div class="text-center">
<a class="dropdown-item">
<strong>See All Alerts</strong>
<i class="fa fa-angle-right"></i>
</a>
</div>
</li>
</ul>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
<!-- /top navigation -->
<!-- page content -->
<div class="right_col" role="main">
<div class="">
<div class="page-title">
<div class="title_left">
<h3>Form Validation</h3>
</div>
</div>
<!-- /top navigation -->
<!-- page content -->
<div class="right_col" role="main">
<div class="">
<div class="page-title">
<div class="title_left">
<h3>Form Validation</h3>
</div>
<div class="title_right">
<div class="col-md-5 col-sm-5 form-group pull-right top_search">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search for...">
<span class="input-group-btn">
<button class="btn btn-default" type="button">Go!</button>
</span>
</div>
<div class="title_right">
<div class="col-md-5 col-sm-5 form-group pull-right top_search">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search for...">
<span class="input-group-btn">
<button class="btn btn-default" type="button">Go!</button>
</span>
</div>
</div>
</div>
<div class="clearfix"></div>
</div>
<div class="clearfix"></div>
<div class="row">
<div class="col-md-12 col-sm-12">
<div class="x_panel">
<div class="x_title">
<h2>Form validation <small>sub title</small></h2>
<ul class="nav navbar-right panel_toolbox">
<li><a class="collapse-link"><i class="fa fa-chevron-up"></i></a>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-wrench"></i></a>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="#">Settings 1</a>
<a class="dropdown-item" href="#">Settings 2</a>
</div>
</li>
<li><a class="close-link"><i class="fa fa-close"></i></a>
</li>
</ul>
<div class="clearfix"></div>
</div>
<div class="x_content">
<form class="form-horizontal form-label-left" novalidate>
<p>For alternative validation library <code>parsleyJS</code> check out in the <a href="form.html">form page</a>
</p>
<span class="section">Personal Info</span>
<div class="item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align" for="name">Name <span class="required">*</span>
</label>
<div class="col-md-6 col-sm-6">
<input id="name" class="form-control" data-validate-length-range="6" data-validate-words="2" name="name" placeholder="both name(s) e.g Jon Doe" required="required" type="text">
</div>
<div class="row">
<div class="col-md-12 col-sm-12">
<div class="x_panel">
<div class="x_title">
<h2>Form validation <small>sub title</small></h2>
<ul class="nav navbar-right panel_toolbox">
<li><a class="collapse-link"><i class="fa fa-chevron-up"></i></a>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i
class="fa fa-wrench"></i></a>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="#">Settings 1</a>
<a class="dropdown-item" href="#">Settings 2</a>
</div>
<div class="item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align" for="email">Email <span class="required">*</span>
</label>
<div class="col-md-6 col-sm-6">
<input type="email" id="email" name="email" required="required" class="form-control">
</div>
</li>
<li><a class="close-link"><i class="fa fa-close"></i></a>
</li>
</ul>
<div class="clearfix"></div>
</div>
<div class="x_content">
<form class="" action="" method="post" novalidate>
<p>For alternative validation library <code>parsleyJS</code> check out in the <a
href="form.html">form page</a>
</p>
<span class="section">Personal Info</span>
<div class="field item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align">Name<span
class="required">*</span></label>
<div class="col-md-6 col-sm-6">
<input class="form-control" data-validate-length-range="6" data-validate-words="2" name="name"
placeholder="ex. John f. Kennedy" required="required" />
</div>
<div class="item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align" for="email">Confirm Email <span class="required">*</span>
</label>
<div class="col-md-6 col-sm-6">
<input type="email" id="email2" name="confirm_email" data-validate-linked="email" required="required" class="form-control">
</div>
</div>
<div class="item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align" for="number">Number <span class="required">*</span>
</label>
<div class="col-md-6 col-sm-6">
<input type="number" id="number" name="number" required="required" data-validate-minmax="10,100" class="form-control">
</div>
</div>
<div class="item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align" for="website">Website URL <span class="required">*</span>
</label>
<div class="col-md-6 col-sm-6">
<input type="url" id="website" name="website label-align" required="required" placeholder="www.website.com" class="form-control">
</div>
</div>
<div class="item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align" for="occupation">Occupation <span class="required">*</span>
</label>
<div class="col-md-6 col-sm-6">
<input id="occupation" type="text" name="occupation" data-validate-length-range="5,20" class="optional form-control">
</div>
</div>
<div class="item form-group">
<label for="password" class="col-form-label col-md-3 label-align">Password</label>
<div class="col-md-6 col-sm-6">
<input id="password" type="password" name="password" data-validate-length="6,8" class="form-control" required="required">
</div>
</div>
<div class="item form-group">
<label for="password2" class="col-form-label col-md-3 col-sm-3 label-align ">Repeat Password</label>
<div class="col-md-6 col-sm-6">
<input id="password2" type="password" name="password2" data-validate-linked="password" class="form-control" required="required">
</div>
</div>
<div class="item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align" for="telephone">Telephone <span class="required">*</span>
</label>
<div class="col-md-6 col-sm-6">
<input type="tel" id="telephone" name="phone" required="required" data-validate-length-range="8,20" class="form-control">
</div>
</div>
<div class="item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align" for="textarea">Textarea <span class="required">*</span>
</label>
<div class="col-md-6 col-sm-6">
<textarea id="textarea" required="required" name="textarea" class="form-control"></textarea>
</div>
</div>
<div class="ln_solid"></div>
</div>
<div class="field item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align">Occupation<span
class="required">*</span></label>
<div class="col-md-6 col-sm-6">
<input class="form-control" class='optional' name="occupation" data-validate-length-range="5,15"
type="text" /></div>
</div>
<div class="field item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align">email<span
class="required">*</span></label>
<div class="col-md-6 col-sm-6">
<input class="form-control" name="email" class='email' required="required" type="email" /></div>
</div>
<div class="field item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align">Confirm email address<span
class="required">*</span></label>
<div class="col-md-6 col-sm-6">
<input class="form-control" type="email" class='email' name="confirm_email"
data-validate-linked='email' required='required' /></div>
</div>
<div class="field item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align">Number <span
class="required">*</span></label>
<div class="col-md-6 col-sm-6">
<input class="form-control" type="number" class='number' name="number"
data-validate-minmax="10,100" required='required'></div>
</div>
<div class="field item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align">Date<span
class="required">*</span></label>
<div class="col-md-6 col-sm-6">
<input class="form-control" class='date' type="date" name="date" required='required'></div>
</div>
<div class="field item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align">Time<span
class="required">*</span></label>
<div class="col-md-6 col-sm-6">
<input class="form-control" class='time' type="time" name="time" required='required'></div>
</div>
<div class="field item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align">Password<span
class="required">*</span></label>
<div class="col-md-6 col-sm-6">
<input class="form-control" type="password" name="password" data-validate-length="6,8"
required='required' /></div>
</div>
<div class="field item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align">Repeat password<span
class="required">*</span></label>
<div class="col-md-6 col-sm-6">
<input class="form-control" type="password" name="password2" data-validate-linked='password'
required='required' /></div>
</div>
<div class="field item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align">Telephone<span
class="required">*</span></label>
<div class="col-md-6 col-sm-6">
<input class="form-control" type="tel" class='tel' name="phone" required='required'
data-validate-length-range="8,20" /></div>
</div>
<div class="field item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align">message<span
class="required">*</span></label>
<div class="col-md-6 col-sm-6">
<textarea required="required" name='message'></textarea></div>
</div>
<div class="ln_solid">
<div class="form-group">
<div class="col-md-6 offset-md-3">
<button type="submit" class="btn btn-primary">Cancel</button>
<button id="send" type="submit" class="btn btn-success">Submit</button>
<button type='submit' class="btn btn-primary">Submit</button>
<button type='reset' class="btn btn-success">Reset</button>
</div>
</div>
</form>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- /page content -->
<!-- footer content -->
<footer>
<div class="pull-right">
Gentelella - Bootstrap Admin Template by <a href="https://colorlib.com">Colorlib</a>
</div>
<div class="clearfix"></div>
</footer>
<!-- /footer content -->
</div>
<!-- /page content -->
<!-- footer content -->
<footer>
<div class="pull-right">
Gentelella - Bootstrap Admin Template by <a href="https://colorlib.com">Colorlib</a>
</div>
<div class="clearfix"></div>
</footer>
<!-- /footer content -->
</div>
</div>
<!-- jQuery -->
<script src="../vendors/jquery/dist/jquery.min.js"></script>
<!-- Bootstrap -->
<script src="../vendors/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<!-- FastClick -->
<script src="../vendors/fastclick/lib/fastclick.js"></script>
<!-- NProgress -->
<script src="../vendors/nprogress/nprogress.js"></script>
<!-- validator -->
<script src="../vendors/validator/validator.js"></script>
<!-- Custom Theme Scripts -->
<script src="../build/js/custom.min.js"></script>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="../vendors/validator/multifield.js"></script>
<script src="../vendors/validator/validator.js"></script>
<script>
// initialize a validator instance from the "FormValidator" constructor.
// A "<form>" element is optionally passed as an argument, but is not a must
var validator = new FormValidator({ "events": ['blur', 'input', 'change'] }, document.forms[0]);
// on form "submit" event
document.forms[0].onsubmit = function (e) {
var submit = true,
validatorResult = validator.checkAll(this);
console.log(validatorResult);
return !!validatorResult.valid;
};
// on form "reset" event
document.forms[0].onreset = function (e) {
validator.reset();
};
// stuff related ONLY for this demo page:
$('.toggleValidationTooltips').change(function () {
validator.settings.alerts = !this.checked;
if (this.checked)
$('form .alert').remove();
}).prop('checked', false);
</script>
<!-- jQuery -->
<script src="../vendors/jquery/dist/jquery.min.js"></script>
<!-- Bootstrap -->
<script src="../vendors/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<!-- FastClick -->
<script src="../vendors/fastclick/lib/fastclick.js"></script>
<!-- NProgress -->
<script src="../vendors/nprogress/nprogress.js"></script>
<!-- validator -->
<!-- <script src="../vendors/validator/validator.js"></script> -->
<!-- Custom Theme Scripts -->
<script src="../build/js/custom.min.js"></script>
</body>
</html>

View File

@ -829,7 +829,7 @@
<thead>
<tr>
<th>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</th>
<th>Name</th>
<th>Position</th>
@ -844,7 +844,7 @@
<tbody>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Tiger Nixon</td>
<td>System Architect</td>
@ -855,7 +855,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Garrett Winters</td>
<td>Accountant</td>
@ -866,7 +866,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Ashton Cox</td>
<td>Junior Technical Author</td>
@ -877,7 +877,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Cedric Kelly</td>
<td>Senior Javascript Developer</td>
@ -888,7 +888,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Airi Satou</td>
<td>Accountant</td>
@ -899,7 +899,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Brielle Williamson</td>
<td>Integration Specialist</td>
@ -910,7 +910,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Herrod Chandler</td>
<td>Sales Assistant</td>
@ -921,7 +921,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Rhona Davidson</td>
<td>Integration Specialist</td>
@ -932,7 +932,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Colleen Hurst</td>
<td>Javascript Developer</td>
@ -943,7 +943,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Sonya Frost</td>
<td>Software Engineer</td>
@ -954,7 +954,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Jena Gaines</td>
<td>Office Manager</td>
@ -965,7 +965,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Quinn Flynn</td>
<td>Support Lead</td>
@ -976,7 +976,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Charde Marshall</td>
<td>Regional Director</td>
@ -987,7 +987,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Haley Kennedy</td>
<td>Senior Marketing Designer</td>
@ -998,7 +998,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Tatyana Fitzpatrick</td>
<td>Regional Director</td>
@ -1009,7 +1009,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Michael Silva</td>
<td>Marketing Designer</td>
@ -1020,7 +1020,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Paul Byrd</td>
<td>Chief Financial Officer (CFO)</td>
@ -1031,7 +1031,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Gloria Little</td>
<td>Systems Administrator</td>
@ -1042,7 +1042,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Bradley Greer</td>
<td>Software Engineer</td>
@ -1053,7 +1053,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Dai Rios</td>
<td>Personnel Lead</td>
@ -1064,7 +1064,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Jenette Caldwell</td>
<td>Development Lead</td>
@ -1075,7 +1075,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Yuri Berry</td>
<td>Chief Marketing Officer (CMO)</td>
@ -1086,7 +1086,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Caesar Vance</td>
<td>Pre-Sales Support</td>
@ -1097,7 +1097,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Doris Wilder</td>
<td>Sales Assistant</td>
@ -1108,7 +1108,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Angelica Ramos</td>
<td>Chief Executive Officer (CEO)</td>
@ -1119,7 +1119,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Gavin Joyce</td>
<td>Developer</td>
@ -1130,7 +1130,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Jennifer Chang</td>
<td>Regional Director</td>
@ -1141,7 +1141,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Brenden Wagner</td>
<td>Software Engineer</td>
@ -1152,7 +1152,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Fiona Green</td>
<td>Chief Operating Officer (COO)</td>
@ -1163,7 +1163,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Shou Itou</td>
<td>Regional Marketing</td>
@ -1174,7 +1174,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Michelle House</td>
<td>Integration Specialist</td>
@ -1185,7 +1185,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Suki Burks</td>
<td>Developer</td>
@ -1196,7 +1196,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Prescott Bartlett</td>
<td>Technical Author</td>
@ -1207,7 +1207,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Gavin Cortez</td>
<td>Team Leader</td>
@ -1218,7 +1218,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Martena Mccray</td>
<td>Post-Sales support</td>
@ -1229,7 +1229,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Unity Butler</td>
<td>Marketing Designer</td>
@ -1240,7 +1240,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Howard Hatfield</td>
<td>Office Manager</td>
@ -1251,7 +1251,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Hope Fuentes</td>
<td>Secretary</td>
@ -1262,7 +1262,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Vivian Harrell</td>
<td>Financial Controller</td>
@ -1273,7 +1273,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Timothy Mooney</td>
<td>Office Manager</td>
@ -1284,7 +1284,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Jackson Bradshaw</td>
<td>Director</td>
@ -1295,7 +1295,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Olivia Liang</td>
<td>Support Engineer</td>
@ -1306,7 +1306,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Bruno Nash</td>
<td>Software Engineer</td>
@ -1317,7 +1317,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Sakura Yamamoto</td>
<td>Support Engineer</td>
@ -1328,7 +1328,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Thor Walton</td>
<td>Developer</td>
@ -1339,7 +1339,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Finn Camacho</td>
<td>Support Engineer</td>
@ -1350,7 +1350,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Serge Baldwin</td>
<td>Data Coordinator</td>
@ -1361,7 +1361,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Zenaida Frank</td>
<td>Software Engineer</td>
@ -1372,7 +1372,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Zorita Serrano</td>
<td>Software Engineer</td>
@ -1383,7 +1383,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Jennifer Acosta</td>
<td>Junior Javascript Developer</td>
@ -1394,7 +1394,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Cara Stevens</td>
<td>Sales Assistant</td>
@ -1405,7 +1405,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Hermione Butler</td>
<td>Regional Director</td>
@ -1416,7 +1416,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Lael Greer</td>
<td>Systems Administrator</td>
@ -1427,7 +1427,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Jonas Alexander</td>
<td>Developer</td>
@ -1438,7 +1438,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Shad Decker</td>
<td>Regional Director</td>
@ -1449,7 +1449,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Michael Bruce</td>
<td>Javascript Developer</td>
@ -1460,7 +1460,7 @@
</tr>
<tr>
<td>
<th><input type="checkbox" id="check-all" class="flat"></th>
<th><input type="checkbox" id="check-all" ></th>
</td>
<td>Donna Snider</td>
<td>Customer Support</td>

View File

@ -1,14 +1,14 @@
{
"name": "validator",
"homepage": "https://github.com/yairEO/validator",
"version": "1.1.0",
"_release": "1.1.0",
"version": "3.3.5",
"_release": "3.3.5",
"_resolution": {
"type": "version",
"tag": "1.1.0",
"commit": "f855eb37c626f2ad712583d25afdd30147a40d8e"
"tag": "3.3.5",
"commit": "01a570d68fa748f87a6a90166f157a64225e9e4d"
},
"_source": "https://github.com/yairEO/validator.git",
"_target": "^1.0.6",
"_target": "^3.3.5",
"_originalSource": "https://github.com/yairEO/validator.git"
}

View File

@ -161,3 +161,4 @@ pip-log.txt
# Mac crap
.DS_Store
/.npmrc

View File

@ -1,10 +1,10 @@
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.
The Validator is cross-browser and will give you the power to use future-proof input types such as
`tel`, `email`, `number`, `date`, `time`, `checkbox` and `url`.
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)
# [DEMO PAGE](http://yaireo.github.io/validator)
### Why should you use this?
@ -12,7 +12,7 @@ In the semantic point-of-view, I believe that this method is very clean and…ap
* Deals with all sorts of edge cases
* Utilize new HTML5 types for unsupported browsers
* Flexible error messaging system
* Light-weight (10kb + comments)
* Light-weight (19kb + comments, unminified)
## 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 wouldnt it be checked in the first place when the form is rendered?
@ -25,26 +25,24 @@ These input types can be validated by the the JS for `<input type='foo' name
* Password
* Number
* Date
* Time
* 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
* Select
* Textarea
* Hidden Hidden fields can also have the required attribute
## Basic semantics
<form action="" method="post" novalidate>
<fieldset>
<div class="item">
<div class="field">
<label>
<span>Name</span>
<input data-validate-lengthRange="6" data-validate-words="2" name="name" placeholder="ex. John f. Kennedy" required="required" type="text" />
<input data-validate-length-range="6" data-validate-words="2" name="name" placeholder="ex. John f. Kennedy" required="required" type="text" />
</label>
<div class='tooltip help'>
<span>?</span>
@ -54,7 +52,7 @@ The below form elements are also supported:
</div>
</div>
</div>
<div class="item">
<div class="field">
<label>
<span>email</span>
<input name="email" required="required" type="email" />
@ -64,8 +62,8 @@ The below form elements are also supported:
### 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 labels text itself, we wrap it with a `<span>` to have control over its style.
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 “field”, and therefor these “fields” will be wraped with `<div class='field'>`. This isolation gives great powers.
Next, inside an field, 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 labels text itself, we wrap it with a `<span>` to have control over its 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.
@ -77,83 +75,134 @@ The whole approach here is to define each form field (input, select, whatever) a
| 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 fields value (the attribute is set on) should be compared to |
| data-validate-linked | Defines the field which the current fields value (the attribute is set on) should be compared to. Value can be a selector or another input's `name` attribute's value |
| 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.
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.
This is the object which holds all the texts used by the form validator:
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'
};
{
invalid : 'inupt is not as expected',
short : 'input is too short',
long : 'input is too long',
checked : 'must be checked',
empty : 'please put something here',
select : 'Please select an option',
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',
date : 'invalid date',
time : 'invalid time',
password_repeat : 'passwords do not match',
no_match : 'no match',
complete : 'input is not complete'
}
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;`
// set custom text on initialization:
var validator = new FormValidator({
texts : {
date:'not a real date'
}
});
// or post-initialization
var validator = new FormValidator();
validator.texts.date = 'not a real date';
Error messages (per field) can be disabled:
validator = new FormValidator({
alerts:false
});
// or by:
var validator = new FormValidator();
validator.settings.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).
There are two 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
### 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.
A generic callback function 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
var validator = new FormValidator();
// select your "form" element from the DOM and attach an "onsubmit" event handler to it:
document.forms[0].onsubmit = function(e){
var validatorResult = validator.checkAll(this);
// check all the rerquired fields
if( !validator.checkAll( $(this) ) )
submit = false;
return !!validatorResult.valid;
};
if( submit )
this.submit();
### Usage example - validate on field blur/input/change events
Check every field (using event Capture)
return false;
})
var validator = new FormValidator();
###Usage example - validate on field blur event (out of focus)
Check every field once it looses focus (onBlur) event
document.forms[0].addEventListener('blur', function(e){
validator.checkField(e.target)
}, true);
$('form').on('blur', 'input[required]', validator.checkField);
document.forms[0].addEventListener('input', function(e){
validator.checkField(e.target);
}, true);
## Tooltips
document.forms[0].addEventListener('change', function(e){
validator.checkField(e.target)
}, true);
The helper tooltips **&lt;div class='tooltip help'&gt;**, 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.
Utilize the internal events' binding system; pass in the settings the `events` property and assign it an array which states which events should be inputs be validated for. For a single events, a string may be paassed instead of an Array:
var validator = new FormValidator( document.forms[0], {
"events" : ['blur', 'input', 'change'] // for a single one, just pass a string, ex: "blur"
});
In case the form is not yet ready, the events maybe be binded later, when the form is ready, using the internal `events` method for a `validator` instance:
// validate fields on these events:
var validator = new FormValidator(document.forms[0]); // the "<form>" element should be passed when the instance is created or passed to the "events" method below (as the 2nd parameter)
// wait for the form, or its' fields, to be ready (for whatever reason), and then bind the events as follows:
validator.events(['blur', 'input', 'change']);
## Tooltips (for each field which did not validate)
The helper tooltips **&lt;div class='tooltip help'&gt;**, 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 “field” is about or for example, what the allowed input format is.
## Classes
`validator.defaults.classes` object can be modified with these classes:
`validator.settings.classes` object can be modified:
item : 'item', // class for each input wrapper
alert : 'alert', // call on the alert tooltip
bad : 'bad' // classes for bad input
var validatorClasses = {
field : 'field', // class for each input wrapper
alert : 'alert', // call on the alert tooltip
bad : 'bad' // classes for bad input
};
## Bonos multifields
validator = new FormValidator(null, {classes:validatorClasses});
// or
validator = new FormValidator();
validator.settings.classes.bad = 'error';
## Bonus 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 its included in multifield.js file.

View File

@ -44,23 +44,23 @@ 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; }
button{ 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; }
.field .tooltip{ float:left; top:2px; left:7px; position:relative; z-index:2; }
.field .tooltip:hover{ z-index:3; }
.field .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; }
.field .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); }
.field .tooltip p{ padding:0; }
.field .tooltip.down .content{ left:auto; right:0; top:30px; }
.field .tooltip:hover .content{ opacity:1; left:36px; }
.field .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; }
.field .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; }
.field .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; }
.field .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; }
.field.bad .alert{ left:0; opacity:1; }
@keyframes shake{
@ -77,47 +77,47 @@ button[type=submit]{ font-size:1.1em; padding:5px 25px; }
}
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; }
form .field{ padding:5px 0; position:relative; height:2em; }
form .field.fields{ height:auto; }
.field label, .field .label{ cursor:pointer; }
.field label > span:first-child, .field .label{ float:left; width:160px; text-transform:capitalize; line-height:2em; }
.field input, .field textarea{ float:left; padding:3px 4px; width:210px; -webkit-transition:0.2s; -moz-transition:0.2s; transition:0.2s; }
.field 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; }
.field input.short{ width:90px; }
.field input:focus:not([type="checkbox"]), .field textarea:focus{ box-shadow:0 0 4px #00AEEF; border:1px solid #00AEEF; }
.field textarea{ }
.field select{ float:left; width:220px; padding:2px 0; margin:0; border:1px solid #CCC; text-transform:capitalize; }
.field select option{ padding:1px; }
.item > .extra{ float:left; font-size:0.9em; color:#999; line-height:2em; margin-left:13px; }
.field > .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; }
.field.multi .input{ float:left; }
.field.multi input{ float:left; margin-right:5px; width:35px; text-align:center; }
form .field.multi input:nth-last-child(-n+2){ margin:0; }
.field.fields 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; }
.bad textarea{ border:1px solid #CE5454; box-shadow:0 0 4px -2px #CE5454; position:relative; left:0; -moz-animation:.4s 1 shake ease; -webkit-animation:0.4s 1 shake ease; }
/* 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; }
.mode2 .field{ float:left; clear:left; margin-bottom:30px; height:auto; padding:0; zoom:1; }
.mode2 .field.bad{ margin-bottom:8px; }
.mode2 .field::before, .mode2 .field::after{ content:''; display:table; }
.mode2 .field::after{ clear:both; }
.mode2 .field label{ }
.mode2 .field label span{ float:none; display:block; line-height:inherit; }
.mode2 .field input:not(type="checkbox"), .field textarea{ width:250px; margin:0; }
.mode2 .field textarea{ width:350px; margin:0; }
.mode2 .field select{ width:260px; float:none; }
.mode2 .field.multi label{ float:none; }
.mode2 .field.multi input{ float:left; margin-right:5px; width:35px; text-align:center; }
.mode2 .field .tooltip{ left:auto; position:absolute; right:-22px; top:19px; }
.mode2 .field .alert::after{ display:none; }
.mode2 .field .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 .field > .extra{ position:absolute; right:0; }

View File

@ -7,8 +7,8 @@
<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; }
.field .tooltip .content{ display:none; opacity:1; }
.field .tooltip:hover .content{ display:block; }
</style>
<![endif]-->
</head>
@ -16,20 +16,20 @@
<a class='btn github' href='https://github.com/yairEO/validator'>Github</a>
<div id='wrap'>
<div class='options'>
<label>
<!-- <label>
<input type='checkbox' id='vfields' />
Vertical orientation
</label>
</label> -->
<label>
<input type='checkbox' id='alerts' />
Disable alerts
<input type='checkbox' class='toggleValidationTooltips' />
Disable vlidation tooltips
</label>
</div>
<h1 title='how forms should be done.'>Forms: validation, styling &amp; semantics</h1>
<section class='form'>
<form action="" method="post" novalidate>
<fieldset>
<div class="item">
<div class="field">
<label>
<span>Name</span>
<input data-validate-length-range="6" data-validate-words="2" name="name" placeholder="ex. John f. Kennedy" required="required" />
@ -42,21 +42,21 @@
</div>
</div>
</div>
<div class="item">
<div class="field">
<label>
<span>Occupation</span>
<input class='optional' name="occupation" data-validate-length-range="5,20" type="text" />
<input class='optional' name="occupation" data-validate-length-range="5,15" 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>
<p>An optional field. This field is only validated when it has a value.<br /><em>Minimum 5 chars, maximum 15</em></p>
</div>
</div>
<span class='extra'>(optional)</span>
</div>
<div class="item">
<div class="field">
<label>
<span>HTML5 Regex</span>
<!--<input required="required" type="text" pattern='\d+' />-->
@ -70,19 +70,19 @@
</div>
</div>
</div>
<div class="item">
<div class="field">
<label>
<span>email</span>
<input name="email" class='email' required="required" type="email" />
</label>
</div>
<div class="item">
<div class="field">
<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">
<div class="field">
<label>
<span>Number</span>
<input type="number" class='number' name="number" data-validate-minmax="10,100" required='required'>
@ -95,13 +95,26 @@
</div>
</div>
</div>
<div class="item">
<div class="field">
<label>
<span>Date</span>
<input class='date' type="date" name="date" required='required'>
</label>
</div>
<div class="item">
<div class="field">
<label>
<span>Time</span>
<input class='time' type="time" name="time" required='required'>
<div class='tooltip help'>
<span>?</span>
<div class='content'>
<b></b>
<p>Format should be: XX:XX</p>
</div>
</div>
</label>
</div>
<div class="field">
<label>
<span>Password</span>
<input type="password" name="password" data-validate-length="6,8" required='required'>
@ -114,13 +127,13 @@
</div>
</div>
</div>
<div class="item">
<div class="field">
<label>
<span>Repeat password</span>
<input type="password" name="password2" data-validate-linked='password' required='required'>
</label>
</div>
<div class="item">
<div class="field">
<label>
<span>Telephone</span>
<input type="tel" class='tel' name="phone" required='required' data-validate-length-range="8,20">
@ -133,11 +146,11 @@
</div>
</div>
</div>
<div class="item">
<div class="field">
<label>
<span>Drop down selection</span>
<select class="required" name="dropdown">
<option value="">-- none --</option>
<select required name="dropdown">
<option value="">-- please select --</option>
<option value="o1">Option 1</option>
<option value="o2">Option 2</option>
<option value="o3">Option 3</option>
@ -151,21 +164,30 @@
</div>
</div>
</div>
<div class="item">
<div class="field">
<label>
<span>url</span>
<input name="url" placeholder="http://www.website.com" required="required" type="url" />
</label>
</div>
<div class="item">
<div class="field">
<label>
<span>Checkboxes</span>
<label><input required="required" type="checkbox" />I agree</label>
<span>Checkbox</span>
<input required="required" type="checkbox" />
<span>I agree</span>
</label>
</div>
<div class="item multi required">
<div class="field">
<label>
<span>Checkbox</span>
<input type="checkbox" />
<span>Optional Checkbox</span>
</label>
</div>
<div class="field multi required">
<label for='multi_first'>
<span>Multifield</span>
</label>
@ -186,13 +208,13 @@
</div>
</div>
</div>
<div class="item">
<div class="field">
<label>
<span>File upload</span>
<input type='file' required>
</label>
</div>
<div class="item">
<div class="field">
<label>
<span>message</span>
<textarea required="required" name='message'></textarea>
@ -200,10 +222,15 @@
</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>
<p>
There is a hidden "required" form field below, notice it will not be validated due to its lack of visibility.<br>
The reason for this is that sometimes there is a section in a form that is not visible until some user "action" is taken,
and changing form fields to be "required" on-the-fly is undesirable.
</p>
<input name="somethingHidden" required="required" type="text" style='display:none' />
</fieldset>
<button id='send' type='submit'>Submit</button>
<button type='submit'>Submit</button>
<button type='reset'>Reset</button>
</form>
</section>
</div>
@ -211,45 +238,30 @@
<script src="multifield.js"></script>
<script src="validator.js"></script>
<script>
// initialize the validator function
validator.message['date'] = 'not a real date';
// initialize a validator instance from the "FormValidator" constructor.
// A "<form>" element is optionally passed as an argument, but is not a must
var validator = new FormValidator({"events" : ['blur', 'input', 'change']}, document.forms[0]);
// 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] );
});
// on form "submit" event
document.forms[0].onsubmit = function(e){
var submit = true,
validatorResult = validator.checkAll(this);
// bind the validation to the form submit event
//$('#send').click('submit');//.prop('disabled', true);
console.log(validatorResult);
return !!validatorResult.valid;
};
$('form').submit(function(e){
e.preventDefault();
var submit = true;
// Validate the form using generic validaing
if( !validator.checkAll( $(this) ) ){
submit = false;
}
// on form "reset" event
document.forms[0].onreset = function(e){
validator.reset();
};
if( submit )
this.submit();
// stuff related ONLY for this demo page:
$('.toggleValidationTooltips').change(function(){
validator.settings.alerts = !this.checked;
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);

22
vendors/validator/package.json vendored Normal file
View File

@ -0,0 +1,22 @@
{
"name" : "@yaireo/validator",
"version" : "3.3.4",
"homepage" : "https://github.com/yairEO/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`, `time`, `checkbox` and `url`",
"_npmUser" : {
"name" : "vsync",
"email" : "vsync.design@gmail.com"
},
"author" : {
"name" : "Yair Even-Or",
"email" : "vsync.design@gmail.com"
},
"main" : "validator.js",
"repository" : {
"type" : "git",
"url" : "git+https://github.com/yairEO/validator.git"
},
"bugs" : {
"url": "https://github.com/yaireo/validator/issues"
}
}

View File

@ -1,30 +0,0 @@
{
"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"
}
}

View File

@ -1,411 +1,594 @@
/*
Validator v1.1.0
Validator v3.3.1
(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"
;(function(root, factory){
var define = define || {};
if( typeof define === 'function' && define.amd )
define([], factory);
else if( typeof exports === 'object' && typeof module === 'object' )
module.exports = factory();
else if(typeof exports === 'object')
exports["FormValidator"] = factory();
else
root.FormValidator = factory();
}(this, function(){
function FormValidator( settings, formElm ){
this.data = {}; // holds the form fields' data
/* 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'
};
this.DOM = {
scope : formElm
};
if(!window.console){
console={};
console.log=console.warn=function(){ return; }
this.settings = this.extend({}, this.defaults, settings || {});
this.texts = this.extend({}, this.texts, this.settings.texts || {});
this.settings.events && this.events();
}
// defaults
defaults = {
alerts : true,
classes : {
item : 'item',
alert : 'alert',
bad : 'bad'
}
};
FormValidator.prototype = {
// Validation error texts
texts : {
invalid : 'inupt is not as expected',
short : 'input is too short',
long : 'input is too long',
checked : 'must be checked',
empty : 'please put something here',
select : 'Please select an option',
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',
date : 'invalid date',
time : 'invalid time',
password_repeat : 'passwords do not match',
no_match : 'no match',
complete : 'input is not complete'
},
/* 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;
// default settings
defaults : {
alerts : true,
events : false,
regex : {
url : /^(https?:\/\/)?([\w\d\-_]+\.+[A-Za-z]{2,})+\/?/,
phone : /^\+?([0-9]|[-|' '])+$/i,
numeric : /^[0-9]+$/i,
alphanumeric : /^[a-zA-Z0-9]+$/i,
email : {
illegalChars : /[\(\)\<\>\,\;\:\\\/\"\[\]]/,
filter : /^.+@.+\..{2,6}$/ // exmaple email "steve@s-i.photo"
}
},
classes : {
item : 'field',
alert : 'alert',
bad : 'bad'
}
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;
// Tests (per type)
// each test return "true" when passes and a string of error text otherwise
tests : {
sameAsPlaceholder : function( field, data ){
if( field.getAttribute('placeholder') )
return data.value != field.getAttribute('placeholder') || this.texts.empty;
else
return true;
};
},
if( words.length < validateWords || !wordsLength(2) ){
alertTxt = message.complete;
return false;
hasValue : function( value ){
return value ? true : this.texts.empty;
},
// '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, type){
if( b != a ){
// choose a specific message or a general one
return this.texts[type + '_repeat'] || this.texts.no_match;
}
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;
}
email : function(field, data){
if ( !this.settings.regex.email.filter.test( data.value ) || data.value.match( this.settings.regex.email.illegalChars ) ){
return this.texts.email;
}
// 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;
return true;
},
// a "skip" will skip some of the tests (needed for keydown validation)
text : function(field, data){
var that = this;
// 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( data.validateWords ){
var words = data.value.split(' ');
// iterate on all the words
var wordsLength = function(len){
for( var w = words.length; w--; )
if( words[w].length < len )
return that.texts.short;
return true;
};
if( words.length < data.validateWords || !wordsLength(2) )
return this.texts.complete;
return true;
}
if( data.lengthRange && data.value.length < data.lengthRange[0] ){
return this.texts.short;
}
// check if there is max length & field length is greater than the allowed
if( data.lengthRange && data.lengthRange[1] && data.value.length > data.lengthRange[1] ){
return this.texts.long;
}
// 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( data.lengthLimit && data.lengthLimit.length ){
while( data.lengthLimit.length ){
if( data.lengthLimit.pop() == data.value.length ){
return true;
}
}
return this.texts.complete;
}
if( data.pattern ){
var regex, jsRegex;
switch( data.pattern ){
case 'alphanumeric' :
regex = this.settings.regex.alphanumeric
break;
case 'numeric' :
regex = this.settings.regex.numeric
break;
case 'phone' :
regex = this.settings.regex.phone
break;
default :
regex = data.pattern;
}
try{
jsRegex = new RegExp(regex).test(data.value);
if( data.value && !jsRegex ){
return this.texts.invalid;
}
}
catch(err){
console.warn(err, field, 'regex is invalid');
return this.texts.invalid;
}
}
}
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;
return true;
},
number : function( field, data ){
var a = data.value;
// if not not a number
if( isNaN(parseFloat(a)) && !isFinite(a) ){
return this.texts.number;
}
// not enough numbers
else if( data.lengthRange && a.length < data.lengthRange[0] ){
return this.texts.short;
}
// check if there is max length & field length is greater than the allowed
else if( data.lengthRange && data.lengthRange[1] && a.length > data.lengthRange[1] ){
return this.texts.long;
}
else if( data.minmax[0] && (a|0) < data.minmax[0] ){
return this.texts.number_min;
}
else if( data.minmax[1] && (a|0) > data.minmax[1] ){
return this.texts.number_max;
}
return true;
},
// Date is validated in European format (day,month,year)
date : function( field, data ){
var day, A = data.value.split(/[-./]/g), i;
// if there is native HTML5 support:
if( field.valueAsNumber )
return true;
for( i = A.length; i--; ){
if( isNaN(parseFloat( data.value )) && !isFinite(data.value) )
return this.texts.date;
}
try{
jsRegex = new RegExp(regex).test(a);
if( a && !jsRegex )
return false;
day = new Date(A[2], A[1]-1, A[0]);
if( day.getMonth()+1 == A[1] && day.getDate() == A[0] )
return true;
return this.texts.date;
}
catch(err){
console.log(err, field, 'regex is invalid');
return false;
catch(er){
return this.texts.date;
}
}
},
time : function( field, data ){
var pattern = /^([0-1][0-9]|2[0-3]):[0-5][0-9]$/;
if( pattern.test(data.value) )
return true;
else
return this.texts.time;
},
url : function( field, data ){
// minimalistic URL validation
if( !this.settings.regex.url.test(data.value) )
return this.texts.url;
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;
hidden : function( field, data ){
if( data.lengthRange && data.value.length < data.lengthRange[0] )
return this.texts.short;
if( data.pattern ){
if( data.pattern == 'alphanumeric' && !this.settings.regex.alphanumeric.test(data.value) )
return this.texts.invalid;
}
return true;
},
select : function( field, data ){
return data.value ? true : this.texts.select;
},
checkbox : function( field, data ){
if( field.checked ) return true;
return this.texts.checked;
}
},
url : function(a){
// minimalistic URL validation
function testUrl(url){
return /^(https?:\/\/)?([\w\d\-_]+\.+[A-Za-z]{2,})+\/?/.test( url );
/**
* bind events on form elements
* @param {Array/String} types [description]
* @param {Object} formElm [optional - form element, if one is not already defined on the instance]
* @return {[type]} [description]
*/
events : function( types, formElm ){
var that = this;
types = types || this.settings.events;
formElm = formElm || this.DOM.scope;
if( !formElm || !types ) return;
if( types instanceof Array )
types.forEach(bindEventByType);
else if( typeof types == 'string' )
bindEventByType(types)
function bindEventByType( type ){
formElm.addEventListener(type, function(e){
that.checkField(e.target)
}, true);
}
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;
/**
* Marks an field as invalid
* @param {DOM Object} field
* @param {String} text
* @return {String} - useless string (should be the DOM node added for warning)
*/
mark : function( field, text ){
if( !text || !field )
return false;
}
if( pattern ){
var regex;
if( pattern == 'alphanumeric' ){
regex = /^[a-z0-9]+$/i;
if( !regex.test(a) ){
return false;
}
var that = this;
// check if not already marked as 'bad' 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 = this.closest(field, '.' + this.settings.classes.item),
alert = item.querySelector('.'+this.settings.classes.alert),
warning;
if( this.settings.alerts ){
if( alert )
alert.innerHTML = text;
else{
warning = '<div class="'+ this.settings.classes.alert +'">' + text + '</div>';
item.insertAdjacentHTML('beforeend', warning);
}
}
return true;
item.classList.remove(this.settings.classes.bad);
// a delay so the "alert" could be transitioned via CSS
setTimeout(function(){
item.classList.add( that.settings.classes.bad );
});
return warning;
},
select : function(a){
if( !tests.hasValue(a) ){
alertTxt = message.select;
/* un-marks invalid fields
*/
unmark : function( field ){
var warning;
if( !field ){
console.warn('no "field" argument, null or DOM object not found');
return false;
}
return true;
}
};
/* marks invalid fields
*/
mark = function( field, text ){
if( !text || !field || !field.length )
return false;
var fieldWrap = this.closest(field, '.' + this.settings.classes.item);
// 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( fieldWrap ){
warning = fieldWrap.querySelector('.'+ this.settings.classes.alert);
fieldWrap.classList.remove(this.settings.classes.bad);
}
if( item.hasClass(defaults.classes.bad) ){
if( defaults.alerts )
item.find('.'+defaults.classes.alert).html(text);
}
if( warning )
warning.parentNode.removeChild(warning);
},
/**
* removes unmarks all fields
* @return {[type]} [description]
*/
reset : function( formElm ){
var fieldsToCheck,
that = this;
else if( defaults.alerts ){
warning = $('<div class="'+ defaults.classes.alert +'">').html( text );
item.append( warning );
}
formElm = formElm || this.DOM.scope;
fieldsToCheck = this.filterFormElements( formElm.elements );
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;
}
fieldsToCheck.forEach(function(elm){
that.unmark(elm);
});
},
field.closest('.' + defaults.classes.item)
.removeClass(defaults.classes.bad)
.find('.'+ defaults.classes.alert).remove();
};
/**
* Normalize types if needed & return the results of the test (per field)
* @param {String} type [form field type]
* @param {*} value
* @return {Boolean} - validation test result
*/
testByType : function( field, data ){
data = this.extend({}, data); // clone the data
function testByType(type, value){
if( type == 'tel' )
pattern = pattern || 'phone';
var type = data.type;
if( !type || type == 'password' || type == 'tel' || type == 'search' || type == 'file' )
type = 'text';
if( type == 'tel' )
data.pattern = data.pattern || 'phone';
if( !type || type == 'password' || type == 'tel' || type == 'search' || type == 'file' )
type = 'text';
return tests[type] ? tests[type](value, true) : true;
}
return this.tests[type] ? this.tests[type].call(this, field, data) : true;
},
function prepareFieldData(el){
field = $(el);
prepareFieldData : function( field ){
var nodeName = field.nodeName.toLowerCase(),
id = Math.random().toString(36).substr(2,9);
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');
}
field["_validatorId"] = id;
this.data[id] = {};
/* Validations per-character keypress
*/
function keypress(e){
prepareFieldData(this);
// String.fromCharCode(e.charCode)
this.data[id].value = field.value.replace(/^\s+|\s+$/g, ""); // cache the value of the field and trim it
this.data[id].valid = true; // initialize validity of field
this.data[id].type = field.getAttribute('type'); // every field starts as 'valid=true' until proven otherwise
this.data[id].pattern = field.getAttribute('pattern');
if( e.charCode ){
return testByType( this.type, this.value );
}
}
// Special treatment
if( nodeName === "select" )
this.data[id].type = "select";
/* 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;
else if( nodeName === "textarea" )
this.data[id].type = "text";
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
/* Gather Custom data attributes for specific validation:
*/
if( tests.sameAsPlaceholder(field) ){
alertTxt = message.empty;
this.data[id].validateWords = field.getAttribute('data-validate-words') || 0;
this.data[id].lengthRange = field.getAttribute('data-validate-length-range') ? (field.getAttribute('data-validate-length-range')+'').split(',') : [1];
this.data[id].lengthLimit = field.getAttribute('data-validate-length') ? (field.getAttribute('data-validate-length')+'').split(',') : false;
this.data[id].minmax = field.getAttribute('data-validate-minmax') ? (field.getAttribute('data-validate-minmax')+'').split(',') : false; // for type 'number', defines the minimum and/or maximum for the value as a number.
this.data[id].validateLinked = field.getAttribute('data-validate-linked');
return this.data[id];
},
/**
* Find the closeset element, by selector
* @param {Object} el [DOM node]
* @param {String} selector [CSS-valid selector]
* @return {Object} [Found element or null if not found]
*/
closest : function(el, selector){
var matchesFn;
// find vendor prefix
['matches','webkitMatchesSelector','mozMatchesSelector','msMatchesSelector','oMatchesSelector'].some(function(fn){
if( typeof document.body[fn] == 'function' ){
matchesFn = fn;
return true;
}
return false;
})
var parent;
// traverse parents
while (el) {
parent = el.parentElement;
if (parent && parent[matchesFn](selector)) {
return parent;
}
el = parent;
}
return null;
},
/**
* MDN polyfill for Object.assign
*/
extend : function( target, varArgs ){
if( !target )
throw new TypeError('Cannot convert undefined or null to object');
var to = Object(target),
nextKey, nextSource, index;
for( index = 1; index < arguments.length; index++ ){
nextSource = arguments[index];
if( nextSource != null ) // Skip over if undefined or null
for( nextKey in nextSource )
// Avoid bugs when hasOwnProperty is shadowed
if( Object.prototype.hasOwnProperty.call(nextSource, nextKey) )
to[nextKey] = nextSource[nextKey];
}
return to;
},
/* Checks a single form field by it's type and specific (custom) attributes
* {DOM Object} - the field to be checked
* {Boolean} silent - don't mark a field and only return if it passed the validation or not
*/
checkField : function( field, silent ){
// skip testing fields whom their type is not HIDDEN but they are HIDDEN via CSS.
if( field.type !='hidden' && !field.clientWidth )
return { valid:true, error:"" }
field = this.filterFormElements( [field] )[0];
// if field did not pass filtering or is simply not passed
if( !field )
return { valid:true, error:"" }
// this.unmark( field );
var linkedTo,
testResult,
optional = field.className.indexOf('optional') != -1,
data = this.prepareFieldData( field ),
form = this.closest(field, 'form'); // if the field is part of a form, then cache it
// check if field has any value
/* 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.
*/
// first, check if the field even has any value
testResult = this.tests.hasValue.call(this, data.value);
// if the field has value, check if that value is same as placeholder
if( testResult === true )
testResult = this.tests.sameAsPlaceholder.call(this, field, data );
data.valid = optional || testResult === true;
if( optional && !data.value ){
return { valid:true, error:"" }
}
if( testResult !== true )
data.valid = false;
// validate by type of field. use 'attr()' is proffered to get the actual value and not what the browsers sees for unsupported types.
if( data.valid ){
testResult = this.testByType(field, data);
data.valid = testResult === true ? true : 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() );
if( data.valid && data.validateLinked ){
if( data['validateLinked'].indexOf('#') == 0 )
linkedTo = document.body.querySelector(data['validateLinked'])
else if( form.length )
linkedTo = form.querySelector('[name=' + data['validateLinked'] + ']');
else
linkedTo = document.body.querySelector('[name=' + data['validateLinked'] + ']');
testResult = this.tests.linked.call(this, field.value, linkedTo.value, data.type );
data.valid = testResult === true ? true : false;
}
/* 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);
if( !silent )
this[data.valid ? "unmark" : "mark"]( field, testResult ); // mark / unmark the field
return {
valid : data.valid,
error : data.valid === true ? "" : testResult
};
},
/**
* Only allow certain form elements which are actual inputs to be validated
* @param {HTMLCollection} form fields Array [description]
* @return {Array} [description]
*/
filterFormElements : function( fields ){
var i,
fieldsToCheck = [];
for( i = fields.length; i--; ) {
var isAllowedElement = fields[i].nodeName.match(/input|textarea|select/gi),
isRequiredAttirb = fields[i].hasAttribute('required'),
isDisabled = fields[i].hasAttribute('disabled'),
isOptional = fields[i].className.indexOf('optional') != -1;
if( isAllowedElement && (isRequiredAttirb || isOptional) && !isDisabled )
fieldsToCheck.push(fields[i]);
}
return fieldsToCheck;
},
checkAll : function( formElm ){
if( !formElm ){
console.warn('element not found');
return false;
}
var that = this,
result = {
valid : true, // overall form validation flag
fields : [] // array of objects (per form field)
},
fieldsToCheck = this.filterFormElements( formElm.elements );
// get all the input/textareas/select fields which are required or optional (meaning, they need validation only if they were filled)
fieldsToCheck.forEach(function(elm, i){
var fieldData = that.checkField(elm);
// use an AND operation, so if any of the fields returns 'false' then the submitted result will be also FALSE
result.valid = !!(result.valid * fieldData.valid);
result.fields.push({
field : elm,
error : fieldData.error,
valid : !!fieldData.valid
})
});
return result;
}
// 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);
return FormValidator;
}));