Học cách tạo biểu mẫu để thu thập thông tin từ người dùng
HTML Forms là cách để thu thập thông tin từ người dùng thông qua các input fields như text, email, password, checkbox, radio buttons, etc. Forms là cầu nối giữa frontend và backend.
Thẻ form chứa tất cả các input elements
<form> - Container chính
Các loại input để người dùng nhập liệu
<input> <textarea> <select>
Tổ chức và mô tả các form elements
<label> <fieldset> <legend>
Submit, reset và các action buttons
<button> <input type="submit">
Thẻ <form> là container chứa tất cả các input elements và định nghĩa cách dữ liệu được gửi đi.
<!-- Form cơ bản -->
<form action="/submit" method="POST">
<!-- Các input elements ở đây -->
<label for="name">Tên:</label>
<input type="text" id="name" name="name" required>
<button type="submit">Gửi</button>
</form>
<!-- Form với nhiều thuộc tính -->
<form
action="https://example.com/process-form"
method="POST"
target="_blank"
enctype="multipart/form-data"
novalidate
autocomplete="on"
>
<!-- Form content -->
</form>
URL nơi form data được gửi đến
action="/submit-form"action="mailto:admin@example.com"
HTTP method để gửi data
method="GET" - Data trong URLmethod="POST" - Data ẩn (khuyến khích)
Cách encode data khi gửi
application/x-www-form-urlencoded (mặc định)multipart/form-data (cho file upload)
Client-side validation
novalidate - Tắt validation<!-- Text inputs -->
<input type="text" name="fullname" placeholder="Họ và tên">
<input type="email" name="email" placeholder="email@example.com" required>
<input type="password" name="password" placeholder="Mật khẩu">
<input type="tel" name="phone" placeholder="0123-456-789">
<input type="url" name="website" placeholder="https://example.com">
<!-- Number & Date inputs -->
<input type="number" name="age" min="18" max="100" step="1">
<input type="range" name="rating" min="1" max="10" value="5">
<input type="date" name="birthday">
<input type="time" name="meeting-time">
<input type="datetime-local" name="appointment">
<!-- Selection inputs -->
<input type="checkbox" name="agree" id="agree" checked>
<input type="radio" name="gender" value="male" id="male">
<input type="radio" name="gender" value="female" id="female">
<!-- File & Hidden inputs -->
<input type="file" name="avatar" accept="image/*">
<input type="hidden" name="user_id" value="123">
<!-- Buttons -->
<input type="submit" value="Gửi form">
<input type="reset" value="Reset">
<input type="button" value="Custom Action">
<!-- Textarea cơ bản -->
<textarea name="message" placeholder="Nhập tin nhắn của bạn..."></textarea>
<!-- Textarea với kích thước và các thuộc tính -->
<textarea
name="description"
rows="5"
cols="50"
maxlength="500"
placeholder="Mô tả sản phẩm (tối đa 500 ký tự)"
required
>Nội dung mặc định ở đây</textarea>
<!-- Textarea không resize -->
<textarea
name="comment"
style="resize: none; width: 100%; height: 120px;"
placeholder="Bình luận của bạn..."
></textarea>
<!-- Select đơn giản -->
<select name="country">
<option value="">Chọn quốc gia</option>
<option value="vn">Việt Nam</option>
<option value="us">United States</option>
<option value="jp" selected>Japan</option>
</select>
<!-- Select với optgroup -->
<select name="city">
<option value="">Chọn thành phố</option>
<optgroup label="Miền Bắc">
<option value="hanoi">Hà Nội</option>
<option value="haiphong">Hải Phòng</option>
</optgroup>
<optgroup label="Miền Nam">
<option value="hcm">TP. Hồ Chí Minh</option>
<option value="cantho">Cần Thơ</option>
</optgroup>
</select>
<!-- Multiple select -->
<select name="skills" multiple size="5">
<option value="html">HTML</option>
<option value="css">CSS</option>
<option value="js" selected>JavaScript</option>
<option value="react">React</option>
<option value="vue" selected>Vue.js</option>
</select>
Label giúp accessibility tốt hơn, khi click vào label sẽ focus vào input tương ứng, và screen readers có thể đọc được mô tả.
<!-- Cách 1: Sử dụng for và id -->
<label for="username">Tên đăng nhập:</label>
<input type="text" id="username" name="username">
<!-- Cách 2: Wrap input trong label -->
<label>
Email:
<input type="email" name="email">
</label>
<!-- Checkbox và Radio với label -->
<label for="agree">
<input type="checkbox" id="agree" name="agree">
Tôi đồng ý với điều khoản sử dụng
</label>
<!-- Radio group -->
<fieldset>
<legend>Giới tính:</legend>
<label>
<input type="radio" name="gender" value="male">
Nam
</label>
<label>
<input type="radio" name="gender" value="female">
Nữ
</label>
</fieldset>
<form>
<fieldset>
<legend>Thông tin cá nhân</legend>
<label for="fname">Họ:</label>
<input type="text" id="fname" name="firstname">
<label for="lname">Tên:</label>
<input type="text" id="lname" name="lastname">
</fieldset>
<fieldset>
<legend>Thông tin liên hệ</legend>
<label for="email">Email:</label>
<input type="email" id="email" name="email">
<label for="phone">Điện thoại:</label>
<input type="tel" id="phone" name="phone">
</fieldset>
<fieldset disabled>
<legend>Thông tin không thể chỉnh sửa</legend>
<label for="readonly-info">ID:</label>
<input type="text" id="readonly-info" value="123456" readonly>
</fieldset>
</form>
HTML5 cung cấp validation built-in không cần JavaScript. Tuy nhiên, luôn cần validation phía server.
<form>
<!-- Required fields -->
<input type="text" name="name" required placeholder="Tên (bắt buộc)">
<input type="email" name="email" required placeholder="Email (bắt buộc)">
<!-- Length validation -->
<input type="password" name="password"
minlength="8" maxlength="20"
placeholder="Mật khẩu (8-20 ký tự)">
<!-- Number validation -->
<input type="number" name="age"
min="18" max="65"
placeholder="Tuổi (18-65)">
<!-- Pattern validation (Regex) -->
<input type="text" name="phone"
pattern="[0-9]{10,11}"
placeholder="Số điện thoại (10-11 số)"
title="Vui lòng nhập 10-11 chữ số">
<!-- Custom validation messages -->
<input type="email" name="work-email"
pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$"
title="Email phải có định dạng đúng"
placeholder="Email công ty">
<!-- File validation -->
<input type="file" name="avatar"
accept="image/jpeg,image/png,image/gif"
required>
<button type="submit">Gửi form</button>
</form>
<!--
🎯 YÊU CẦU FORM ĐĂNG KÝ:
1. Form với method="POST" action="#"
2. Fieldset "Thông tin cơ bản":
- Họ và tên (text, required)
- Email (email, required)
- Mật khẩu (password, minlength="8", required)
- Xác nhận mật khẩu (password, required)
- Ngày sinh (date, required)
3. Fieldset "Thông tin bổ sung":
- Giới tính (radio: Nam, Nữ, Khác)
- Quốc gia (select với 5 quốc gia)
- Sở thích (checkbox: Đọc sách, Du lịch, Thể thao, Âm nhạc)
- Giới thiệu bản thân (textarea, maxlength="500")
4. Fieldset "Avatar":
- Upload ảnh (file, accept="image/*")
5. Checkbox đồng ý điều khoản (required)
6. 2 buttons: Submit "Đăng ký" và Reset "Làm lại"
✅ YÊU CẦU KỸ THUẬT:
- Tất cả input phải có label
- Sử dụng placeholder phù hợp
- Required validation cho các field quan trọng
- Proper form structure với fieldset/legend
-->
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Đăng ký tài khoản</title>
</head>
<body>
<h1>Form Đăng Ký Tài Khoản</h1>
<!-- Viết form của bạn ở đây -->
</body>
</html>
<!--
📞 YÊU CẦU CONTACT FORM:
1. Form liên hệ:
- Tên (required)
- Email (required)
- Số điện thoại (pattern validation cho VN: 0xxxxxxxxx)
- Chủ đề (select: Hỗ trợ kỹ thuật, Khiếu nại, Góp ý, Khác)
- Tin nhắn (textarea, required, minlength="20")
2. Form đánh giá dịch vụ:
- Đánh giá (radio: Rất tốt, Tốt, Bình thường, Kém, Rất kém)
- Điểm số (range input 1-10)
- Sẽ giới thiệu cho bạn bè? (radio: Có, Không)
- Cải thiện gì? (checkbox multiple: UI/UX, Tốc độ, Tính năng, Giá cả)
3. Newsletter subscription:
- Đăng ký nhận tin (checkbox)
- Tần suất (select: Hàng ngày, Hàng tuần, Hàng tháng)
4. Validation:
- Pattern cho phone: ^0[0-9]{9,10}$
- Email validation
- Required fields có dấu * đỏ
💡 BONUS:
- Thêm CSS để form đẹp
- Group related fields với fieldset
- Accessible labels và descriptions
-->
<!-- Tạo contact form của bạn ở đây -->
Trong Bài 5, chúng ta sẽ học về Layout & Containers - cách sử dụng div, span, và các thẻ container để tạo layout cho website.