表单验证
如果想要屏蔽浏览器对表单的默认验证行为,可以在表单元素上添加novalidate标记。
下面看一下可以在input元素上使用的所有验证选项。
1. 必填项
验证某个表单输入是否已填写,只要在输入字段元素上添加HTML5标记required即可:
<input type="text" required />
2. 最小长度
验证表单输入的文本长度是否大于某个最小值,在输入字段上使用AngularJS指令ng-minleng=
"{number}":
<input type="text" ng-minlength="5" />
3. 最大长度
验证表单输入的文本长度是否小于或等于某个最大值,在输入字段上使用AngularJS指令
ng-maxlength="{number}":
<input type="text" ng-maxlength="20" />
4. 模式匹配
使用ng-pattern="/PATTERN/"来确保输入能够匹配指定的正则表达式:
<input type="text" ng-pattern="[a-zA-Z]" />
5. 电子邮件
验证输入内容是否是电子邮件,只要像下面这样将input的类型设置为email即可:
<input type="email" name="email" ng-model="user.email" />
6. 数字
验证输入内容是否是数字,将input的类型设置为number:
<input type="number" name="age" ng-model="user.age" />
7. URL
验证输入内容是否是URL,将input的类型设置为 url:
<input type="url" name="homepage" ng-model="user.facebook_url" />
8. 自定义验证
在AngularJS中自定义指令是非常容易的。鉴于目前还没有介绍到指令的相关内容,第10章
再深入研究如何创建自定义验证。目前先来看一下如何通过向后端服务器发送请求,并通过响应
的结果来将输入字段设置为合法或不合法,以确保输入字段中的内容是唯一的。
9. 在表单中控制变量
表单的属性可以在其所属的$scope对象中访问到,而我们又可以访问$scope对象,因此
JavaScript可以间接地访问DOM中的表单属性。借助这些属性,我们可以对表单做出实时(和
AngularJS中其他东西一样)响应。这些属性包括下面这些。
(注意,可以使用下面的格式访问这些属性。)
formName.inputFieldName.property
未修改的表单
这是一个布尔属性,用来判断用户是否修改了表单。如果未修改,值为true,如果修改过值
为false:
formName.inputFieldName.$pristine
修改过的表单
只要用户修改过表单,无论输入是否通过验证,该值都返回true:
formName.inputFieldName.$dirty
合法的表单
这个布尔型的属性用来判断表单的内容是否合法。如果当前表单内容是合法的,下面属性的
值就是true:
formName.inputFieldName.$valid
不合法的表单
这个布尔属性用来判断表单的内容是否不合法。如果当前表单内容是不合法的,下面属性的
值为true:
formName.inputFieldName.$invalid
错误
这是AngularJS提供的另外一个非常有用的属性:$error对象。它包含当前表单的所有验证
内容,以及它们是否合法的信息。用下面的语法访问这个属性:
formName.inputfieldName.$error
如果验证失败,这个属性的值为true;如果值为false,说明输入字段的值通过了验证。
10. 一些有用的CSS样式
AngularJS处理表单时,会根据表单当前的状态添加一些CSS类(例如当前是合法的、未发生
变化的,等等),这些CSS类的命名和前面介绍的属性很相似。
它们包括:
.ng-pristine {}
.ng-dirty {}
.ng-valid {}
.ng-invalid {}
它们对应着表单输入字段的特定状态。
当某个字段中的输入非法时,.ng-invlid类会被添加到这个字段上。当前例子中的站点将
对应的CSS样式设置为:
input.ng-invalid {
border: 1px solid red;
}
input.ng-valid {
border: 1px solid green;
}
表单实例html代码如下
1 <!DOCTYPE html> 2 <html ng-app = "myApp"> 3 <head> 4 <title>Simple app</title> 5 </head> 6 <body> 7 <form name = "signup_form" novalidate-submit = "signupForm()"> 8 <fieldset> 9 <legend>Signup</legend> 10 11 <div class = "row"> 12 <div class = "large-12 columns"> 13 <label>Your name</label> 14 <input type = "text" placeholder="Name" name = "name" ng-model = "signup.name" ng-minlength = 3 ng-maxlength = 20 required /> 15 <!-- 对输入进行实时验证,若对输入进行过更改且输入不合格则实时进行错误显示--> 16 <div class = "error" ng-show = "signup_form.name.$dirty && signup_form.name.$invalid"> 17 <small class = "error" ng-show = "signup_form.name.$error.required">Your name is required.</small> 18 <small class = "error" ng-show = "signup_form.name.$error.minlength">Your name is required to be at least 3 characters</small> 19 <small class = "error" ng-show = "signup_form.name.$error.maxlength">Your name can't be longer than 20 characters</small> 20 </div> 21 </div> 22 </div> 23 24 <div class = "row"> 25 <div class = "large-12 columns"> 26 <label>Your email</label> 27 <input type="email" placeholder="Email" name = "email" ng-model = "signup.email" ng-minlength = 3 ng-maxlength = 20 required /> 28 <div class = "error" ng-show = "signup_form.email.$dirty && signup_form.email.$invalid"> 29 <small class = "error" ng-show = "signup_form.email.$error.required">Your email is required.</small> 30 <small class = "error" ng-show = "signup_form.email.$error.minlength">Your email is required to be at least 3 characters</small> 31 <small class = "error" ng-show = "signup_form.email.$error.email">That is not a valid email.Please input a valid email.</small> 32 <small class = "error" ng-show = "signup_form.email.$error.maxlength">Your email can't be longer than 20 characters</small> 33 </div> 34 </div> 35 </div> 36 37 <div class = "large-12 columns"> 38 <label>Username</label> 39 <input type = "text" placeholder="Desired username" name = "username" ng-model = "signup.username" ng-minlength = 3 ng-maxlength = 20 ensure-unique = "username" required /> 40 <div class = "error" ng-show = "signup_form.name.$dirty && signup_form.name.$invalid"> 41 <small class = "error" ng-show = "signup_form.username.$error.required">Please input a username.</small> 42 <small class = "error" ng-show = "signup_form.username.$error.minlength">Your username is required to be at least 3 characters</small> 43 <small class = "error" ng-show = "signup_form.username.$error.maxlength">Your username can't be longer than 20 characters</small> 44 <small class = "error" ng-show = "signup_form.username.$error.unique">That username is taken, please try another</small> 45 </div> 46 </div> 47 48 <button type = "submit" class = "button radius" ng-disabled = "signup_form.$invalid">Submit</button> 49 </fieldset> 50 </form> 51 <script type="text/javascript" src = "js/jquery.min.js"></script> 52 <script type="text/javascript" src = "js/bootstrap.min.js"></script> 53 <script type="text/javascript" src = "js/angular.js"></script> 54 <script type="text/javascript" src = "js/app.js"> 55 </script> 56 </body> 57 </html>
js代码如下
1 var myApp = angular.module('myApp', []); 2 myApp.directive('ensureUnique', ['$http', function($http) { 3 return { 4 require: 'ngModel', 5 link: function(scope, ele, attrs, c) { 6 scope.$watch(attrs.ngModel, function() { 7 $http({ 8 method: 'POST', 9 url: '/api/check/' + attrs.ensureUnique, 10 data: {'field': attrs.ensureUnique} 11 }).success(function(data, status, headers, cfg) { 12 c.$setValidity('unique', data.isUnique); 13 }).error(function(data, status, headers, cfg) { 14 c.$setValidity('unique', false); 15 }); 16 }); 17 } 18 }; 19 }]);
在提交后显示验证信息
当用户试图提交表单时,你可以在作用域中捕获到一个submitted值,然后对表单内容进行
验证并显示错误信息。
例如,修改一下前面的例子,只在用户提交表单时才显示错误信息。在ng-show指令中加入
对表单是否进行了提交的检查(后面会实现这个功能):
<form name="signup_form"
novalidate
ng-submit="signupForm()"
ng-controller="signupController">
<fieldset>
<legend>Signup</legend>
<div class="row">
<div class="large-12 columns">
<label>Your name</label>
<input type="text"
placeholder="Name"
name="name"
ng-model="signup.name"
ng-minlength="3"
ng-maxlength="20" required />
<div class="error"
ng-show="signup_form.name.$dirty && signup_form.name.$invalid &&
signup_form.submitted">
<small class="error"
ng-show="signup_form.name.$error.required">
Your name is required.
</small>
<small class="error"
ng-show="signup_form.name.$error.minlength">
Your name is required to be at least 3 characters
</small>
<small class="error"
ng-show="signup_form.name.$error.maxlength">
Your name cannot be longer than 20 characters
</small>
</div>
</div>
</div>
<button type="submit" >Submit</button>
</fieldset>
</form>
现在,仅当signup_form.submitted设置为true时,容纳错误信息的div才会展示出来。在
signupForm操作中实现这个行为,如下所示:
app.controller('signupController', function($scope) {
$scope.submitted = false;
$scope.signupForm = function() {
if ($scope.signup_form.$valid) {
// 正常提交
} else {
$scope.signup_form.submitted = true;
}
}
});
在失焦后显示验证信息
如果想保留实时错误提示的体验,可以在用户从某个输入字段失焦后提示错误信息(例如用
户已经不在某个特定的输入字段中时)。为了实现这个效果,需要实现一个不是很复杂的指令,
并向表单中添加一个新的变量。
我们需要使用的指令是ngFocus,它是这样的:
app.directive('ngFocus', [function() {
var FOCUS_CLASS = "ng-focused";
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attrs, ctrl) {
ctrl.$focused = false;
element.bind('focus', function(evt) {
element.addClass(FOCUS_CLASS);
scope.$apply(function() {
ctrl.$focused = true;
});
}).bind('blur', function(evt) {
element.removeClass(FOCUS_CLASS);
scope.$apply(function() {
ctrl.$focused = false;
});
});
}
};
}]);
将ngFocus指令添加到input元素上就可以使用这个指令,如下所示:
<input ng-class="{error: signup_form.name.$dirty && signup_form.name.$invalid}"
type="text"
placeholder="Name"
name="name"
ng-model="signup.name"
ng-minlength="3"
ng-maxlength="20" required ng-focus />
ngFocus指令给表单输入字段的blur和focus添加了对应的行为,添加了一个名为ng-focus
ed的类,并将$focused的值设置为true。接下来,可以根据表单是否具有焦点来展示独立的错
误信息。如下所示:
<div class="error"
ng-show="signup_form.name.$dirty && signup_form.name.$invalid && !signup_form.name.$focused">
在线示例:http://jsbin.com/ePomUnI/7/edit。
也可以在ngModel控制器中使用$isEmpty()方法来判断输入字段是否为空。当输入字段为空
这个方法会返回true,反之如果不为空则返回false。