Everything you need to know about HTML Form

簡單明確的了解 HTML 表單使用方式

前言

在網頁中時常會需要接收用戶端所提供的資訊,舉例來說像是登入時需要輸入「信箱與密碼」、預約旅館時需要輸入「時段與房間種類」或是報名比賽需要輸入「作品檔案」……等不同型態的資料,這些輸入選項的功能與介面都可以輕易的透過原生 HTML 標籤來完成,只要想要在網頁中提交資料,都是使用 HTML 表單的好時機

<form> 開始

在早期 AJAX🔗 尚未盛行時,網頁會透過表單來向伺服器提交資料,預設會使用 HTTP GET 的方法,也可以自訂透過註明 method 屬性來達成:

<form method="POST">
<!-- ... -->
</form>

舉例來說如果該表單在 https://webdong.dev/contact 那麼當提交事件觸發時就會對該 URL 發送一個 POST 請求,當然後端也會需要對應的設定來聆聽這些請求去接收表單所提交的資料。

<form action="/new-contact" method="POST">
<!-- ... -->
</form>

也可以額外指定目標的 URL 使用 action 屬性,這樣就會對 /new-contact 這個相對位址發送 POST 請求,也就是 https://webdong.dev/new-contact

實際上現在已經很少會使用表單向伺服器溝通了,只是描述一些歷史用法,也是鋪陳說明為什麼很多教學都說要阻擋所謂「預設事件」的「預設事件」,在 JavaScript 還很初始渾沌的時代,表單原先設計就是這樣使用的。

當今通常會使用 preventDefault🔗 方法來避免瀏覽器預設事件發生(向伺服器發送請求,並重整頁面),並透過 JavaScript 來取得表單的內容:

// 選取目前 DOM 中的表單
const form = document.querySelector('form');
// 如果表單被提交,就執行函式
form.addEventListener('submit', (event) => {
event.preventDefault(); // 避免瀏覽器預設事件發生
const formData = new FormData(form); // 取得表單內容
});

雖然語法上不使用 <form> 並沒有任何問題 ,但還是建議在撰寫表單控制元件 (Form Control)之前使用它,原因是因為:

  1. 組織資料 - <form> 可以將一組相關的表單控制組織在一起,以便用戶能夠提交資料。例如,當要求用戶填寫姓名、電子郵件地址和訊息時,這些表單元素通常會放在同一個 <form> 標籤中,以便把資料一齊提交。
  2. 語意清晰 - 明確標明哪些內容是用於表單,而不是普通的文字或其他元素。這有助於維持代碼的結構性與可讀性,讓開發者和維護者更容易理解和處理。
  3. 表單控制 - 可以使用表單預設提供的方法,例如提交🔗重置🔗驗證🔗,實踐常見的表單功能。

舉例來說以下代碼就是一個簡單輸入姓名的表單,可以透過提交按鈕觸發提交事件或是重置事件:

<form>
<label for="name">姓名</label>
<input id="name" type="text" placeholder="請輸入姓名" />
<button type="submit">提交</button>
<button type="reset">重置</button>
</form>

表單控制元件

具體來說常用的有以下幾種表單控制元件,看起來很多但實際上它們使用方式是差不多的,本文挑選一些最常見的解釋:

  • input - 單行文字
  • textarea - 多行文字
  • select boxes - 從下拉式選單中選取單一選項
  • radio buttons - 從多個選項中選取單一選項
  • checkboxes - 從多個選項中選取無、一個或多個選項
  • file uploads - 上傳檔案
  • 更多……

<label>

<label> 用於描述表單控制元件,可以透過 for 屬性與 id 屬性同名的控制元件明確建立關係也可以透過包裹的方式隱晦的建立關係,都是正確的方法:

<label for="name">姓名</label> <input id="name" type="text" placeholder="請輸入姓名" />
<label>
姓名
<input type="text" placeholder="請輸入姓名" />
</label>

要留意 <label> 的存在是為了輔助說明表單控制元件,應盡量為每個表單控制元件都添加;時常會出現為了美觀因素而省略容易造成使用者無法理解該欄位的用途的錯誤,可以透過:隱藏標籤🔗使用 aria-label🔗使用 aria-labelledby🔗使用 title 屬性🔗視情況來為沒有 <label> 的表單控制選項添加描述。

<input>

<input type="text" />

<input> 在表單中最基本也是最常使用的元素,可以用於接收各種不同型態的資料,例如文字、數字、日期、時間、電子郵件、密碼、檔案……等,<input> 具備多種屬性🔗,最常用的有 required🔗type🔗placeholder🔗value🔗name🔗disabled🔗……等屬性。

A. 舉例來說可以為輸入框添加文字提示,使用 placeholder 屬性:

<input type="text" placeholder="input 標籤範例……" />

B. 或是讓輸入框預先填入預設值,使用 value 屬性:

<input type="text" value="我是預設文字" />

C. 或是限定必須要填寫才能提交,使用 required 屬性:

<input type="text" required />

D. 或是使用 disabled 來禁用其功能:

<input type="text" disabled />

也可以使用 type 的屬性來限制輸入的資料型態,例如 type="email" 就會限制輸入的資料必須符合電子郵件格式,type="number" 就會限制輸入的資料必須是數字,type="password" 就會將輸入的資料隱藏並且無法複製與剪下,type="file" 就會讓使用者可以選擇檔案上傳,依照想要獲得的資料種類都可以註明 type 屬性來達成。

請選擇一種顏色:

<textarea>

<textarea> 用於接收多行文字,可以透過 rowscols 屬性來設定預設的行數與列數,也可以透過 placeholdervalue 屬性來設定預設文字與預設值。

參考資料