前言
在網頁中時常會需要接收用戶端所提供的資訊,舉例來說像是登入時需要輸入「信箱與密碼」、預約旅館時需要輸入「時段與房間種類」或是報名比賽需要輸入「作品檔案」……等不同型態的資料,這些輸入選項的功能與介面都可以輕易的透過原生 HTML 標籤來完成,只要想要在網頁中提交資料,都是使用 HTML 表單的好時機。
從 <form>
開始
在早期 AJAX 尚未盛行時,網頁會透過表單來向伺服器提交資料,預設會使用 HTTP GET 的方法,也可以自訂透過註明 method
屬性來達成:
舉例來說如果該表單在 https://webdong.dev/contact
那麼當提交事件觸發時就會對該 URL 發送一個 POST 請求,當然後端也會需要對應的設定來聆聽這些請求去接收表單所提交的資料。
也可以額外指定目標的 URL 使用 action
屬性,這樣就會對 /new-contact
這個相對位址發送 POST 請求,也就是 https://webdong.dev/new-contact
。
實際上現在已經很少會使用表單向伺服器溝通了,只是描述一些歷史用法,也是鋪陳說明為什麼很多教學都說要阻擋所謂「預設事件」的「預設事件」,在 JavaScript 還很初始渾沌的時代,表單原先設計就是這樣使用的。
當今通常會使用 preventDefault
方法來避免瀏覽器預設事件發生(向伺服器發送請求,並重整頁面),並透過 JavaScript 來取得表單的內容:
雖然語法上不使用 <form>
並沒有任何問題 ,但還是建議在撰寫表單控制元件 (Form Control)之前使用它,原因是因為:
- 組織資料 -
<form>
可以將一組相關的表單控制組織在一起,以便用戶能夠提交資料。例如,當要求用戶填寫姓名、電子郵件地址和訊息時,這些表單元素通常會放在同一個<form>
標籤中,以便把資料一齊提交。 - 語意清晰 - 明確標明哪些內容是用於表單,而不是普通的文字或其他元素。這有助於維持代碼的結構性與可讀性,讓開發者和維護者更容易理解和處理。
- 表單控制 - 可以使用表單預設提供的方法,例如提交、重置或驗證,實踐常見的表單功能。
舉例來說以下代碼就是一個簡單輸入姓名的表單,可以透過提交按鈕觸發提交事件或是重置事件:
表單控制元件
具體來說常用的有以下幾種表單控制元件,看起來很多但實際上它們使用方式是差不多的,本文挑選一些最常見的解釋:
- input - 單行文字
- textarea - 多行文字
- select boxes - 從下拉式選單中選取單一選項
- radio buttons - 從多個選項中選取單一選項
- checkboxes - 從多個選項中選取無、一個或多個選項
- file uploads - 上傳檔案
- 更多……
<label>
<label>
用於描述表單控制元件,可以透過 for
屬性與 id
屬性同名的控制元件明確建立關係也可以透過包裹的方式隱晦的建立關係,都是正確的方法:
要留意 <label>
的存在是為了輔助說明表單控制元件,應盡量為每個表單控制元件都添加;時常會出現為了美觀因素而省略容易造成使用者無法理解該欄位的用途的錯誤,可以透過:隱藏標籤、使用 aria-label、使用 aria-labelledby或使用 title 屬性視情況來為沒有 <label>
的表單控制選項添加描述。
<input>
<input>
在表單中最基本也是最常使用的元素,可以用於接收各種不同型態的資料,例如文字、數字、日期、時間、電子郵件、密碼、檔案……等,<input>
具備多種屬性,最常用的有 required
、type
、placeholder
、value
與name
、disabled
……等屬性。
A. 舉例來說可以為輸入框添加文字提示,使用 placeholder
屬性:
B. 或是讓輸入框預先填入預設值,使用 value
屬性:
C. 或是限定必須要填寫才能提交,使用 required
屬性:
D. 或是使用 disabled
來禁用其功能:
也可以使用 type
的屬性來限制輸入的資料型態,例如 type="email"
就會限制輸入的資料必須符合電子郵件格式,type="number"
就會限制輸入的資料必須是數字,type="password"
就會將輸入的資料隱藏並且無法複製與剪下,type="file"
就會讓使用者可以選擇檔案上傳,依照想要獲得的資料種類都可以註明 type
屬性來達成。
<textarea>
<textarea>
用於接收多行文字,可以透過 rows
與 cols
屬性來設定預設的行數與列數,也可以透過 placeholder
與 value
屬性來設定預設文字與預設值。
參考資料
- Learn Forms - web.dev
- Is
<input>
well formed without a<form>
? - Stack Overflow - Forms - W3C Superseded Recommendation
- Labeling Controls - W3C Web Accessibility Initiative WAI