AngularJs 表單字段合法性校驗(yàn)
基于AngularJS入門(mén)與進(jìn)階(江榮波 著)這本書(shū)的筆記
AngularJS 1.x的demo
AngularJS1.x和Angular2,4,5是不一樣的兩個(gè)東西烛谊,構(gòu)建方式茴恰,語(yǔ)法肴沫,都很多不同
參考文章:https://www.oschina.net/translate/angularjs-form-validation
在AngularJs要使用自帶的表單驗(yàn)證泌绣,只需要在頁(yè)面定義一個(gè)<form>
標(biāo)簽司忱,然后定義表單氓奈,再使用ng-model
進(jìn)行數(shù)據(jù)的雙向綁定就可以了痹籍。
CSS樣式與狀態(tài)對(duì)應(yīng)的屬性關(guān)系
CSS樣式 | 狀態(tài)屬性 | 描述 |
---|---|---|
ng-valid | $valid | 表單輸入合法 |
ng-invalid | $invalid | 表單輸入不合法 |
ng-pristine | $pristine | 表單元素未被使用 |
ng-dirty | $dirty | 表單元素被使用 |
ng-touched | $touched | 元素獲取焦點(diǎn) |
ng-untouched | $untouched | 元素失去焦點(diǎn) |
ng-empty | $empty | 元素內(nèi)容為空 |
AngularJs表單常用校驗(yàn)相關(guān)屬性和指令
校驗(yàn)名 | 指令名 | 示例 |
---|---|---|
必填 | required | <input type="text" required> |
最小長(zhǎng)度 | ng-minlength="{number}" | <input type="text" ng-minlength="10"> |
最大長(zhǎng)度 | ng-maxlength="{number}" | <input type="text" ng-maxlength="10"> |
正則匹配 | ng-pattern="/pattern/" | <input type="text" ng-pattern="[0-9]"> |
郵箱格式 | type = "email" | <input type="email" ng-model="user.email"> |
數(shù)字格式 | type = "number" | <input type="number" ng-model="user.age"> |
網(wǎng)址格式 | type = "url" | <input type="url" ng-model="user.url"> |
首先假設(shè)有個(gè)注冊(cè)頁(yè)面的場(chǎng)景瞬欧,有個(gè)用戶(hù)注冊(cè)頁(yè)面
- 用戶(hù)名必填
- 密碼只能是數(shù)字或者英文字母
- 密碼長(zhǎng)度8到16位
- 郵箱必須格式合法
ng-show
和ng-messages
指令
表單驗(yàn)證如果不通過(guò)贷屎,我們通常需要給用戶(hù)提示出對(duì)應(yīng)的錯(cuò)誤信息,ng-show
指令可以在ng-show="false"
的時(shí)候控制顯示和隱藏艘虎,true為顯示唉侄,false為隱藏,上面表格也說(shuō)了可以通過(guò)$invalid
獲取到當(dāng)前文本框是否合法的boolean
如果是單條錯(cuò)誤提示可以用ng-show實(shí)現(xiàn)野建,有時(shí)候我們一個(gè)文本框有過(guò)多個(gè)驗(yàn)證属划,需要提示,可以用ng-messages指令贬墩,當(dāng)檢測(cè)到不合法的時(shí)候榴嗅,會(huì)順序顯示第一條不合法的提示信息,如果需要使用ng-message指令陶舞,必須在module中引入ngMessages,并且頁(yè)面引入angular-messages.js
一個(gè)簡(jiǎn)單控制器 app.js
var formApp = angular.module("formApp",["ngMessages"]);
formApp.controller("formController",function ($scope,$log) {
$scope.submitValid = function (isValid) {
if(!isValid) {
$('#showMsg').text("驗(yàn)證不通過(guò)嗽测,請(qǐng)檢查!");
$('#showMsgDiv').modal();
}
}
});
demo頁(yè)面 index.html
<!DOCTYPE html>
<html lang="en" ng-app="formApp">
<head>
<meta charset="UTF-8">
<title>表單驗(yàn)證</title>
<link rel="stylesheet" href="/bootstrap-3.3.7/dist/css/bootstrap.css">
<link rel="stylesheet" href="/bootstrap-3.3.7/dist/css/bootstrap-theme.min.css">
<script src="/lib/angular/angular.js"></script>
<script src="/lib/angular-messages/angular-messages.js"></script>
<script src="../../js/jquery-1.9.1/jquery.js"></script>
<script src="/bootstrap-3.3.7/dist/js/bootstrap.js"></script>
<script src="app.js"></script>
<style>
body
{ padding-top:30px;
padding-left: 600px;
}
</style>
</head>
<body ng-controller="formController">
<di class = 'page-header'><h3>AngularJs 表單驗(yàn)證</h3></di>
<!-- novalidate 禁用自帶的驗(yàn)證規(guī)則-->
<form name ='userForm' novalidate ng-submit="submitValid(userForm.$valid)" style="width: 300px;">
<div class="form-group" style="height: 70px;">
<label>用戶(hù)名</label>
<input type="text" class="form-control" name="userName" ng-model="userName" required>
<!--必填單純判斷會(huì)在頁(yè)面加載的時(shí)候就顯示錯(cuò)誤提示肿孵,可以先判斷表單是否未使用$pristine 可以避免頁(yè)面加載進(jìn)來(lái)就提示錯(cuò)誤-->
<span ng-show="userForm.userName.$invalid && !userForm.userName.$pristine" class="help-block">必填項(xiàng)</span>
</div>
<div class="form-group" style="height: 70px;">
<label>密碼</label>
<input type="text" class="form-control" name="password" ng-model="password"
ng-pattern="/^[A-Za-z0-9]+$/" ng-minlength="8" ng-maxlength="16">
<!--這里有2個(gè)驗(yàn)證規(guī)則唠粥,第一個(gè)是只能是數(shù)字或者字母,第二個(gè)是長(zhǎng)度要在8-16位 使用ng-messages優(yōu)先提示格式停做,然后提示長(zhǎng)度-->
<div ng-messages="userForm.password.$error" >
<span ng-message="pattern">密碼只能是數(shù)字或英文字母</span>
<span ng-message="minlength">密碼長(zhǎng)度最短8位</span>
<span ng-message="maxlength">密碼長(zhǎng)度最長(zhǎng)16位</span>
</div>
</div>
<div class="form-group" style="height: 70px;">
<label>郵箱</label>
<input type="email" class="form-control" name="email" ng-model="email" >
<span ng-show="userForm.email.$invalid && !userForm.email.$pristine" class="help-block">郵箱格式錯(cuò)誤</span>
</div>
<button type="submit" class="btn btn-primary">提交</button>
</form>
<!-- 模態(tài)彈出窗 -->
<div class="modal fade" id="showMsgDiv">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title">提示信息</h4>
</div>
<div class="modal-body">
<p id="showMsg"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">關(guān)閉</button>
<!--<button type="button" class="btn btn-primary">保存</button>-->
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</body>
</html>
失去焦點(diǎn)時(shí)驗(yàn)證
從頁(yè)面驗(yàn)證可以看出所有驗(yàn)證都是生效的了的晤愧,也按照我們的預(yù)期在驗(yàn)證,基于AngularJs的數(shù)據(jù)雙向綁定蛉腌,我們發(fā)現(xiàn)我們所有的驗(yàn)證都是及時(shí)生效的官份,這在大多數(shù)情況下是期望的只厘,不過(guò)在注冊(cè)這種情況下,我們不期望在用戶(hù)輸入的過(guò)程中就提示舅巷,期望是文本框失去焦點(diǎn)或者提交的時(shí)候驗(yàn)證羔味。
ng-model-options
和 ng-blur
與ng-focus
如果要達(dá)到獲取焦點(diǎn)或失去焦點(diǎn)的時(shí)候驗(yàn)證的方式比較多,這里舉例兩種钠右,ng-model-options
和 ng-blur
與ng-focus
赋元。
首先我們做了個(gè)變量change,在通過(guò)ng-blur
與ng-focus
在獲取或失去焦點(diǎn)的時(shí)候改變這個(gè)值,讓ng-show指令中的表達(dá)式在失去焦點(diǎn)的時(shí)候才成立往下驗(yàn)證
對(duì)像中的blur,給對(duì)象添加一個(gè)判斷當(dāng)前輸入框是否失去焦點(diǎn)的屬性 userForm.email.$error.blur
飒房,再用input的事件ng-focus搁凸,ng-blur來(lái)動(dòng)態(tài)改變這個(gè)值。
<div class="form-group" style="height: 70px;">
<label>郵箱</label>
<input type="email" class="form-control" name="email" ng-model="email"
ng-blur="change=true" ng-focus="change=false">
<span ng-show="change && userForm.email.$invalid && !userForm.email.$pristine" class="help-block">郵箱格式錯(cuò)誤</span>
</div>
還可以用ng-model-option
狠毯,在默認(rèn)情況下护糖,任何內(nèi)容的改變將觸發(fā)表單驗(yàn)證和model的更新。ngModelOptions指令綁定到一個(gè)事件集合中來(lái)重寫(xiě)觸發(fā)的時(shí)間垃你,例如:ng-model-options="{ updateOn: 'blur' }" 將會(huì)在控件失去焦點(diǎn)后執(zhí)行表單驗(yàn)證和更新Model椅文。你可以使用空格來(lái)分割多個(gè)事件的觸發(fā)驗(yàn)證和更新的時(shí)間。例如:ng-model-options="{ updateOn: 'mousedown blur' }"惜颇。
<div class="form-group" style="height: 70px;">
<label>密碼</label>
<input type="text" class="form-control" name="password" ng-model="password"
ng-pattern="/^[A-Za-z0-9]+$/" ng-minlength="8" ng-maxlength="16"
ng-model-options="{ updateOn: 'blur' }">
<!--這里有2個(gè)驗(yàn)證規(guī)則皆刺,第一個(gè)是只能是數(shù)字或者字母,第二個(gè)是長(zhǎng)度要在8-16位 使用ng-messages優(yōu)先提示格式凌摄,然后提示長(zhǎng)度-->
<div ng-messages="userForm.password.$error" >
<span ng-message="pattern" class="help-block">密碼只能是數(shù)字或英文字母</span>
<span ng-message="minlength" class="help-block">密碼長(zhǎng)度最短8位</span>
<span ng-message="maxlength" class="help-block">密碼長(zhǎng)度最長(zhǎng)16位</span>
</div>
</div>
ng-class
動(dòng)態(tài)改變文本框樣式
在驗(yàn)證的時(shí)候我們還期望錯(cuò)誤的文本框改變顏色羡蛾,ng-class
允許我們基于一個(gè)表達(dá)式添加類(lèi)。因?yàn)槲覀兪褂昧?Bootstrap, 我們將就使用它們提供的類(lèi)(has-error)
<div class="form-group" style="height: 70px;" ng-class="{'has-error' : userForm.userName.$invalid && !userForm.userName.$pristine}">
<label>用戶(hù)名</label>
<input type="text" class="form-control" name="userName" ng-model="userName" required
ng-model-options="{ updateOn: 'blur' }">
<!--必填單純判斷會(huì)在頁(yè)面加載的時(shí)候就顯示錯(cuò)誤提示锨亏,可以先判斷表單是否未使用$pristine 可以避免頁(yè)面加載進(jìn)來(lái)就提示錯(cuò)誤-->
<span ng-show="userForm.userName.$invalid && !userForm.userName.$pristine" class="help-block">必填項(xiàng)</span>
</div>
<div class="form-group" style="height: 70px;" ng-class="{'has-error' : userForm.password.$invalid && !userForm.password.$pristine}">
<label>密碼</label>
<input type="text" class="form-control" name="password" ng-model="password"
ng-pattern="/^[A-Za-z0-9]+$/" ng-minlength="8" ng-maxlength="16"
ng-model-options="{ updateOn: 'blur' }">
<!--這里有2個(gè)驗(yàn)證規(guī)則痴怨,第一個(gè)是只能是數(shù)字或者字母,第二個(gè)是長(zhǎng)度要在8-16位 使用ng-messages優(yōu)先提示格式器予,然后提示長(zhǎng)度-->
<div ng-messages="userForm.password.$error" >
<span ng-message="pattern" class="help-block">密碼只能是數(shù)字或英文字母</span>
<span ng-message="minlength" class="help-block">密碼長(zhǎng)度最短8位</span>
<span ng-message="maxlength" class="help-block">密碼長(zhǎng)度最長(zhǎng)16位</span>
</div>
</div>
下面是完整的html,app.js沒(méi)做改變
<!DOCTYPE html>
<html lang="en" ng-app="formApp">
<head>
<meta charset="UTF-8">
<title>表單驗(yàn)證</title>
<link rel="stylesheet" href="/bootstrap-3.3.7/dist/css/bootstrap.css">
<link rel="stylesheet" href="/bootstrap-3.3.7/dist/css/bootstrap-theme.min.css">
<script src="/lib/angular/angular.js"></script>
<script src="/lib/angular-messages/angular-messages.js"></script>
<script src="../../js/jquery-1.9.1/jquery.js"></script>
<script src="/bootstrap-3.3.7/dist/js/bootstrap.js"></script>
<script src="app.js"></script>
<style>
body
{ padding-top:30px;
padding-left: 600px;
}
</style>
</head>
<body ng-controller="formController">
<di class = 'page-header'><h3>AngularJs 表單驗(yàn)證</h3></di>
<!-- novalidate 禁用自帶的驗(yàn)證規(guī)則-->
<form name ='userForm' novalidate ng-submit="submitValid(userForm.$valid)" style="width: 300px;">
<div class="form-group" style="height: 70px;" ng-class="{'has-error' : userForm.userName.$invalid && !userForm.userName.$pristine}">
<label>用戶(hù)名</label>
<input type="text" class="form-control" name="userName" ng-model="userName" required
ng-model-options="{ updateOn: 'blur' }">
<!--必填單純判斷會(huì)在頁(yè)面加載的時(shí)候就顯示錯(cuò)誤提示浪藻,可以先判斷表單是否未使用$pristine 可以避免頁(yè)面加載進(jìn)來(lái)就提示錯(cuò)誤-->
<span ng-show="userForm.userName.$invalid && !userForm.userName.$pristine" class="help-block">必填項(xiàng)</span>
</div>
<div class="form-group" style="height: 70px;" ng-class="{'has-error' : userForm.password.$invalid && !userForm.password.$pristine}">
<label>密碼</label>
<input type="text" class="form-control" name="password" ng-model="password"
ng-pattern="/^[A-Za-z0-9]+$/" ng-minlength="8" ng-maxlength="16"
ng-model-options="{ updateOn: 'blur' }">
<!--這里有2個(gè)驗(yàn)證規(guī)則,第一個(gè)是只能是數(shù)字或者字母乾翔,第二個(gè)是長(zhǎng)度要在8-16位 使用ng-messages優(yōu)先提示格式爱葵,然后提示長(zhǎng)度-->
<div ng-messages="userForm.password.$error" >
<span ng-message="pattern" class="help-block">密碼只能是數(shù)字或英文字母</span>
<span ng-message="minlength" class="help-block">密碼長(zhǎng)度最短8位</span>
<span ng-message="maxlength" class="help-block">密碼長(zhǎng)度最長(zhǎng)16位</span>
</div>
</div>
<div class="form-group" style="height: 70px;" ng-class="{'has-error' : change && userForm.email.$invalid && !userForm.email.$pristine}">
<label>郵箱</label>
<input type="email" class="form-control" name="email" ng-model="email"
ng-blur="change=true" ng-focus="change=false">
<span ng-show="change && userForm.email.$invalid && !userForm.email.$pristine" class="help-block">郵箱格式錯(cuò)誤</span>
</div>
<button type="submit" class="btn btn-primary">提交</button>
</form>
<!-- 模態(tài)彈出窗 -->
<div class="modal fade" id="showMsgDiv">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title">提示信息</h4>
</div>
<div class="modal-body">
<p id="showMsg"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">關(guān)閉</button>
<!--<button type="button" class="btn btn-primary">保存</button>-->
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</body>
</html>
提交時(shí)驗(yàn)證
提交時(shí)驗(yàn)證的原理也是通過(guò)angularJS的雙向數(shù)據(jù)綁定原理,這里因?yàn)樽隽伺袛辔谋究蚴欠袷褂梅磁ǎ薷奶峤坏尿?yàn)證方法萌丈,在提交的時(shí)候把所有文本框設(shè)置為已經(jīng)使用,然后還做了個(gè)全局變量雷则,是否提交辆雾,控制ng-show和ng-messages 判斷表達(dá)式
app.js
var formApp = angular.module("formApp",["ngMessages"]);
formApp.controller("formController",function ($scope,$log) {
// 失去焦點(diǎn)驗(yàn)證變量
$scope.changeFlagBon = false;
// 提交變量
$scope.isSubmit = false;
// form 提交時(shí)的方法
$scope.submitValid = function (isValid,userForm) {
if(!isValid) {
// 提交的時(shí)候所有的輸入框都設(shè)置為已經(jīng)使用
userForm.userName.$pristine =false;
userForm.password.$pristine =false;
userForm.email.$pristine =false;
$scope.changeFlagBon = true;
// 處理更詳細(xì)的驗(yàn)證
// 提交變量設(shè)置為已經(jīng)提交
$scope.isSubmit = true;
$('#showMsg').text("驗(yàn)證不通過(guò),請(qǐng)檢查月劈!");
$('#showMsgDiv').modal();
}else {
// 處理提交邏輯
}
}
// ng-blur ng-focus 獲取焦點(diǎn)度迂,失去焦點(diǎn)方法
$scope.changeFlag = function (flag) {
$scope.changeFlagBon = flag;
}
});
index.html
<!DOCTYPE html>
<html lang="en" ng-app="formApp">
<head>
<meta charset="UTF-8">
<title>表單驗(yàn)證</title>
<link rel="stylesheet" href="/bootstrap-3.3.7/dist/css/bootstrap.css">
<link rel="stylesheet" href="/bootstrap-3.3.7/dist/css/bootstrap-theme.min.css">
<script src="/lib/angular/angular.js"></script>
<script src="/lib/angular-messages/angular-messages.js"></script>
<script src="../../js/jquery-1.9.1/jquery.js"></script>
<script src="/bootstrap-3.3.7/dist/js/bootstrap.js"></script>
<script src="app.js"></script>
<style>
body
{ padding-top:30px;
padding-left: 600px;
}
</style>
</head>
<body ng-controller="formController">
<di class = 'page-header'><h3>AngularJs 表單驗(yàn)證</h3></di>
<!-- novalidate 禁用自帶的驗(yàn)證規(guī)則-->
<form name ='userForm' novalidate ng-submit="submitValid(userForm.$valid,userForm)" style="width: 300px;">
<div class="form-group" style="height: 70px;" ng-class="{'has-error' : userForm.userName.$invalid && !userForm.userName.$pristine}">
<label>用戶(hù)名</label>
<input type="text" class="form-control" name="userName" ng-model="userName" required
ng-model-options="{ updateOn: 'blur' }">
<!--必填單純判斷會(huì)在頁(yè)面加載的時(shí)候就顯示錯(cuò)誤提示藤乙,可以先判斷表單是否未使用$pristine 可以避免頁(yè)面加載進(jìn)來(lái)就提示錯(cuò)誤-->
<span ng-show="userForm.userName.$invalid && !userForm.userName.$pristine" class="help-block">必填項(xiàng)</span>
</div>
<div class="form-group" style="height: 70px;" ng-class="{'has-error' :isSubmit && userForm.password.$invalid && !userForm.password.$pristine}">
<label>密碼</label>
<input type="text" class="form-control" name="password" ng-model="password" required
ng-pattern="/^[A-Za-z0-9]+$/" ng-minlength="8" ng-maxlength="16"
ng-model-options="{ updateOn: 'blur' }">
<!--這里有2個(gè)驗(yàn)證規(guī)則,第一個(gè)是只能是數(shù)字或者字母英岭,第二個(gè)是長(zhǎng)度要在8-16位 使用ng-messages優(yōu)先提示格式湾盒,然后提示長(zhǎng)度-->
<div ng-messages="userForm.password.$error" ng-if="isSubmit">
<span ng-message="pattern" class="help-block">密碼只能是數(shù)字或英文字母</span>
<span ng-message="minlength" class="help-block">密碼長(zhǎng)度最短8位</span>
<span ng-message="maxlength" class="help-block">密碼長(zhǎng)度最長(zhǎng)16位</span>
<span ng-message="required" class="help-block">密碼必填</span>
</div>
</div>
<div class="form-group" style="height: 70px;" ng-class="{'has-error' : changeFlagBon && userForm.email.$invalid && !userForm.email.$pristine}">
<label>郵箱</label>
<input type="email" class="form-control" name="email" ng-model="email" required
ng-blur="changeFlag(true)" ng-focus="changeFlag(false)">
<span ng-show="changeFlagBon && userForm.email.$invalid && !userForm.email.$pristine" class="help-block">郵箱格式錯(cuò)誤</span>
</div>
<button type="submit" class="btn btn-primary">提交</button>
</form>
<!-- 模態(tài)彈出窗 -->
<div class="modal fade" id="showMsgDiv">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title">提示信息</h4>
</div>
<div class="modal-body">
<p id="showMsg"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">關(guān)閉</button>
<!--<button type="button" class="btn btn-primary">保存</button>-->
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</body>
</html>