Categories
Form trong HTML
Phần tử form
Các form được thêm tới trang web bằng phần tử form
. Phần tử form
là một bộ chứa mọi nội dung của form, bao gồm các form control như các trường văn bản và nút. Nó cũng có thể chứa các phần tử khối (như h1
, p
, danh sách). Tuy nhiên, nó không thể chứa phần tử form
khác.
Ví dụ, tài liệu HTML sau có chứa một form:
<!DOCTYPE html>
<html>
<head>
<title>Mailing List Signup</title>
<meta charset="utf-8">
</head>
<body>
<h1>Mailing List Signup</h1>
<form action="/mailinglist.php" method="POST">
<fieldset>
<legend>Join our email list</legend>
<p>
Get news about the band such as tour dates and special MP3 releases sent to your own in-box.
</p>
<ol>
<li>
<label for="firstlast">Name:</label>
<input type="text" name="fullname" id="firstlast">
</li>
<li>
<label for="email">Email:</label>
<input type="text" name="email" id="email">
</li>
</ol>
<input type="submit" value="Submit">
</fieldset>
</form>
</body>
</html>
Thường thì ta nên bọc các form control trong các phần tử HTML như một danh sách hoặc một div
. Danh sách có thứ tự như ví dụ trên, là một giải pháp phổ biến. Các phần tử fieldset
, legend
và label
được sử dụng trong ví dụ trên nhằm tăng khả năng tiếp cận. Chúng sẽ được giải thích sau trong bài này.
Thuộc tính action
Thuộc tính action
cung cấp địa chỉ URL tới ứng dụng, hoặc script được dùng để xử lý form. Thuộc tính action
trong ví dụ trên gửi dữ liệu tới một script có tên mailinglist.php
:
<form action="/mailinglist.php" method="POST">...</form>
Phần mở rộng .php
cho biết rằng script này viết bằng ngôn ngữ PHP. Ngoài ra script còn có thể viết bằng nhiều ngôn ngữ khác như Java, JavaScript, Python, Ruby…
Thuộc tính method
Thuộc tính method
xác định cách thông tin được gửi tới máy chủ. Giả sử bạn nhập vào hai trường Name
và Email
thông tin như sau:
Có hai cách gửi thông tin tới máy chủ: POST
và GET
, xác định bởi giá trị của thuộc tính method
trong phần tử form
. Nếu không chỉ định rõ giá trị của method
thì phương thức GET
mặc định được sử dụng.
Phương thức GET
<form action="https:///www.bandname.com/mailinglist.php" method="GET">...</form>
Khi bạn bấm nút Submit
, trình duyệt chuyển đến URL có dạng:
https://www.bandname.com/mailinglist.php?fullname=Sally+Strongarm&email=strongarm%40example.com
Như vậy với GET
thông tin sau được gửi kèm theo URL:
fullname = Sally Strongarm
email = strongarm@example.com
Trong đó fullname
và email
lấy từ giá trị của thuộc tính name
của các trường Name
và Email
.
Trước khi gửi thông tin được mã hóa, cách dấu cách thay thế bằng dấu cộng +
, kí tự @
được thay bằng %40
.
fullname = Sally Strongarm
được mã hóa thành:
fullname=Sally+Strongarm
email = strongarm@example.com
được mã hóa bằng:
email=strongarm%40example.com
Sau đó chúng được nối với nhau, ngăn cách bởi dấu &
:
fullname=Sally+Strongarm&email=strongarm%40example.com
và đặt sau URL của script theo sau dấu ?
.
Phương thức POST
Khi phương thức method
được đặt thành POST
, trình duyệt gửi một request tới máy chủ chứa các header đặc biệt, sau đó là thông tin lấy được từ form. Về lý thuyết chỉ máy chủ có thể xem được các thông tin này, do vậy phương thức POST
phù hợp khi cần gửi các thông tin nhạy cảm như địa chỉ nhà hay các thông tin cá nhân khác.
Phương thức POST
cũng thích hợp khi cần gửi nhiều dữ liệu, do số ký tự không bị giới hạn như GET
.
Thuộc tính name
Mỗi form control bắt buộc phải có thuộc tính name
. Giá trị name
đóng vai trò như tên biến tương ứng với mỗi trường dữ liệu, dữ liệu thu được được gán cho biến này.
Trong ví dụ sau, văn bản lấy được từ phần tử textarea
được lưu vào biến có tên comment
:
<textarea name="comment" rows="4" cols="45" placeholder="Leave us a comment."></textarea>
Khi người dùng nhập văn bản (bình luận) vào trường này (chẳng hạn “This is the best band ever!”
), nó được truyền tới máy chủ như cặp biến/giá trị sau:
comment=This+is+the+best+band+ever%21
Các form control không liên quan đến việc thu thập dữ liệu như nút Submit
và Reset
không cần phải có thuộc tính name
.
Các form control
Phiên bản HTML5.2 có 22 form control. Phần này ta sẽ tìm hiểu chúng.
Các form control để thu thập văn bản
Một trong những công việc phổ biến nhất của form là thu thập thông tin dưới dạng văn bản. Sử dụng form control nào để thu thập dữ liệu văn bản phụ thuộc vào chuỗi văn bản cần thu thập gồm một dòng hay nhiều dòng.
Thu thập một dòng văn bản
Để thu thập văn bản viết trên một dòng, sử dụng phần tử input
với thuộc tính type
là text
.
<li>
<label>
Favorite color:
<input type="text"
name="favcolor"
value="Red"
maxlength="50">
</label>
</li>
Có thêm vài thuộc tính bạn cần biết:
value
: cung cấp giá trị mặc định của trường. Giá trị này cũng tự động được hiển thị khi form được tải. Khi bạn reset form, nó trả về giá trị này. Có một thuộc tính khác làplaceholder
cung văn bản mô tả cho trường, chẳng hạn “My favorite color”. Giá trị củaplaceholder
không phải là giá trị của trường.maxlength
,minlength
: Mặc định người dùng có thể nhập vô hạn ký tự. Bạn có thể cài đặt số kí tự tối đa được nhập qua thuộc tínhmaxlength
, số kí tự tối thiểu cần nhập qua thuộc tínhminlength
.size
: xác định chiều dài của trường, là số kí tự tối đa trường có thể hiện thị được.
Thu thập một đoạn văn bản
Để thu thập một đoạn văn bản (gồm nhiều dòng), sử dụng phần tử textarea
. Không giống như phần tử input
, bạn có thể đặt nội dung vào giữa thẻ mở và thẻ đóng của phần tử textarea
. Nội dung này trở thành giá trị mặc định của trường, được hiển thị khi form được tải.
<p>
<label>
Official contest entry: <br>
<em>Tell us why you love the band. Five winners will get backstage passes!</em><br>
<textarea name="contest_entry" rows="5" cols="50">
The band is totally awesome!
</textarea>
</label>
</p>
Thuộc tính rows
và cols
cho phép xác định kích thước của textarea, rows
xác định số dòng văn bản textarea hiển thị được, cols
xác định số kí tự trên một dòng mà textarea có thể hiển thị được. Khi textarea không thể hiển thị được toàn bộ văn bản, các thanh cuộn sẽ xuất hiện.
Thuộc tính maxlength
và minlength
cài đặt số kí tự tối đa và tối thiểu có thể nhập vào trường.
Thường thì ta không cung cấp giá trị mặc định cho textarea, mà cung cấp một chỉ dẫn qua thuộc tính placeholder
:
<p>
Official contest entry: <br>
<em>Tell us why you love the band. Five winners will get backstage passes!</em><br>
<textarea name="contest_entry" placeholder="50 words or less" rows="5" cols="50"></textarea>
</p>
Thuộc tính disable
và readonly
Thuộc tính disabled
và readonly
ngăn người dùng tương tác với một form control, nhưng giữa chúng có một chút khác biệt.
Khi một form control bị disabled
, người dùng không thể chọn nó. Trình duyệt thường hiển thị những form control này có dạng màu xám. Muốn “enable” lại cần sử dụng JavaScript.
Khi một form control cài đặt thành readonly
, người dùng có thể chọn, nhưng không thể thay đổi giá trị của trường tương ứng.
<p>
<label>
Disabled form control:
<input type="text" name="" value="Default value" disabled>
</label>
<br>
<label>
Readonly form control:
<input type="text" name="" value="Default value" readonly>
</label>
</p>
Khác biệt quan trọng nhất giữa disabled
và readonly
là các giá trị trường readonly
vẫn được gửi đi khi nút Submit được bấm, trong khi trường disabled
thì không.
Các form control thu thập văn bản đặc biệt
Thu thập mật khẩu
<li>
<label for="form-pswd">Password:</label>
<input type="password" name="pswd" maxlength="12" id="form-pswd">
</li>
Từ khóa tìm kiếm, địa chỉ email, số điện thoại, địa chỉ URL
<li>
<label for="form-search">Search:</label>
<input type="search" name="search" id="form-search">
</li>
<li>
<label for="form-email">Email:</label>
<input type="email" name="email" id="form-email">
</li>
<li>
<label for="form-tel">Tel:</label>
<input type="tel" name="tel" id="form-tel">
</li>
<li>
<label for="form-url">Url:</label>
<input type="url" name="url" id="form-url">
</li>
Phần tử datalist
Phần tử datalist
cho phép cung cấp danh sách thả xuống chứa các giá trị gợi ý cho một trường văn bản bất kỳ. Nó cho phép người dùng chọn nhanh một số giá trị phổ biến, nhưng nếu không muốn người dùng vẫn có thể nhập một giá trị khác.
Trong datalist
chứa nhiều phần tử option
. Mỗi một giá trị trong danh sách được đánh tạo bởi phần tử option
, giá trị được cung cấp qua thuộc tính value
của option
.
Mỗi một datalist
được gắn với một trường cụ thể. Để khai báo sự tương ứng này, sử dụng thuộc tính id
trong datalist
và list
trong một form control, như sau:
<p>
Education completed:
<input type="text" list="edulevel" name="education">
<datalist id="edulevel">
<option value="High School">
<option value="Bachelors Degree">
<option value="Masters Degree">
<option value="PhD">
</datalist>
</p>
Nút Submit và Reset
Nút submit: Gửi dữ liệu từ form tới máy chủ
<input type="submit">
Nút reset: Đặt lại giá trị các form control về mặc định.
<input type="reset">
<p>
<label for="firstname">First Name:</label>
<input type="text" name="firstname" id="firstname" value="Hung">
<br>
<label for="lastname">Last Name:</label>
<input type="text" name="lastname" id="lastname" value="Phung">
</p>
<p>
<input type="submit" value="Submit">
<input type="reset" value="Start over">
</p>
Nút radio và checkbox
Nút radio
Khi có một danh sách các tùy chọn và bạn chỉ có thể chọn một và chỉ một tùy chọn trong số đó, đó là lúc ta sử dung các nút radio:
<p>How old are you?</p>
<ol>
<li>
<input type="radio" name="age" value="under24" checked>
under 24
</li>
<li>
<input type="radio" name="age" value="25-34">
25 to 34
</li>
<li>
<input type="radio" name="age" value="35-44">
35 to 44
</li>
<li>
<input type="radio" name="age" value="over45">
45+
</li>
</ol>
Một nút radio được tạo bởi:
<input type="radio">
Khi các nút radio phải có cùng name
và bạn chỉ có thể chọn một trong số chúng, giá trị của mỗi nút được xác định bởi thuộc tính value
. Nút radio nào có thuộc tính checked
sẽ mặc định được chọn.
Trong ví dụ trên các nút radio có cùng tên age
, giá trị age
được lấy từ thuộc tính value
của nút được chọn.
Chặng hạn nếu bạn chọn nút thứ hai “25 to 34” thì:
age = 25-34
Nút checkbox
Khi có một danh sách các tùy chọn và bạn có thể chọn cùng lúc nhiều tùy chọn này, khi đó các nút checkbox được sử dụng.
<p>What type music do you listen to?</p>
<ul>
<li>
<input type="checkbox" name="genre" value="punk" checked>
Punk rock
</li>
<li>
<input type="checkbox" name="genre" value="indie" checked>
Indie rock
</li>
<li>
<input type="checkbox" name="genre" value="hiphop">
Hip Hop
</li>
<li>
<input type="checkbox" name="genre" value="rockabilly">
Rockabilly
</li>
</ul>
Các menu
Menu thả xuống
Phần tử select
tạo một menu thả xuống. Trong menu thả xuống, chỉ một mục có thể chọn (giống như nút radio). Ví dụ:
<p>What is your favorite 80s band?</p>
<select name="EightiesFave">
<option>The Cure</option>
<option>Cocteau Twins</option>
<option>Tears for Fears</option>
<option>Thompson Twins</option>
<option value="EBTG">Everything But the Girl</option>
<option>Depeche Mode</option>
<option>The Smiths</option>
<option>New Order</option>
</select>
Khi không có value
nội dung của option
được gửi tới máy chủ khi nó được chọn. Khi có value
thì giá trị của value
được gửi tới máy chủ thay cho nội dung của option
. Các giá trị này được gán cho biến có tên lấy từ thuộc tính name
của select
, trong ví dụ trên là biến EightiesFave
.
Menu cuộn
Để biến menu thả xuống thành menu cuộn, đơn giản cài đặt giá trị cho thuộc tính size
. Theo mặc định, ta chỉ có thể chọn một mục, muốn chọn nhiều mục cùng lúc (giống nút checkbox), sử dụng thuộc tính multiple
.
<p>What is your favorite 80s band?</p>
<select name="EightiesFave" size="6" multiple>
<option>The Cure</option>
<option>Cocteau Twins</option>
<option>Tears for Fears</option>
<option>Thompson Twins</option>
<option value="EBTG">Everything But the Girl</option>
<option>Depeche Mode</option>
<option>The Smiths</option>
<option>New Order</option>
</select>
Chú ý, để chọn nhiều mục, ta giữ phím Ctrl
trong khi chọn.
Muốn một mục được chọn mặc đinh, sử dụng thuộc tính selected
trong phần tử option
tương ứng.
Nhóm nhiều mục với nhau
Trong menu thả xuống, có thể có nhiều mục có liên quan về mặt ý nghĩa với nhau, lúc đó ta có thể gom chúng thành một nhóm và gán nhãn cho nhóm bằng phần tử optgroup
và thuộc tính label
:
<select name="icecream" size="7" multiple>
<optgroup label="traditional">
<option>vanilla</option>
<option>chocolate</option>
</optgroup>
<optgroup label="fancy">
<option>Super praline</option>
<option>Nut surprise</option>
<option>Candy corn</option>
</optgroup>
</select>
Chọn file
Không chỉ dữ liệu văn bản, các form còn có thể truyền các file từ ổ cứng máy tính tới máy chủ.
<form action="/client.php" method="POST" enctype="multipart/form-data">
<fieldset>
<label>
Send a photo to be used as your online icon <em>(optional)</em><br>
<input type="file" name="photo">
</label>
</fieldset>
</form>
Khi sử dụng form để truyền file tới máy chủ, bạn phải chỉ rõ kiểu mã hóa là multipart/form-data
trong phần tử form
và phải sử dụng phương thức POST
.
Kiểu phần tử input
có vài thuộc tính mới:
accept
: chỉ rõ kiểu file nào được chấp nhận.multiple
: cho phép chọn nhiều file để truyền.required
: bắt buộc phải chọn file.
Các form control ẩn
Đôi khi cần gửi tới máy chủ những thông tin không đến từ người dùng. Lúc này có thể sử dụng các form control ẩn để gửi các thông tin này. Các form control ẩn không được hiển thị trong trình duyệt.
Các form control ẩn được thêm qua phần tử input
với type
là hidden
. Mục đích của nó là gửi cặp giá trị tên biến/giá trị
tới máy chủ. Ví dụ:
<input type="hidden" name="success-link" value="https://www.example.com/thankyou.html">
Nhập dữ liệu ngày và giờ
<input type="date">
Cú pháp ngày là:
YYYY-MM-DD
YYYY
: năm (có 4 chữ số)MM
: tháng (có 2 chữ số)DD
: ngày (có 2 chữ số)
<label>
Birthday:
<input type="date" name="date" value="1986-08-03">
</label>
<input type="time">
Cú pháp giờ là:
hh:mm:ss
hh
: giờ (có 2 chữ số từ00
đến23
)mm
: phút (có 2 chữ số từ00
đến59
)ss
: giây (có 2 chữ số từ00
đến59
)
<label>
Time:
<input type="time" name="time" value="20:30:00">
</label>
<input type="datetime-local">
Cú pháp ngày, giờ (không có múi giờ) là:
YYYY-MM-DDThh:mm:ss
trong đó T
là dấu phân cách giữa phần ngày và phần giờ.
<label>
Date and time:
<input type="datetime-local" name="datetime" value="2020-02-12T00:38:00">
</label>
<input type="month">
Cú pháp tháng năm:
YYYY-MM
<input type="month" name="month" value="2020-02">
<input type="week">
Cú pháp tuần trong năm:
YYYY-W#
trong đó #
là số thứ tự tuần trong năm.
<input type="week" name="week" value="2020-W6">
Nhập dữ liệu số
Nhập một số
<label>
Number of guests:
<input type="number" name="guests" min="1" max="6">
</label>
Nhập một số sử dụng thanh trượt
<label>
Satisfaction (0 to 100)
<input type="range" name="satisfaction" min="0" max="10" step="1">
</label>
Thuộc tính step
cho phép xác định giá trị bước nhảy khi kéo thanh trượt. Mặc định là 1.
Chọn màu
<label>
Your favorite color:
<input type="color" name="favcolor" value="#FF0065">
</label>
Giá trị màu có dạng:
#RRGGBB
trong đó RRGGBB
là mã Hexa của màu.
Tăng cường tính dễ sử dụng của form
Các phần tử label
, fieldset
và legend
giúp form dễ sử dụng hơn.
Label
Phần tử label
giúp liên kết văn bản mô tả với trường tương ứng. Lúc này khi muốn chọn trường, chỉ cần chọn văn bản mô tả trường đó.
Mỗi phần tử label
chỉ tương ứng với một form control duy nhất. Có hai cách sử dụng.
Liên kết ngầm định
Đặt form control trong label
:
<ul>
<li>
<label>
<input type="checkbox" name="genre" value="punk">
Punk rock
</label>
</li>
<li>
<label>
<input type="checkbox" name="genre" value="indie">
Indie rock
</label>
</li>
<li>
<label>
<input type="checkbox" name="genre" value="hiphop">
Hip Hop
</label>
</li>
<li>
<label>
<input type="checkbox" name="genre" value="rockabilly">
rockabilly
</label>
</li>
</ul>
Để chọn một nút checkbox chỉ cần click vào văn bản mô tả.
Liên kết tương minh
Kết hợp thuộc tính for
(trong label
) với id
(trong form control):
<label for="form-login-username">Login account</label>
<input type="text" name="login" id="form-login-username">
<br>
<label for="form-login-password">Password</label>
<input type="password" name="password" id="form-login-password">
fieldset và legend
fieldset
nhóm các form control có liên quan lại với nhau. Mỗi fieldset
có thể có tiêu đề đặt trong phần tử legend
.
<fieldset>
<legend>Mailing List Sign-up</legend>
<ul>
<li>
<label>
Add me to your mailing list
<input type="radio" name="list" value="yes" checked>
</label>
</li>
<li>
<label>
No thanks
<input type="radio" name="list" value="no">
</label>
</li>
</ul>
</fieldset>
<fieldset>
<legend>Customer Information</legend>
<ul>
<li>
<label>
Full name:
<input type="text" name="fullname">
</label>
</li>
<li>
<label>
Email:
<input type="email" name="email">
</label>
</li>
<li>
<label>
State:
<input type="text" name="state">
</label>
</li>
</ul>
</fieldset>