2010/11/13

Firefox 4 的 HTML5 表單

WW1 Certificate Of Employment - Army Form Z.18- Part I

(廣義的)HTML5 除了絢麗的各種 CSS3 及新 JavaScript API 組合技之外,還有一個十分實用、卻比較容易忽略的 HTML5 Forms。Firefox 4 實作了其中不少東西,這篇文章將大致介紹一下這玩意。

本文編譯自 Mozilla Hacks 的文章:Firefox 4: HTML5 Forms。原文亦採 CC:BY-SA 3.0 釋出。要實際試用文中的表單效果,你需要以支援 HTML5 表單的瀏覽器觀看此頁。關於各瀏覽器的支援程度,文末將略提一下目前的概況,可逕自參考。


輸入欄位新型態

HTML5 中新增了不少 INPUT 元素 的 type 屬性值,可以表達我們希望使用者輸入哪一類的資料,從而在語意甚至互動呈現方式上獲得更好的結果。

舉例而言,手機上虛擬鍵盤的輸入一向受限於顯示區域、經常得在各種模式(中文、英文、數字)間切換。假若一開始就擺明了要輸入電話號碼、那麼瀏覽器就可以自動呼叫數字鍵盤出來,節省時間也增進體驗;又或者,如果這個欄位就是要輸入 URL,那麼或許也可以跟瀏覽器的瀏覽紀錄互相結合以節省使用者記憶的功夫。

Firefox 4 Beta 7 裡新增了以下幾種 type

<input type="search">
<input type="tel">
<input type="url">
<input type="email">

其中 urlemail 會自動驗證使用者是否確實輸入了網址或電子郵件地址格式的資料,等下會再提一下這個部份。

輸「出」欄位

還有一個新的 OUTPUT 元素,用來表達某個區域的內容是因應表單的輸入而改變的。例如,你填了出生年月日後,就在此顯示你幾歲那類的。寫法如下:

<output for="i1 i2">

for 屬性中是以空白字元分隔的、「構成這個輸出結果」的表單元素 ID 清單。使用這個元素主要是可以讓補助工具(如螢幕閱讀軟體)了解該區域的語意並提供對應服務,但 OUTPUT 裡的內容並不會「自動」計算出來,你還是得用 JavaScript 算好後填進去。畢竟,瀏覽器怎麼知道你想如何計算呢?

輸入欄位的備選清單

長久以來,網頁世界裡一直缺乏「ComboBox」這樣的元件:一方面能接受使用者自由輸入、二方面也能提供預選的清單,讓使用者更方便。過去我們可以利用 JavaScript 「做」出類似的效果,而以後則可以使用 DATALIST這個新元素來處理。在DATALIST 中所有的 OPTION元素,都會被視為是這份清單裡的備選答案。在清單定義完畢之後,則可在 INPUT 裡加上 list 來使用。範例如下:


<label>輸入所在城市:<input list="cities"></label>
<datalist id="cities">
  或
  <label>從清單中挑選
    <select>
      <option value="Taipei">台北</option>
      <option value="Tainan">台南</option>
      <option value="Taichung">台中</option>
      <option value="Taidong">台東</option>
      <option value="Taihsi">台西</option>
    </select>
  </label>
</datalist>

以這個方式書寫的話,如果訪客的瀏覽器不支援這個功能,也會直接略過 DATALIST 而將當中的 SELECT 選單顯示出來,所以不必擔心使用者就因此無法使用。你可以另外拿一個不支援這個標籤的瀏覽器來看本頁試試。

輸入元素新屬性

autofocus

不必再仰賴 JavaScript 將輸入焦點移到使用者第一個要輸入的表單欄位了!只要在要搶輸入焦點的 INPUT 元素上加入 autofocus 屬性即可:

<input autofocus>

placeholder

在使用者未輸入文字前,要在欄位裡顯示的東西。可以用來提示使用者該輸入些什麼,例如:

<label>電話:<input placeholder="02-22223333#311"></label>
<label>意見:<textarea placeholder="請輸入您對本產品的意見。"></textarea>

解構式表單

現在表單元素的書寫方式將有更多靈活的變化。

form 屬性

INPUT 不再需要放在 FORM 元素中了,現在放在任何地方都行,只要加上 form 屬性指明要歸屬的 FORM id,此部份的資料就會隨該表單一併送出。

舉個實用的例子:你想在網頁頁首放一個簡單的搜尋欄位,又想在頁尾另外提供更進階的搜尋功能選項。那麼,頁首可以這麼寫:

<input type="search" name="search_field" form="search_form">

而頁尾可以這麼寫:

<form id="search_form" action="search.php" method="post">
  <fieldset>
    <legend>進階選項</legend>
    <input type="checkbox">也搜尋私人內容
    <!-- 其他內容 -->
  </fieldset>
</form>

這麼一來,兩個部份就屬於同一個表單,而你可以更自由地隨意擺放。

欄位中的各種表單選項

FORM 元素中定義的屬性,都可以視情況、由表單欄位中的設定來推翻。目前表單的送出按鈕(包括 BUTTONtype="submit"FORM)支援的相關屬性有:formenctypeformactionformmethodformtarget

有個可能的使用情境是,若表單尾附上「預覽」及「送出」兩個按鈕,則按下去後的表單行為不見得要都相同:

<form action="new_post.php" method="post">
<label>標題:<input type="text"></label>
<label>內文:<textarea></textarea></label>
<input type="submit" formaction="preview.php" formmethod="get" value="預覽">
<input type="submit" value="送出">
</form>

若使用者按下「預覽」鈕,則表單送出的方式會從 POST 改為 GET,且傳送目標也從 new_post.php 改為 preview.php。

表單驗證

我們經常需要驗證表單中的資料,確定使用者輸入了正確資訊。我們可以在表單送出前用 JavaScript 驗證資料,也可以在表單送出後以 PHP 等後端語言驗證。一般來說我們都希望使用者盡早知道自己輸入錯誤的地方,所以前端的 JavaScript 多少是會做的,那麼如果瀏覽器就可以處理這塊,不是很好?

必填資訊 required

在表單元素中加上 required 屬性,就代表要求使用者一定要填寫這個欄位。以 Checkbox (多選方塊)來說就代表這個格子一定要勾,而 Radio button (單選鈕)的情況則代表這群按鈕中要選一個。

直接試試以下範例吧!

<input type="text" required>

<input type="checkbox" required>

<input type="radio" name="radiogroup" required>
<input type="radio" name="radiogroup" required>
<input type="radio" name="radiogroup" required>

網址 url

自動驗證是否為 URL。

<input type="url" value="mozilla">
<input type="url" value="http://mozilla.org">

電子郵件地址 email

自動驗證是否為電子郵件地址。如果再加上 multiple 屬性的話,就可以驗證以逗號分隔的多個郵件地址。(multiple 屬性也適用於 type="file" 的欄位。)

<input type="email" value="foo">
<input type="email" value="foo@bar.org">

<input type="email" multiple value="foo@bar.org, spongebob">
<input type="email" multiple value="foo@bar.org, spongebob@squarepants.org">

這種驗證方式並不會排除有「+」號的 email 地址,所以 Gmail 那類可以在帳號上另外指定標籤(如 bobchao+spam@gmail.com)的方式也適用。

進階驗證 API

如果你想進一步控制驗證方式,可以使用 setCustomValidity 方法撰寫 JavaScript 來驗證表單。傳入字串就代表未通過驗證的錯誤訊息,以 tooltip 方式顯現(且,該表單元素會被標為未通過驗證);傳入空字串則表示驗證通過。

<label>請輸入密碼:<input type="password" id="password1" oninput="checkPasswords()"></label>
<label>請再輸入一次密碼:<input type="password" id="password2" oninput="checkPasswords()"></label>
<script>
function checkPasswords() {
  var password1 = document.getElementById('password1');
  var password2 = document.getElementById('password2');
  if (password1.value != password2.value) {
    password2.setCustomValidity('您這兩次輸入的密碼不同,請再次確認!');
  } else {
    password2.setCustomValidity('');
  }
}
</script>

若表單中有任何元素被標為未通過驗證,則送出表單前就會被擋下來、將輸入焦點自動移至第一個未通過驗證的表單元素、顯示錯誤訊息。若你想自訂這樣的行為,可以在 FORM 元素上設定 novalidate 屬性,或於送出表單的按鈕加上 formnovalidate 屬性。

關於驗證表單這點,Mounir 寫了另一篇文章,可參考。我(柏強)可能也會翻譯那篇,資訊很豐富。

新的 CSS 選取符

因應這些新增的表單功能,CSS 部份也有些新的選取符。

:required:optional

預設情形下,所有的元素都屬於 :optional 的影響範圍。如果你為某元素加上 required 屬性中是以空白字元分隔的,則該元素會改套用 :required 的樣式。以下是自訂樣式的必填資訊輸入欄位:

:-moz-placeholder

這個擬似類別可以調整 placeholder 的樣式。這種設定方法還沒進入 CSS 標準,這麼寫就只有 Gecko 相關瀏覽器看得到了。WebKit 瀏覽器也有一個一樣的東西,以下為兩類瀏覽器都能看到效果的範例:

<style>
#selectors2 :-moz-placeholder {
  font-style: italic;
}
#selectors2 ::-webkit-placeholder {
  font-style: italic;
}
</style>
<form id="selectors2">
  <input placeholder="Style me">
</form>

瀏覽器相容性與標準制定

HTML5 Forms 還算比較新的功能,各瀏覽器的支援程度也大不相同。Opera 在 HTML5 Forms 還叫做 Webforms 2 時就實做了部份規格草案內容,所以雖然支援情形良好,但有些行為反而與後來的規格修訂結果有些出入;WebKit 的瀏覽器也已經支援了部份規格,所以也可以實際試試看。

Firefox 4 已經不會再加上更多表單相關功能,而要完整支援 HTML5 Forms 則還有一段路要走:還有些新的欄位型態(數字、色彩、日期)、屬性(數字變動間距、最大值、最小值)、事件(onforminputonformchange)等等,尚未實做。在未來的版本中,我們會一步步加上去。

這篇文章只是表單功能的概括介紹。Mozilla Developer Network 上還有更詳細的資訊,歡迎參考。

沒有留言:

張貼留言

歡迎留下您的意見