最近的專案才有機會接觸到 form,也瞭解了 form 幫忙做驗證的強大功能。
記錄一些我在開發 form 的經驗跟簡單的 custom validation。
--------------------------
首先,以下需要注意的點:
使用 form validation 的時候,注意 input 一定要在放在 form 裡面,form validation 才會有作用!
from 一定有要 name attribute。
在使用 form 的時候要加 novalidate attribute。防止瀏覽器原生的驗證。
-----------------------------
form 提供了對 input 跟 select 等驗證功能。
先談談 select。
ng-options + ng-model:ng-options 在建立的過程中有點像是 ng-repeat,幫你從指定的 array 跟 object 重複產生對應的 options element。
官網範例
only ng-model:在 select element 中設定 ng-model,並直接把 options value 寫死。
範例:[http://plnkr.co/edit/CMocAYHE0tY7kW6chEP5?p=preview](http://plnkr.co/edit/CMocAYHE0tY7kW6chEP5?p=preview" style="text-decoration: underline;)
心得: 注意 option 的 value 是會比對 type 的 ( === 的概念)
範例:http://plnkr.co/edit/iKDxQ0ayJnnA7ymRJddg?p=preview
app.controller('myCtrl', function ($scope){
var ctrl = this;
ctrl.list = [{
code: '200',
place: '基隆'
},{
code: '220',
place: '新北市'
}]
ctrl.selectValue = 200;
})
<form name="myForm" novalidate>
<!-- default value should be set -->
<select name="mySelect" ng-model="Ctrl.selectValue"
ng-options="item.code as item.place for item in Ctrl.list">
</select>
</form>
在範例中,controller 中定義的預設值 (selectValue) 是 200,
可是 select 卻沒有顯示應該要有的預設值 (例子中,就是 ”基隆“ )
原因就是因為我們給的預設值 type 是 number,可是在 ctrl.list 對應的 code type 是 string。
兩者因為 type 不同,所以 ng-model 找不到在 ng-options 對應的 default select value。
把 selectValue 改成 string type (範例) 或 code type 改成 number (範例) 問題就解決了。
ng-input 是個有趣的東西,範例可以上官網學習。
這次我主要想先寫有關 ng-pattern 的用法。
ng-input 目前支援 6 種 input type:checkbox, email, number, radio, text, url。
普通的 text input 就是 text type, AngularJS 在 email, number 跟 url 這三種 type 中幫忙設定 ng-pattern 符合的樣式。(註一)
所以其實 email, number, url 是 AngularJS 幫忙檢查 pattern 給特定的 type。
( 在 IE8 & IE9 也可以 work 噢。)
-----------------
自己定義 ng-pattern:
範例:使用 ng-pattern 驗證身分證字號的 input。
(目前只寫了簡單第一個字是英文字母後面接 9 位數字的檢查。
正確的身分證的驗證是要符合特定 pattern ,有興趣的可以去查查~)
先把 RegExp 定義好:[a-zA-Z][0-9]{9}
ng-pattern 吃下列格式:
1. 使用 regular expression literal 格式在 HTML 裡。
<input type="text" name="idInput" ng-model=“Ctrl.value" ng-pattern="/[a-zA-Z][0-9]{9}/“>
2. 在 scope 中定義 RegExp object。
ctrl.regexp = new RegExp(‘[a-zA-Z][0-9]{9}’)
<input type="text" name="idInput" ng-model=“Ctrl.value" ng-pattern="ctrl.regexp“>
3. 在 scope 中定義 regular expression literal regexp
ctrl.regexp2 = /[a-zA-Z][0-9]{9}/
<input type="text" name="idInput" ng-model=“Ctrl.value" ng-pattern="ctrl.regexp2“>
AngularJS 就會依照 ng-pattern 做驗證,
並且可用 [form name].[input name].$error.pattern = true/false 檢查該 input pattern 是否正確/錯誤.
完整範例 http://plnkr.co/edit/44OTkA6mVK7PuNflrtK9?p=preview
-------------------------------
兩個以上 input validation 是可以一起使用的,
上面範例中,我還有用 required 把 input 設成必要欄位。
也可用 [form name].[input name].$error.required = true/false 檢查
假如不想要使用者在一開始就還沒輸入就看到錯誤訊息,可以使用 $dirty 跟 $pristine value。
ex: [form name].[input name].$dirty: input 已經被使用者輸入過了
$dirty: 使用者已經跟表單有互動了
$pristine: 使用者還沒跟表單有互動
**註一
翻一下 AngularJS source code, 會發現 AngularJS 制定 url, email, number pattern 非常精密。
angular.1.2.20.js
var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/;