iT邦幫忙

DAY 7
2

我在前端 ng 時系列 第 7

AngularJS Forms 的經驗談

最近的專案才有機會接觸到 form,也瞭解了 form 幫忙做驗證的強大功能。

記錄一些我在開發 form 的經驗跟簡單的 custom validation。

--------------------------

首先,以下需要注意的點:

  1. 使用 form validation 的時候,注意 input 一定要在放在 form 裡面,form validation 才會有作用!

  2. from 一定有要 name attribute。

  3. 在使用 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*$/;

上一篇
ng-if & ng-show
下一篇
自己的 input 自己驗證
系列文
我在前端 ng 時30

尚未有邦友留言

立即登入留言