前言 :
這篇寫超久的,大概超過三個禮拜了吧,有點忙啊!
學了那麼久的 AngularJS (學得很慢) 終於學到感覺比較有趣的表單驗證啦!
所以這一篇主要是要來紀錄學習心得 + 如何在網頁表單中使用 AngularJS 來做資料驗證
驗證的話,AngularJS 搭配 HTML5 的一些屬性就可以做到很強大的表單驗證與提示了
目前大部分使用者的瀏覽器幾乎都可接受 HTML5 了,ie9 以下的瀏覽器應該也很難找到
所以使用 HTML5 做驗證應該不是太大的問題
在開始 angularjs 驗證之前先來熟悉一下 HTML5簡單的驗證方式,因為比較簡單
而 angularjs 必須要搭配HTML5 還有formController 的表單狀態屬性和 $error 物件來處理
底下為這篇稍微分類一下
1. HTML5 表單驗證
2.1. FormController 的 Properties 介紹
2.2. 表單驗證的簡單範例
3.1. 表單狀態樣式的應用範例
6. 使用 ASP.Net 傳統 Web Form 開發所遇到的問題
1. HTML5 表單驗證
required
表單送出時會自動檢查該欄位是否有輸入值 (空值也是值),沒輸入值就會像下圖一樣跳出訊息
用法就像下面這樣,用一個屬性取代幾行 javascript 判斷還蠻划算的
placeholder
用來顯示提示文字用 ex : <input type="text" placeholder="請輸入電子郵件" />
上面是使用 placeholder 的文字輸入,下面則是一般的 textbox
<input type="email" />
表單送出時會檢查欄位值是否為正確的 email 格式
ex : <input type="email" />
minlength、maxlength
ex : <input type="text" minlength="3" maxlength="6" />
限制文字輸入的字元數,最多只能輸入6個字,若不足3碼,送出時會跳出提示
<input type="number" />、max、min
輸入格式為數字,然後可以用 max、min 來規範數字的範圍
ex : <input type="number" max="9" min="5" />
<input type="url" />
表單送出時會檢查輸入的值是否為正確的 url 格式
ex : <input type="url" />
pattern
使用規則表示式來驗證
ex : <input type="text" pattern="[A-Za-z0-9]" />
以上例而言就是輸入必須要為A ~ Z、a ~ z、0 ~ 9,不允許特殊符號
以上是一些HTML5內建的簡單驗證,還有很多好用的表單控制請自行參考
HTML5 forms : http://www.w3.org/TR/html5/forms.html#forms
因為 AngularJS 的部分驗證是必需要搭配 HTML5的,所以稍微了解之後就來進入重頭戲
2. AngularJS 表單驗證 - FormController 的 Properties
接下來才是這篇要學習的重點,使用 AngularJS 來做驗證
當使用 AngularJS 來做表單驗證的時候,AngularJS 會建立一個 FormController 來保存表單目前的狀態
並且提供一些方法可以使用,有關於 FormController 可以參考官方文件
https://docs.angularjs.org/api/ng/type/form.FormController
文件中的方法(method)現在還不知道要怎麼使用......還沒學到,這次要看的是屬性 Properties
以下列出 FromController 中的所有屬性 (官網的資料)
Properties
-
$pristine
boolean True if user has not interacted with the form yet.
-
$dirty
boolean True if user has already interacted with the form.
-
$valid
boolean True if all of the containing forms and controls are valid.
-
$invalid
boolean True if at least one containing control or form is invalid.
-
$submitted
boolean True if user has submitted the form even if its invalid.
-
$error
Object Is an object hash, containing references to controls or forms with failing validators, where:
- keys are validation tokens (error names),
-
values are arrays of controls or forms that have a failing validator for given error name.
Built-in validation tokens:
-
email
max
maxlength
min
minlength
number
pattern
required
url
date
datetimelocal
time
week
month
上面的 $submitted 是 1.3 版本才有的,每一個都跟表單的狀態有關
然後 $error 稍微比較特別一些,所以首先先來看看 $error
$error
透過上面的列表可以發現,除了最後一個 $error 是物件之外,其他都是 boolean (ture or false)
使用這些屬性的方法很簡單,就是透過 formName.inputFieldName.Properies
用例子來看最清楚了
ex :
如上面的範例使用 form1.account.$error 取得Properies 裡的 $error 物件
就是透過抓取 form 的名字為 form1,textbox 的名字為 account,然後抓到該屬性的
$error 物件顧名思義就是一個有關錯誤的物件,把抓取到的 $error 物件呈現出來看就會長這樣
裡面的那些參數都是我們設定過的 ng-minlength、ng-maxlength、required,而狀態被 FormController 所記錄下來
可以自行切換到 result 看看變化的結果
所以之後如果要檢查驗證結果就可以直接用下面這方法了
ex : form1.account.$error.required ,就會返回 ture or false
如下面的例子
如官網的文件所寫的,在 $error 物件中可檢查的項目有以下這些,必須要搭配 HTML5來做驗證
也就是說如果要檢查 email,那就是要用 <input type="email" />
想檢查 url 就是要用 <input type="url" />
- max
- maxlength
- min
- minlength
- number
- pattern
- required
- url
- date
- datetimelocal
- time
- week
- month
等等再來挑幾個練習一下,先來看看 $error 之外的 Properties
$pristine
如果該欄位還沒輸入過值,就會返回 true 反之為 false
使用方式也是一樣 : formName.inputFieldName.$pristine
$dirty
若該欄位之前曾經輸入過值就會返回 true (因為用過髒掉了嘛) 反之則是 false
$valid
如果該欄位有通過驗證的話就會返回 true 反之 false
$invalid
若該欄位沒有通過驗證的話就會返回 true 反之 false
$submitted (1.3 新增)
如果表單曾經送出過,不論有沒有通過驗證都會返回 true
2.2 簡單範例
以下就來稍微練習一下如何應用上面的表單屬性吧
練習一、Email 驗證
上面說過 AngularJS 的驗證是要結合 HTML5 的,所以驗證 email 就用了 <input type="email" />
然後結合 ng-class,當發生錯誤就套用 .msg 的樣式,也可以直接用 ng-show 來做顯示與隱藏
HTML :
CSS :
結果如下 :
練習二、ng-minlength、ng-maxlength、ng-pattern 的檢查
下面這個也是自己隨便練習的範例,用來練習帳號長度檢查 + 密碼規則驗證
最後在 submit 按鈕上面綁 ng-disabled,當表單驗證沒通過的話就會回傳 ture 讓按鈕 disabled
ng-pattern 則是用來驗證規則表示式,一樣是 pattern ,在HTML5中則不須輸入開始與結束符號 "/"
如下 :
實際結果 :
再繼續生出其他例子來練習之前,先來稍微停一下.....
以上範例的提示訊息不外乎是HTML5內建、或是搭配使用 ng-class 針對表單狀態而呈現的
例如當密碼輸入規則不符合驗證條件時,就會搭配 ng-class 或是 ng-show 來顯示錯誤訊息
但其實 AngularJS 也有內建表單狀態的樣式,下面先來學一下怎麼使用~
3. AngularJS 表單的狀態樣式
上面有提到表單的驗證中有各種狀態 ex: $valid、$invalid 、$dirty、$pristine.....等
如剛剛上面的範例所示,我們可以使用 ng-class 搭配上面這些表單狀態呈現出不同的提示效果提醒使用者
ex: 未填寫資料,或是與驗證格式不符的話,就將 textbox 變成紅框之類的
但其實除了使用 ng-class 之外,AngularJS 有提供相關狀態的 CSS 來方便使用
可以參考官網這個連結 : https://docs.angularjs.org/api/ng/directive/form
CSS classes
ng-valid
is set if the form is valid.ng-invalid
is set if the form is invalid.ng-pristine
is set if the form is pristine.ng-dirty
is set if the form is dirty.ng-submitted
is set if the form was submitted.
直接來看個簡單的例子好了
HTML :
CSS :
原本的 CSS Selector 後面直接接上 .ng-invalid 之類的狀態 class name 即可
效果如下 :
除了上面用的 .ng-invalid 還有下面這些,基本上是每個狀態都有一個相對應的 class name
輸入狀態 | CSS 類別名稱 |
$invalid | ng-invalid |
$valid | ng-valid |
$pristine | ng-pristine |
$dirty | ng-dirty |
$submitted | ng-submitted |
required | ng-valid-required 或 ng-invalid-required |
min | ng-valid-min 或 ng-invalid-min |
max | ng-valid-max 或 ng-invalid-max |
minlength | ng-valid-minlength 或 ng-invalid-minlength |
maxlength | ng-valid-maxlength 或 ng-invalid-maxlength |
pattern | ng-valid-pattern 或 ng-invalid-pattern |
url | ng-valid-url 或 ng-invalid-url |
ng-valid-email 或 ng-invalid-email | |
date | ng-valid-date 或 ng-invalid-date |
number | ng-valid-number 或 ng-invalid-number |
再來下面用實際的例子來看看怎麼應用
練習一、Email 驗證提醒
這也是一個簡單的範例,主要是利用上面講的狀態 CSS 來簡單做到提示使用者的功能
HTML:
CSS:
上面的範例的 HTML 基本上沒什麼特別的,主要就是必須要輸入 email 格式,主要的提示效果在 CSS 裡
這範例想要做到的效果是....
1. 因為是必填欄位,所以在尚未輸入的時候要是紅框,提醒使用者必填
套用的是這個 CSS: input.ng-invalid (代表input 驗證未通過)
2. 當使用者輸入之後就會檢查是否為正確的 email 格式,如果不是正確的 email 格式,就將背景上色
套用的是這個 CSS: input.ng-dirty.ng-invalid (代表已經輸入過,但是驗證失敗)
3. 如果輸入的 email 是正確的格式就會呈現綠框 ,代表通過驗證
套用的是這個 CSS:input.ng-valid (通過驗證)
實際的結果如下 :
4. 使用 ng-form 的巢狀表單
所謂的巢狀表單指的就是類似這樣的感覺....(當然一個正確的HTML不可能有巢狀 <form>)
就是一個表單內有多個表單群組,就可以針對各群組來進行各別的表單檢查
就像上面範例的檢查方式,可以檢查子表單 formA 與 formB
但是以上的 HTML 是不正確的,因為 HTML 沒有巢狀 form 這東西
所以 AngularJs 提供了 ng-form 來模擬表單
所以上面就可以寫成這樣
這邊有幾個要注意的地方是 :
子表單的狀態可以直接存取 ex : formA.$invalid
也可以由父表單開始存取 ex : formMain.formA.$invalid 兩種方式都 ok 喔
但是子表單也會影響到父表單,例如子表單如果設定了 required 但是卻沒填資料
那父表單 formMain.$invalid 還是會等於 true (驗證失敗的意思)
在 Controller 中檢查表單驗證結果
前面的例子都是在按下送出按鈕前,利用 CSS 來做到提示使用者表單資料是否正確
那如果想要按下按鈕之後在 controller 之中檢查驗證結果,然後做一些事情呢?
方法好像很多種,有些還沒學到....不過先參考參考~
像下面這個
AngularJs can't access form object in controller ($scope)
另一種方法 :
又另一種方法,但需要傳入 form name + event
使用 ASP.Net 傳統 Web Form 開發所遇到的問題
因為我的工作幾乎都是在寫傳統的 Web Form,所以這可以說是我的疑問
後來我去上課後得到了解答,請看這篇 "傳統的 ASP.Net Web Form 適合使用 AngularJS 來開發嗎?"
雖然如此還是來掙扎一下看看硬寫會出什麼事
如果你不是 ASP.Net 傳統 web form 的開發者的話可以跳過這段了
AngularJs 十分適合 ASP.Net MVC 來使用,但是非常不適合用在傳統的 Web Form 開發上
這是因為傳統的 Web Form 需要 postback,頁面一 postback, js 就不見啦
但如果你還是想要硬寫在傳統 web form 的話,就來看看以下可能會遇到的問題
第一個問題是,傳統 Web Form 所產生的網頁 form 是沒有 name 屬性的啊!
你就算像下面這樣硬寫也沒用~
編譯完之後就會自動幫你砍掉
為何會這樣咧! 原因如下面這個連結所講的
https://msdn.microsoft.com/zh-tw/library/exc57y7e(v=vs.100).aspx
注意事項: |
---|
form 項目上的 name 屬性在 XHTML 1.1 方針中不允許使用。您可以將應用程式設定為不呈現 name 屬性。如需詳細資訊,請參閱本主題稍後的「控制 ASP.NET 網頁和控制項的呈現」。 |
原因就是ASP.Net 為了全面符合 XHTML 1.1,而 XHTML 1.1 的規範裡面 form 是沒有 name 屬性的
不過你可以使用下面這個連結來改變這個很煩的設定
HOW TO:在 ASP.NET 網站中設定 XHTML 呈現
但是要注意更改了 web.config 之後,ASP.NET 網頁和控制項會將其呈現變更為 ASP.NET 先前版本的行為
包含下面這些.....
- form 項目會使用 name 屬性呈現。
- ASP.NET 不會自動將 form 項目中的 div 項目呈現為控制項的容器。
- 會使用自訂屬性將驗證程式控制項呈現為 span 項目,例如 controltovalidate。
- 除非您明確包含這些屬性,否則 img 項目不會呈現 alt 和 src 屬性。
- 如果需要支援自動回傳行為,控制項會呈現 language 屬性 (例如 language="javascript")。
- 如果控制項的 Wrap 屬性設定為 false,nowrap 屬性會包含在呈現 div 項目的控制項中 (例如 Panel 控制項)。
- ImageButton 控制項呈現 border 屬性。
- 呈現至網頁的任何 br 項目都會呈現為 <br>。然而,如果您明確包含 <br /> 標記,網頁就會依原本的方式呈現它。
- DataGrid 和 Calendar 控制項會將 bordercolor 屬性包含在呈現的 table 項目中 (如果其設定 BackColor 屬性)。
但看到改設定變動這麼大還是不要動的好
這個問題會造成你在做表單檢查的時候無法用 form name 來控制表單狀態
解決方式就是可以使用上面提到的 ng-form 來建立虛擬的 form
第二個遇到的問題就是 ASP.Net 傳統的 Web Form 是需要 submit 後 action 到自己的
按下 submit 之後若沒擋住你前面的 js 就會不見了,所以就勢必要在 <form> 裡面加上 ng-submit 事件
然後在 controller 中用 return false or preventDefault 取消 submit 預設的送出動作
如同這個例子 :
禁止表單送出之後,再利用 AJAX 來做到 CRUD 的效果
但最後的建議還是不要太自虐
ASP.Net 傳統的 Web Form 不要使用 AngularJs 開發比較好
AngularJS 學習筆記系列 : (依本人的上進心持續增加)
AngularJS 初學者筆記與教學 (一) - 使用方式、Expression、Controller、Module
AngularJS 初學者筆記與教學 (二) 內建的簡單指令之1 ng-click、ng-show、ng-hide
AngularJS 初學者筆記與教學 (三) - AngularJS 的載入流程與 ng-cloak 運作原理
AngularJS 初學者筆記與教學 (四) - 如何動態改變 CSS 樣式,使用 ng-class、ng-style
AngularJS 初學者筆記與教學 (五) - 繼續深入學習常用的 ng-repeat
AngularJS 初學者筆記與教學 (新手入門課程 - 課後心得篇)
AngularJS 初學者筆記與教學 (七) - FormController 的表單驗證與資料檢查
留言列表