最近學了一段時間的Angular,也開使用在現有的專案上,剛好有機會可以幫手邊負責的專案擴充一些Angular的驗證directive。不管是學哪個Library和FrameWork,其實驗證一直是我最不感興趣的東西,但最近在幫手邊的專案作用戶端驗證時,發現Angular的驗證真的非常的方便,擴充自己要的驗證directive也不會太難。
這篇文章會先介紹Agular基本的驗證機制,接下來才會進入如何擴充Angularjs驗證的directive。
首先我們先看個範例,有個表單我們希望使用者名稱和Email為必填,且Email必須符合正確的個式。
那Angular如何幫我們驗證呢? 這裡是這個表單的code
<form name="logOnForm" class="form-horizontal" novalidate>
<input name="userName" type="text" class="form-control" ng-model="userName" required>
<span ng-show="logOnForm.userName.$error.required">
請輸入使用者名稱
</span>
<input name="email" type="email" class="form-control" id="email" placeholder="Email" ng-model="email" required>
<span ng-show="logOnForm.email.$error.required">
請輸入Email
</span>
</form>
預設能使用的驗證
這裡我沒有寫認何一行javascript的code就做好了基本的用戶端驗證
希望欄位是必填欄位,我只需要在表單欄位加上Html5標準的required
屬性,angular就會幫我們驗證該欄位是否合法。那angular提供了哪些基本的驗證呢?
必填
驗證使用者是否輸入值,只要加上簡單的Html5 Attribute required
就能夠使用
<input type="text" ng-model="name" required>
最小長度
驗證使用者輸入的文字是否符合最小長度,我們只要加上ng-minlength
這個directive
<input type="text" ng-model="name" ng-minlength="3">
最大長度
驗證使用者輸入的文字是否符合最大長度,我們只要加上ng-axlength
這個directive
<input type="text" ng-model="name" ng-maxlength="12">
正規表達式
所有angular提供的基本驗證中最有趣的。 我們可以設定正規表達式來進行驗證,使用directive:ng-pattern="/pattern/"
<input type="text" ng-model="name" ng-pattern="/[0-9]/">
數字
必須為數字欄位,只需將type設為number
<input type="number" ng-model="age">
必須為正確的Email,只需將type設為email
<input type="email" ng-model="email">
Url
必須為正確的Url,只需將type設為url
<input type="url" ng-model="url">
表單欄位狀態
那我們要如何知道欄位發生錯誤和定義錯誤訊息呢?
我們可以透過以下的格式取得驗證是否通過
formName.inputFieldName.$error.errorType
例如用logOnForm.userName.$error.required
可以取得下面表單的userName欄位是否通過required驗證,若驗證不過則會取得true,通過則取得false
<form name="logOnForm" class="form-horizontal" novalidate role="form" ng-controller="demo1Ctrl">
<input name="userName" type="text" class="form-control" ng-model="userName" required>
</form>
我們能利用該屬性定義錯誤訊息,若logOnForm.userName.$error.required
為true則顯示,若為false則隱藏
<form name="logOnForm" class="form-horizontal" novalidate>
<input name="userName" type="text" class="form-control" ng-model="userName" required>
<span ng-show="logOnForm.userName.$error.required">請輸入使用者名稱</span>
</form>
取得其他驗證狀態
formName.inputFieldName.$error.required
formName.inputFieldName.$error.email
formName.inputFieldName.$error.url
formName.inputFieldName.$error.maxlength
formName.inputFieldName.$error.minlength
formName.inputFieldName.$error.pattern
除了$error
我們還可以取得其他有用的屬性
$valid
取得該欄位是否通過驗證,若無任何驗證失敗則回傳true,否則回傳false
formName.inputFieldName.$valid;
$invalid
和$valid相反
formName.inputFieldName.$valid;
$pristine
若該input欄位還沒有輸入過值,則為true,否則為false
formName.inputFieldName.$pristine;
$dirty
若該input欄位以經輸入過值,則為true,否則為false
formName.inputFieldName.$dirty;
若我們不希望使用者還沒輸入過表單就出現錯誤訊息,可以用以下技巧
<form name="logOnForm" class="form-horizontal" novalidate>
<input name="userName" type="text" class="form-control" ng-model="userName" required>
<span ng-show="logOnForm.userName.$error.required && logOnForm.userName.$dirty">
請輸入使用者名稱
</span>
</form>
以上這些屬性form也可以取得
例如 formName.$invalid
所以我們可以利用以下技巧防止使用者送出未通過驗證的表單
<form name="logOnForm" class="form-horizontal" novalidate ng-submit="logOn()">
<input name="userName" type="text" class="form-control" ng-model="userName" required>
<span ng-show="logOnForm.userName.$error.required && logOnForm.userName.$dirty">
請輸入使用者名稱
</span>
<input type="submit" ng-disabled="logOnForm.$invalid" />
</form>
或者在Controller裡定義submit事件的方法裡檢查
function formController($scope) {
$scope.logOn = function(){
if($scope.logOnForm.$invalid) return;
//省略
};
}
為表單欄位設計樣式
AngularJs在處理表單的狀態時,會為表單加入各種狀態的class,每個屬性都有對應的class,我們可以根據這些class定義各種狀態的CSS樣式。
ng-pristine
ng-dirty
ng-valid
ng-invalid
ng-valid-errorType
ng-invalid-errorType
我們可以利用這些class來幫我們的表單增加一些色彩
input.ng-invalid{
background-color: #fcf8e3;
border-color: red;
}
input.ng-valid{
border-color: green;
}
<form name="logOnForm" class="form-horizontal" novalidate ng-submit="logOn()">
<input name="userName" type="text" class="form-control" ng-model="userName" required>
<span ng-show="logOnForm.userName.$error.required && logOnForm.userName.$dirty">
請輸入使用者名稱
</span>
<input type="submit" ng-disabled="logOnForm.$invalid" />
</form>
Agularjs的驗證真的非常簡單好用,但光會這些很難應付複雜的應用程式,接下來我會介紹如何建立自己的驗證directive和一些我認為好用的小技巧。