前幾年介紹過一個不錯的表單驗證外掛「Validator」,最近為了想增進網頁效能,研究一下能否不靠外掛就實現這些複雜功能。 由於 HTML5 已經內建基本的表單驗證功能,效果、質感都滿有水準的,那麼剩下的就是一一想辦法解決實作上容易遇到的情境。 本篇會舉例各種常見的表單項目如何進行驗證,並提供實作範例。 (圖片出處: pxhere.com)
一、強制驗證參數 required
HTML5 表單要觸發驗證的機制有這兩個:- 表單項目的 html 加上
required="required" 參數 - 表單 form 之中必須有送出按鈕
input type="submit"
二、文字 text(電話)
文字輸入是最常見的型態,若要限制輸入的文字格式:- 可使用正規表示式,加上參數
pattern="填入正規表示式參數" - 可限制文字位元數,加上參數
maxlength="填入數字"
<input type="text" required="required" maxlength="11" pattern="09\d{2}-\d{6}"/>
三、日期 date(生日)
HTML5 表單的日期(date)型態內建了日期選擇器,可不用另裝外掛就有不錯的效果。以輸入生日為例,利用一些參數限制輸入範圍,就可避免使用者惡搞,假扮成嬰兒或是古人,以下為範例:<input type="date" min="1900-01-01" max="2021-01-01" required="required"/>
以上的參數限定日期只能輸入 "1900-01-01" 到今年元旦為止,避免出現未來日期以及上古人類。 四、Email
HTML5 表單支援 email 型態,但內建的檢驗功能過於陽春,只能檢測是否輸入了 "@" 符號,無法遏止使用者輸入惡搞、不存在的郵件信箱。 想要得到較佳的檢驗效果,最好使用正規表示式參數,以下為範例程式碼:<input type="email" required="required" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$"/>
以上的參數可限定使用者至少必須輸入 "xxx@xxx.xxx" 這樣的英數字串形式。 五、密碼(包含英數字串)
輸入密碼也是常用的表單項目,但困難的是如何限定輸入字串,避免使用者設定過於簡單的密碼。以下範例程式碼使用的正規表示式,可以限定使用者設定的密碼,至少要使用 6 個位元,至少使用一個英文字元,至少使用一個數字:<input type="password" pattern="^(?=.*[a-zA-Z])(?=.*[0-9]).{6,}$" required="required"/>
六、自訂錯誤訊息
HTML5 表單內建的錯誤訊息大部分情況算是夠用,但我們總是會想要客製自訂的訊息,而且有些情況如果無法提示正確的字串格式,使用者怎麼知道要如何輸入呢? 以「二、文字 text(電話)」為例,我們設定的手機號碼形式 "09xx-xxxxxx" 說不定使用者根本不知道要輸入 "-",那麼錯誤訊息顯示半天使用者依然只輸入 10 個號碼,這個表單可就永遠發送不出去了! HTML5 支援的自訂錯誤訊息為呼叫 setCustomValidity 函數,詳細說明可參考這篇「html5 自訂表單驗證的警示文字 - setCustomValidity」,這篇提到幾個自訂錯誤訊息非常重要的 bug,以及解決方法,請務必詳讀。 這裡只摘錄重點與結論:- 自訂錯誤訊息需利用事件 oninvalid(當驗證錯誤時) 來觸發
- 但只要使用了 oninvalid 且發生錯誤時,使用者每輸入一個字元都會持續跳出錯誤訊息,造成體驗不佳
- 因此設定 oninvalid 事件後,需同時設定 oninput 事件,抹除錯誤訊息
七、驗證密碼
既然前面提供了輸入密碼的例子,那麼表單下一個欄位必定是「驗證密碼」,而這件事要如何做到呢?而且很重要的一點,驗證密碼必須搭配「自訂錯誤訊息」才能讓整個功能完整,以下是範例程式碼:<input id="inputPassword" type="password" pattern="^(?=.*[a-zA-Z])(?=.*[0-9]).{6,}$" required="required" oninput="setCustomValidity('');" oninvalid="setCustomValidity('請輸入正確的密碼格式:含英數至少六個字元');"/> <input id="ConfirmPassword" type="password" required="required" oninput="setCustomValidity('');" onchange="if(document.getElementById('inputPassword').value != document.getElementById('ConfirmPassword').value){setCustomValidity('密碼不吻合');}"/>
- 第一個輸入框輸入原始密碼,格式錯誤時會提醒輸入 "含英數至少六個字元"
- 第二個輸入框再次輸入密碼,輸入完會檢查兩個輸入框的字串是否一致,如果不一致便會出現提醒訊息 "密碼不吻合"
八、實作範例
以下統整前面的所有範例,利用 Bootstrap 修飾版面,製作一個常見的會員註冊表單:<!--引用 Bootstrap--> <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/> <!--表單內容--> <form> <div class="form-group"> <input name="Name" type="text" class="form-control" placeholder="姓名" required="required" minlength="2"/> </div> <div class="form-group"> <input name="Email" class="form-control" type="email" placeholder="電子郵件地址" required="required" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$"/> </div> <div class="form-group"> <input name="Birthday" class="form-control" type="date" min="1900-01-01" max="2021-01-01" required="required"/> </div> <div class="form-group"> <input name="Tel" class="form-control" type="text" placeholder="手機號碼(格式:09xx-xxxxxx)" required="required" maxlength="11" pattern="09\d{2}-\d{6}" oninput="setCustomValidity('');" oninvalid="setCustomValidity('請輸入正確的手機號瑪格式:09xx-xxxxxx');"/> </div> <div class="form-group"> <input id="inputPassword" name="Password" class="form-control" type="password" placeholder="設定密碼(格式:含英數至少六個字元)" pattern="^(?=.*[a-zA-Z])(?=.*[0-9]).{6,}$" required="required" oninput="setCustomValidity('');" oninvalid="setCustomValidity('請輸入正確的密碼格式:含英數至少六個字元');"/> </div> <div class="form-group"> <input id="ConfirmPassword" name="ConfirmPassword" class="form-control" type="password" placeholder="確認密碼" required="required" oninput="setCustomValidity('');" onchange="if(document.getElementById('inputPassword').value != document.getElementById('ConfirmPassword').value){setCustomValidity('密碼不吻合');}"/> </div> <input type="submit" value="註冊" class="btn btn-danger btn-block" /> </form>
實際效果如下面的表單,讀者可自行玩看看: 更多 HTML 相關技巧: