فرمها در Bootstrap
بهنام نوبخت · ۱۴۰۵/۷/۱۲
فرمها بخش جداییناپذیر بسیاری از وبسایتها و برنامههای تحت وب هستند. ثبتنام، ورود، جستجو، ثبت سفارش، ارسال پیام، ایجاد محصول، ویرایش اطلاعات کاربر و بسیاری از عملیات دیگر از طریق فرم انجام میشوند. Bootstrap مجموعهای از کلاسها و Componentهای آماده برای طراحی فرمهای حرفهای و Responsive در اختیار ما قرار میدهد. با استفاده از این امکانات میتوانیم ظاهر Inputها، Labelها، Selectها، Checkboxها، Radioها، Textareaها و دکمههای فرم را بدون نوشتن مقدار زیادی CSS مدیریت کنیم. در این مقاله ابتدا ساختار پایه فرم در Bootstrap را یاد میگیریم و سپس به سراغ انواع Input، اندازهها، Select، Checkbox، Radio، Range، File Input، Input Group، Floating Labels، Validation و در نهایت ساخت یک فرم واقعی ثبتنام میرویم.
فرم چیست؟
فرم مجموعهای از کنترلهای ورودی است که کاربر از طریق آن اطلاعاتی را وارد یا انتخاب میکند.
برای مثال فرم ثبتنام میتواند شامل موارد زیر باشد:
First Name
Last Name
Email
Password
Gender
Country
Terms
Registerساختار ساده یک فرم HTML:
<form>
<label>
First Name
</label>
<input type="text">
<button type="submit">
Register
</button>
</form>Bootstrap کمک میکند این فرم ظاهر حرفهایتر و منظمتری داشته باشد.
کلاس form-control
یکی از مهمترین کلاسهای Bootstrap برای Inputها:
form-controlاست.
مثال:
<input
type="text"
class="form-control">این کلاس ظاهر Input را با Style استاندارد Bootstrap هماهنگ میکند.
Label در Bootstrap
برای Label معمولاً از:
form-labelاستفاده میکنیم.
مثال:
<label
for="firstName"
class="form-label">
First Name
</label>
<input
type="text"
id="firstName"
class="form-control">وجود for در Label و id متناظر در Input باعث ارتباط صحیح آنها میشود.
چرا ارتباط Label و Input مهم است؟
کاربر میتواند روی متن Label کلیک کند و Focus به Input منتقل شود.
همچنین ابزارهای Accessibility میتوانند رابطه بین Label و کنترل فرم را بهتر تشخیص دهند.
بنابراین بهتر است همیشه از الگوی زیر استفاده کنیم:
<label for="email" class="form-label">
Email
</label>
<input
type="email"
id="email"
class="form-control">فاصله بین Form Controls
یکی از روشهای رایج برای جدا کردن کنترلهای فرم:
<div class="mb-3">
<label for="username" class="form-label">
Username
</label>
<input
type="text"
id="username"
class="form-control">
</div>است.
در اینجا:
mb-3بین این کنترل و بخش بعدی فاصله ایجاد میکند.
Text Input
برای Input متنی:
<div class="mb-3">
<label for="username" class="form-label">
Username
</label>
<input
type="text"
id="username"
class="form-control">
</div>Email Input
برای Email:
<div class="mb-3">
<label for="email" class="form-label">
Email Address
</label>
<input
type="email"
id="email"
class="form-control">
</div>استفاده از type="email" باعث میشود مرورگر بتواند رفتار مناسبتری برای این نوع داده داشته باشد.
Password Input
<div class="mb-3">
<label for="password" class="form-label">
Password
</label>
<input
type="password"
id="password"
class="form-control">
</div>محتوای Password در صفحه به صورت مستقیم نمایش داده نمیشود.
Number Input
<div class="mb-3">
<label for="age" class="form-label">
Age
</label>
<input
type="number"
id="age"
class="form-control">
</div>در صورت نیاز میتوان محدودیتهایی مانند min و max نیز تعریف کرد:
<input
type="number"
class="form-control"
min="1"
max="100">Date Input
برای تاریخ:
<div class="mb-3">
<label for="birthDate" class="form-label">
Birth Date
</label>
<input
type="date"
id="birthDate"
class="form-control">
</div>Color Input
<div class="mb-3">
<label for="color" class="form-label">
Favorite Color
</label>
<input
type="color"
id="color"
class="form-control form-control-color">
</div>کلاس form-control-color برای ظاهر مناسب Color Picker استفاده میشود.
File Input
برای انتخاب فایل:
<div class="mb-3">
<label for="file" class="form-label">
Upload File
</label>
<input
type="file"
id="file"
class="form-control">
</div>برای چند فایل:
<input
type="file"
class="form-control"
multiple>البته انتخاب فایل به تنهایی باعث Upload شدن آن روی سرور نمیشود و برای Upload واقعی باید Backend نیز فایل را دریافت و پردازش کند.
Textarea
برای متن چندخطی از textarea استفاده میکنیم:
<div class="mb-3">
<label for="description" class="form-label">
Description
</label>
<textarea
id="description"
class="form-control"
rows="5"></textarea>
</div>rows ارتفاع تقریبی اولیه Textarea را مشخص میکند.
Placeholder
میتوان برای راهنمایی کاربر از Placeholder استفاده کرد:
<input
type="text"
class="form-control"
placeholder="Enter your name">Placeholder نباید جایگزین Label شود.
بهتر است هر Input مهم همچنان Label مشخص داشته باشد.
Required
برای اجباری کردن یک Field در سطح HTML:
<input
type="email"
class="form-control"
required>مرورگر قبل از Submit میتواند خالی بودن این Field را بررسی کند.
Disabled Input
برای غیرفعال کردن Input:
<input
type="text"
class="form-control"
value="Disabled"
disabled>کاربر نمیتواند مقدار آن را تغییر دهد.
Readonly Input
برای نمایش مقدار غیرقابل ویرایش:
<input
type="text"
class="form-control"
value="Read Only"
readonly>تفاوت مهم:
disabled
|
+-- User cannot edit
+-- Normally not submitted with form
readonly
|
+-- User cannot edit
+-- Value can still participate in form submissionInput Size
Bootstrap اندازههای مختلفی برای Form Controlها دارد.
کوچک
<input
type="text"
class="form-control form-control-sm">معمولی
<input
type="text"
class="form-control">بزرگ
<input
type="text"
class="form-control form-control-lg">Select
برای ایجاد Dropdown از form-select استفاده میکنیم.
<div class="mb-3">
<label for="country" class="form-label">
Country
</label>
<select
id="country"
class="form-select">
<option selected>
Select a country
</option>
<option value="tr">
Türkiye
</option>
<option value="ir">
Iran
</option>
<option value="de">
Germany
</option>
</select>
</div>Select Multiple
اگر کاربر بتواند چند گزینه را انتخاب کند:
<select
class="form-select"
multiple>
<option>HTML</option>
<option>CSS</option>
<option>JavaScript</option>
<option>Bootstrap</option>
</select>Select Size
میتوان تعداد گزینههای قابل مشاهده را نیز مشخص کرد:
<select
class="form-select"
size="4">
<option>HTML</option>
<option>CSS</option>
<option>JavaScript</option>
<option>Bootstrap</option>
<option>React</option>
</select>Checkbox
برای Checkbox از ساختار زیر استفاده میکنیم:
<div class="form-check">
<input
class="form-check-input"
type="checkbox"
id="terms">
<label
class="form-check-label"
for="terms">
I agree to the terms.
</label>
</div>کلاسهای مهم:
form-check
form-check-input
form-check-labelCheckbox انتخابشده
برای انتخاب اولیه:
<input
class="form-check-input"
type="checkbox"
id="newsletter"
checked>
<label
class="form-check-label"
for="newsletter">
Subscribe to newsletter
</label>Checkbox Disabled
<div class="form-check">
<input
class="form-check-input"
type="checkbox"
id="disabledCheck"
disabled>
<label
class="form-check-label"
for="disabledCheck">
Disabled Option
</label>
</div>Radio Button
Radio Button زمانی استفاده میشود که کاربر باید معمولاً یکی از چند گزینه را انتخاب کند.
مثال:
<div class="form-check">
<input
class="form-check-input"
type="radio"
name="gender"
id="male"
value="male">
<label
class="form-check-label"
for="male">
Male
</label>
</div>
<div class="form-check">
<input
class="form-check-input"
type="radio"
name="gender"
id="female"
value="female">
<label
class="form-check-label"
for="female">
Female
</label>
</div>نکته مهم این است که Radioهایی که باید یک گروه انتخابی باشند، name یکسان داشته باشند.
Radio انتخابشده
<input
class="form-check-input"
type="radio"
name="plan"
id="basic"
checked>
<label
class="form-check-label"
for="basic">
Basic
</label>Switch
Bootstrap امکان نمایش Checkbox به شکل Switch را نیز فراهم میکند.
<div class="form-check form-switch">
<input
class="form-check-input"
type="checkbox"
id="notifications">
<label
class="form-check-label"
for="notifications">
Enable Notifications
</label>
</div>این الگو برای تنظیماتی مانند:
Notifications
Dark Mode
Auto Save
Email Alerts
کاربرد زیادی دارد.
Range
برای ایجاد Slider:
<label
for="volume"
class="form-label">
Volume
</label>
<input
type="range"
class="form-range"
id="volume">میتوان حداقل و حداکثر نیز تعیین کرد:
<input
type="range"
class="form-range"
min="0"
max="100"
step="10">Input Group
یکی از قابلیتهای بسیار کاربردی Bootstrap، Input Group است.
فرض کنید میخواهیم یک Prefix کنار Input قرار دهیم:
<div class="input-group">
<span class="input-group-text">
$
</span>
<input
type="number"
class="form-control">
</div>ساختار:
+-----+----------------------+
| $ | Amount |
+-----+----------------------+Input Group با Text
<div class="input-group">
<span class="input-group-text">
Username
</span>
<input
type="text"
class="form-control">
</div>Input Group با Button
میتوان Button را نیز کنار Input قرار داد:
<div class="input-group">
<input
type="text"
class="form-control"
placeholder="Search">
<button
class="btn btn-primary"
type="button">
Search
</button>
</div>این الگو برای Search Box بسیار کاربردی است.
Input Group برای جستجو
یک Search Box واقعی:
<div class="input-group">
<input
type="search"
class="form-control"
placeholder="Search products...">
<button
type="button"
class="btn btn-dark">
Search
</button>
</div>Floating Labels
Bootstrap امکان قرار دادن Label شناور را نیز فراهم میکند.
ساختار:
<div class="form-floating mb-3">
<input
type="email"
class="form-control"
id="email"
placeholder="name@example.com">
<label for="email">
Email Address
</label>
</div>در این حالت Label ابتدا در داخل Field قرار میگیرد و هنگام Focus یا وجود مقدار، به قسمت بالاتر منتقل میشود.
Floating Label برای Password
<div class="form-floating mb-3">
<input
type="password"
class="form-control"
id="password"
placeholder="Password">
<label for="password">
Password
</label>
</div>وجود placeholder در Floating Labelها مهم است تا رفتار Component مطابق انتظار Bootstrap باشد.
Floating Label برای Textarea
<div class="form-floating">
<textarea
class="form-control"
placeholder="Description"
id="description"
style="height: 120px"></textarea>
<label for="description">
Description
</label>
</div>Form Validation
یکی از قابلیتهای مهم فرمها، Validation است.
Validation یعنی بررسی کنیم اطلاعات واردشده شرایط موردنیاز را دارد یا خیر.
مثلاً:
<input
type="email"
class="form-control is-invalid"
required>کلاس:
is-invalidظاهر Field را در وضعیت نامعتبر قرار میدهد.
نمایش پیام خطا
برای نمایش پیام خطا:
<input
type="email"
class="form-control is-invalid">
<div class="invalid-feedback">
Please enter a valid email address.
</div>invalid-feedback پیام مربوط به خطا را نمایش میدهد.
وضعیت Valid
برای نمایش موفق بودن Field:
<input
type="email"
class="form-control is-valid">
<div class="valid-feedback">
Looks good!
</div>کلاس:
is-validبرای نمایش حالت معتبر استفاده میشود.
تفاوت HTML Validation و Bootstrap Validation
یک نکته بسیار مهم:
Bootstrap خودش Backend Validation انجام نمیدهد.
مثلاً:
<input
type="email"
class="form-control"
required>Validation اولیه توسط Browser و HTML انجام میشود.
اما:
HTML Validation
|
v
Browser
Bootstrap
|
v
Visual Styling
Backend Validation
|
v
Serverدر یک پروژه واقعی، Validation باید در Backend نیز انجام شود.
نباید صرفاً به Validation سمت Client اعتماد کنیم.
Validation با JavaScript
برای ایجاد Validation سفارشی میتوان از JavaScript نیز استفاده کرد.
یک نمونه ساده:
<form class="needs-validation" novalidate>
<div class="mb-3">
<label
for="email"
class="form-label">
Email
</label>
<input
type="email"
class="form-control"
id="email"
required>
<div class="invalid-feedback">
Please enter a valid email.
</div>
</div>
<button
type="submit"
class="btn btn-primary">
Submit
</button>
</form>JavaScript:
(() => {
'use strict';
const forms =
document.querySelectorAll('.needs-validation');
Array.from(forms).forEach(form => {
form.addEventListener('submit', event => {
if (!form.checkValidity()) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
})();در اینجا:
needs-validationبرای مشخص کردن فرم استفاده شده است.
و:
was-validatedپس از تلاش برای Submit روی فرم قرار میگیرد تا Styleهای Validation نمایش داده شوند.
Form Grid
یکی از قابلیتهای مهم Bootstrap ترکیب Form با Grid است.
مثلاً دو Input در یک Row:
<div class="row">
<div class="col-md-6 mb-3">
<label
for="firstName"
class="form-label">
First Name
</label>
<input
type="text"
id="firstName"
class="form-control">
</div>
<div class="col-md-6 mb-3">
<label
for="lastName"
class="form-label">
Last Name
</label>
<input
type="text"
id="lastName"
class="form-control">
</div>
</div>در دسکتاپ:
+----------------------+----------------------+
| First Name | Last Name |
+----------------------+----------------------+در موبایل:
+----------------------+
| First Name |
+----------------------+
| Last Name |
+----------------------+
فرم دو ستونه
میتوان فرم کاملتری ایجاد کرد:
<form>
<div class="row g-3">
<div class="col-md-6">
<label
for="firstName"
class="form-label">
First Name
</label>
<input
type="text"
id="firstName"
class="form-control">
</div>
<div class="col-md-6">
<label
for="lastName"
class="form-label">
Last Name
</label>
<input
type="text"
id="lastName"
class="form-control">
</div>
<div class="col-12">
<label
for="email"
class="form-label">
Email
</label>
<input
type="email"
id="email"
class="form-control">
</div>
<div class="col-12">
<label
for="address"
class="form-label">
Address
</label>
<input
type="text"
id="address"
class="form-control">
</div>
</div>
</form>ساخت فرم ثبتنام کامل
حالا تمام مفاهیم مهم را با هم ترکیب میکنیم.
<div class="container py-5">
<div class="row justify-content-center">
<div class="col-12 col-md-10 col-lg-8 col-xl-6">
<div class="border rounded-4 shadow-sm p-4">
<div class="text-center mb-4">
<h1 class="fw-bold">
Create Account
</h1>
<p class="text-secondary mb-0">
Register a new account
</p>
</div>
<form>
<div class="row g-3">
<div class="col-md-6">
<label
for="firstName"
class="form-label">
First Name
</label>
<input
type="text"
id="firstName"
class="form-control"
required>
</div>
<div class="col-md-6">
<label
for="lastName"
class="form-label">
Last Name
</label>
<input
type="text"
id="lastName"
class="form-control"
required>
</div>
<div class="col-12">
<label
for="email"
class="form-label">
Email
</label>
<input
type="email"
id="email"
class="form-control"
placeholder="name@example.com"
required>
</div>
<div class="col-12">
<label
for="password"
class="form-label">
Password
</label>
<input
type="password"
id="password"
class="form-control"
required>
</div>
<div class="col-12">
<label
for="country"
class="form-label">
Country
</label>
<select
id="country"
class="form-select"
required>
<option selected disabled value="">
Select Country
</option>
<option value="tr">
Türkiye
</option>
<option value="ir">
Iran
</option>
<option value="de">
Germany
</option>
</select>
</div>
<div class="col-12">
<div class="form-check">
<input
class="form-check-input"
type="checkbox"
id="terms"
required>
<label
class="form-check-label"
for="terms">
I agree to the terms.
</label>
</div>
</div>
<div class="col-12">
<button
type="submit"
class="btn btn-primary w-100">
Create Account
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>ساختار کلی این فرم:
+--------------------------------------+
| Create Account |
| |
| First Name | Last Name |
|--------------------------------------|
| Email |
|--------------------------------------|
| Password |
|--------------------------------------|
| Country |
|--------------------------------------|
| [ ] I agree to the terms |
|--------------------------------------|
| Create Account |
+--------------------------------------+Form Helper Text
گاهی لازم است زیر Input توضیح کوتاهی نمایش دهیم.
مثلاً:
<label
for="username"
class="form-label">
Username
</label>
<input
type="text"
id="username"
class="form-control">
<div class="form-text">
Your username must be unique.
</div>کلاس:
form-textبرای این کار استفاده میشود.
Input Group همراه با Validation
میتوان Input Group را نیز با Validation ترکیب کرد:
<div class="input-group has-validation">
<span class="input-group-text">
@
</span>
<input
type="text"
class="form-control is-invalid">
<div class="invalid-feedback">
Please enter a username.
</div>
</div>وجود has-validation در چنین ساختاری میتواند برای نمایش صحیح Feedback اهمیت داشته باشد.
فرم Search
یک فرم جستجوی ساده:
<form>
<div class="input-group">
<input
type="search"
class="form-control"
placeholder="Search...">
<button
type="submit"
class="btn btn-primary">
Search
</button>
</div>
</form>فرم Login
یک Login Form ساده:
<div class="container py-5">
<div class="row justify-content-center">
<div class="col-12 col-sm-10 col-md-6 col-lg-4">
<div class="border rounded-4 shadow-sm p-4">
<h2 class="text-center fw-bold mb-4">
Login
</h2>
<form>
<div class="mb-3">
<label
for="email"
class="form-label">
Email
</label>
<input
type="email"
id="email"
class="form-control"
required>
</div>
<div class="mb-3">
<label
for="password"
class="form-label">
Password
</label>
<input
type="password"
id="password"
class="form-control"
required>
</div>
<div class="form-check mb-3">
<input
type="checkbox"
class="form-check-input"
id="remember">
<label
class="form-check-label"
for="remember">
Remember me
</label>
</div>
<button
type="submit"
class="btn btn-primary w-100">
Login
</button>
</form>
</div>
</div>
</div>
</div>نکات مهم طراحی Form
هنگام طراحی فرمهای واقعی به نکات زیر توجه کنید.
Label را حذف نکنید
اگرچه Placeholder میتواند راهنمای کاربر باشد، اما بهتر است Label مناسب نیز داشته باشیم.
پیام خطا واضح باشد
به جای:
Invalidبهتر است پیام مشخص باشد:
Please enter a valid email address.Fieldهای غیرضروری را حذف کنید
فرم طولانی معمولاً تجربه کاربری پیچیدهتری ایجاد میکند.
نوع Input را درست انتخاب کنید
برای Email:
<input type="email">برای Password:
<input type="password">برای Date:
<input type="date">استفاده از نوع مناسب به مرورگر و ابزارهای مختلف کمک میکند.
Validation سمت Server را فراموش نکنید
Validation سمت Client برای تجربه کاربری مفید است، اما امنیت برنامه نباید به آن وابسته باشد.
دادههای فرم باید در Server نیز بررسی و اعتبارسنجی شوند.
تمرین عملی
یک صفحه ثبتنام حرفهای با Bootstrap بسازید.
فرم باید شامل موارد زیر باشد:
First Name
Last Name
Email
Phone Number
Password
Confirm Password
Country
Gender
Newsletter
Terms
Register Button
شرایط:
فرم Responsive باشد.
First Name و Last Name در Desktop کنار هم باشند.
در Mobile زیر یکدیگر قرار بگیرند.
Inputها از
form-controlاستفاده کنند.Select از
form-selectاستفاده کند.Checkboxها از
form-checkاستفاده کنند.برای Terms از
requiredاستفاده شود.Register Button تمام عرض باشد.
حداقل یک Field را با
is-invalidوinvalid-feedbackآزمایش کنید.فرم را داخل یک Card یا Box زیبا قرار دهید.
ساختار پیشنهادی:
Desktop
+---------------------------------------------+
| Create Account |
| |
| First Name Last Name |
| Email |
| Phone |
| Password Confirm Password |
| Country |
| Gender |
| [ ] Newsletter |
| [ ] Terms |
| |
| Register |
+---------------------------------------------+در موبایل:
+--------------------------+
| Create Account |
| |
| First Name |
| Last Name |
| Email |
| Phone |
| Password |
| Confirm Password |
| Country |
| Gender |
| [ ] Newsletter |
| [ ] Terms |
| |
| Register |
+--------------------------+جمعبندی
در این مقاله با Forms در Bootstrap به صورت کامل آشنا شدیم.
ابتدا با form-control برای Inputهای معمولی کار کردیم و سپس انواع Input مانند:
text
email
password
number
date
color
fileرا بررسی کردیم.
سپس textarea، Placeholder، Required، Disabled و Readonly را یاد گرفتیم.
در ادامه با form-select برای Select و با:
form-check
form-check-input
form-check-labelبرای Checkbox و Radio کار کردیم.
همچنین Switch و Range را بررسی کردیم.
بعد از آن به سراغ قابلیتهای مهمتر رفتیم:
Input Group
Floating Labels
Form Validation
Feedback
Form Gridو در نهایت چند فرم واقعی مانند Login، Search و Register ایجاد کردیم.
اکنون میتوانیم فرمهای Responsive و حرفهای را با Bootstrap طراحی کنیم.
نظرات
هنوز نظری ثبت نشده است.