angularjs 表單驗證
進行表單驗證時,第一步要確認form表單有name屬性,eg. <form name='myForm'></form>
,最好屏蔽掉瀏覽器的默認表單驗證:novalidate.
input上的所有驗證選項:
1. 必填項
驗證必填項,直接在input元素內加上:‘required’
<input type=text required>
2. 最小長度
直接在input元素上加:ng-minlength=’{number}’
<input type=text ng-minlength='5'/>
3. 最大長度
加:ng-maxlength=’{number}’
<input type=text ng-maxlength='15'/>
4. 模式匹配
加:ng-pattern=’/pattern/’ 來匹配正則表達式
<input type=text ng-pattern='[a-zA-Z]'/>
5. 電子郵件
將input的type值設置爲email.
<input type=email name=email ng-model=user.email/>
6. 數字
經input的type值設置爲number
<input type=number name=age ng-model=user.age/>
當驗證電話號碼時,只有11位數字,使用maxlength屬性會與type=number相沖突,導致maxlength失效,解決辦法是,將type=tel, maxlength=11, 再用正則/[0-9]/i.test(input.value)來判斷輸入是否爲數字。
7. URL
將input的type值設置爲url
<input type=url name=homepage ng-model=user.feedback_url/>
8. 自定義驗證
稍後詳細說明
訪問表單屬性
用下面格式訪問部分表單屬性方法:
表單名稱.輸入項名稱.屬性名
formName.inputFieldName.property
- 未修改過表單:formName.inputFieldName.$pristine
- 修改過表單:formName.inputFieldName.$dirty
- 合法表單:formName.inputFieldName.$valid
- 不合法表單:formName.inputFieldName.$invalid
- 錯誤表單:formName.inputFieldName.$error
Angular在處理這些信息時,會給表單增加上對應的CSS類。
自定義表單驗證
當用戶同控制器進行交互,並且ngModelController中的$setViewValue()方法被調用時,$parsers數組中的函數會以流水線的形式被逐個調用。第一個$parse被調用後,執行結果會傳遞給第二個$parse,以此類推。
使用$parsers數組是實現自定義驗證的途徑之一。例如,假設我們想要確保輸入值在某兩個數值之間,可以在$parsers數組中入棧一個新的函數,這個函數會在驗證鏈中被調用。
eg:
link: function(scope, ele, attrs, ctrl) {
var url = attrs.ensureUnique;
ctrl.$parsers.push(function(val) {
if (!val || val.length === 0) {
return;
}
}
一般情況將自定義表單驗證方法寫入指令:
$setValidity:ctrl.$setValidity(errorName, boolean)
用來設置錯誤標誌。
html:
<input phone-validate name='phone' type="tel" ng-model="phoneNumber" maxlength="11"/>
<span class='error' ng-show="myForm.phone.$dirty && myForm.phone.$invalid" style="color:red">
<span ng-show="myForm.phone.$error.phoneLength">必須爲11位數字</span>
</span>
js:
app.directive('phoneValidate',function(){
return{
restrict:'A',
require:'ngModel',
link:function($scope,ele,attrs,ctrl){
$scope.$watch(attrs.ngModel,function(newValue){
if(!newValue) return;
if(ele.val().length==11&& /[0-9]/i.test(ele.val())){
/*
* $setValidity 用來設置$error錯誤標誌
* $setValidity(errorName, true/false)
* 可以經過$error[errorName]來訪問
* 並可以改變$invalid, $valid值
* */
ctrl.$setValidity('phoneLength',true)
}else{
ctrl.$setValidity('phoneLength',false);
}
})
}
}
})
失焦後驗證
創建一個ngFocus指令,監控ctrl.$focused的變化。
html:
<input phone-validate type='tel' maxlength="11" name="phone" ng-model="user.phone" required class="form-control" placeholder="輸入手機號" ng-focus/>
<span style="color:red" ng-show="myForm.phone.$dirty && myForm.phone.$invalid&& !myForm.phone.$focused ">
<span ng-show="myForm.phone.$error.phoneLength">必須爲11位數字</span>
</span>
js:
app.directive('ngFocus',function(){
return{
restrict:'A',
require:'ngModel',
link:function(scope,elem,attr,ctrl){
ctrl.$focused=false;
elem.bind('focus',function(){
elem.addClass('focused');
scope.$apply(function(){ ctrl.$focused=true})
}).bind('blur',function(){
elem.removeClass('focused');
/*注意scope.$apply()方法的調用,目的是讓視圖裏相關內容隨時更新。*/
scope.$apply(function(){
ctrl.$focused=false;})
})
}
}
});
使用ngMessages插件:
<div class="error" ng-messages="myForm.name.$error" ng-messages-multiple>
<div ng-message="required"> sure you enter your name</div>
<div ng-message="minlength">Your name must be at least 3 characters</div>
<div ng-message="maxlength">Your name cannot be longer than 20 characters</div>
</div>
使用ngMessage插件時,若自定義驗證指令,必須將錯誤消息自定義到ngModel中,而不是控制器中。
HTML:
<form name="signup_form" novalidate ng-submit="signupForm()" ng-controller="signupController"
ensure-unique="/api/checkUsername.json">
<label>
Your name
</label>
<input type="text" placeholder="Username" name="username" ng-model="signup.username"
ng-minlength=3 ng-maxlength=20 required />
<div class="error" ng-messages="signup_form.username.$error">
<div ng-message="required">
Make sure you enter your username
</div>
<div ng-message="checkingAvailability">
Checking...
</div>
<div ng-message="usernameAvailablity">
The username has already been taken. Please choose another
</div>
</div>
<button type="submit">
Submit
</button>
</form>
JS:
app.directive('ensureUnique', function($http) {
return {
require: 'ngModel',
link: function(scope, ele, attrs, ctrl) {
var url = attrs.ensureUnique;
ctrl.$parsers.push(function(val) {
if (!val || val.length === 0) {
return;
}
ngModel.$setValidity('checkingAvailability', true);
ngModel.$setValidity('usernameAvailablity', false);
$http({
method: 'GET',
url: url,
params: {
username: val
}
}).success(function() {
ngModel
.$setValidity('checkingAvailability', false);
ngModel
.$setValidity('usernameAvailablity', true);
})['catch'](function() {
ngModel
.$setValidity('checkingAvailability', false);
ngModel
.$setValidity('usernameAvailablity', false);
});
return val;
})
}
}
});
使用angular-validation.js插件
- 引入js文件
- 依賴注入app. eg.
var app=angular.module('app',['ui.router','ngCookies','validation']);
- 可以使用內置驗證方法,或者自定義:
如下列:
angular.module('app').config(['$validationProvider', function($validationProvider) {
var expression = {
phone: /^1[\d]{10}$/,
password: function(value) {
var str = value + '';
return str.length > 5;
},
required: function(value) {
return !!value;
}
};
var defaultMsg = {
phone: {
success: '',
error: '必須是11位手機號'
},
password: {
success: '',
error: '長度至少6位'
},
required: {
success: '',
error: '不能爲空!'
}
};
$validationProvider.setExpression(expression).setDefaultMsg(defaultMsg);
}]);
validataion.js API:
https://github.com/hueitan/angular-validation/blob/master/API.md