Alerts، Toasts و Progress در Bootstrap
بهنام نوبخت · ۱۴۰۵/۷/۱۲
در بسیاری از صفحات وب لازم است نتیجه یک عملیات یا وضعیت خاص را به کاربر اطلاع دهیم. برای مثال بعد از ثبتنام باید پیام موفقیت نمایش داده شود، هنگام حذف یک محصول باید هشدار مناسب نشان داده شود، اگر اطلاعات واردشده اشتباه باشد باید پیام خطا نمایش داده شود یا هنگام آپلود یک فایل میزان پیشرفت عملیات به کاربر نشان داده شود. Bootstrap برای این نیازها چند کامپوننت کاربردی در اختیار ما قرار میدهد. Alert برای نمایش پیامهای مهم و قابل مشاهده در صفحه، Toast برای نمایش اعلانهای کوتاه و موقتی و Progress برای نمایش میزان پیشرفت یک عملیات استفاده میشود. در این مقاله ابتدا Alertها را یاد میگیریم، سپس با انواع Toast و نحوه کنترل آنها با JavaScript آشنا میشویم و در ادامه Progress Bar را بررسی میکنیم. در پایان نیز این سه کامپوننت را در یک سناریوی واقعی مانند داشبورد مدیریت و فرم آپلود فایل ترکیب خواهیم کرد.
Alert چیست؟
Alert برای نمایش یک پیام مهم به کاربر استفاده میشود.
برای مثال:
<div class="alert alert-primary" role="alert">
این یک پیام اطلاعرسانی است.
</div>Alert معمولاً در بخشی از صفحه نمایش داده میشود و تا زمانی که خودمان آن را حذف نکنیم، باقی میماند.
انواع Alert
Bootstrap چند نوع Alert آماده دارد.
Primary
<div class="alert alert-primary" role="alert">
اطلاعات جدیدی در دسترس است.
</div>Secondary
<div class="alert alert-secondary" role="alert">
این یک پیام عمومی است.
</div>Success
برای عملیات موفق:
<div class="alert alert-success" role="alert">
اطلاعات با موفقیت ذخیره شد.
</div>Danger
برای خطا یا عملیات خطرناک:
<div class="alert alert-danger" role="alert">
ذخیره اطلاعات با خطا مواجه شد.
</div>Warning
برای هشدار:
<div class="alert alert-warning" role="alert">
رمز عبور شما ضعیف است.
</div>Info
برای اطلاعات:
<div class="alert alert-info" role="alert">
سیستم در ساعت 12 شب بروزرسانی خواهد شد.
</div>Light
<div class="alert alert-light" role="alert">
یک پیام ساده.
</div>Dark
<div class="alert alert-dark" role="alert">
یک پیام با ظاهر تیره.
</div>Alert و مفهوم رنگها
در یک پروژه واقعی بهتر است رنگ Alert با مفهوم پیام هماهنگ باشد:
Success → عملیات موفق
Danger → خطا
Warning → هشدار
Info → اطلاعرسانیاما بهتر است مفهوم پیام فقط از طریق رنگ منتقل نشود و متن مناسب نیز وجود داشته باشد.
Alert با عنوان
میتوانیم داخل Alert یک Heading داشته باشیم:
<div class="alert alert-success" role="alert">
<h4 class="alert-heading">
عملیات موفق بود!
</h4>
<p>
اطلاعات حساب کاربری شما با موفقیت ذخیره شد.
</p>
</div>این ساختار برای پیامهای مهم بسیار مناسب است.
Alert با لینک
میتوانیم لینک را نیز داخل Alert قرار دهیم:
<div class="alert alert-primary" role="alert">
برای مشاهده جزئیات
<a href="#" class="alert-link">
اینجا کلیک کنید
</a>.
</div>کلاس alert-link باعث میشود لینک با ظاهر مناسب Alert نمایش داده شود.
Alert با دکمه بستن
اگر بخواهیم کاربر بتواند Alert را ببندد، باید از alert-dismissible استفاده کنیم:
<div
class="alert alert-warning alert-dismissible fade show"
role="alert"
>
این پیام را میتوانید ببندید.
<button
type="button"
class="btn-close"
data-bs-dismiss="alert"
aria-label="بستن"
></button>
</div>در این مثال:
alert-dismissibleفضای مناسب برای دکمه بستن ایجاد میکند.btn-closeدکمه بستن است.data-bs-dismiss="alert"باعث میشود Alert بسته شود.fade showافکت نمایش و مخفی شدن را فعال میکند.
برای این قابلیت باید Bootstrap JavaScript نیز در صفحه بارگذاری شده باشد.
Alert ساده یا Dismissible؟
اگر پیام باید همیشه قابل مشاهده باشد:
<div class="alert alert-info">
...
</div>اگر کاربر باید بتواند پیام را ببندد:
<div class="alert alert-info alert-dismissible fade show">
...
</div>
در پروژههای واقعی، این انتخاب به اهمیت و طول عمر پیام بستگی دارد.
Alert برای فرم ثبتنام
فرض کنیم کاربر یک فرم ثبتنام دارد:
<div class="alert alert-success" role="alert">
ثبتنام شما با موفقیت انجام شد.
</div>یا در صورت خطا:
<div class="alert alert-danger" role="alert">
امکان ثبتنام وجود ندارد. اطلاعات واردشده را بررسی کنید.
</div>این الگو در صفحات Login و Register بسیار رایج است.
Alert برای پیامهای Validation
میتوان چند خطا را داخل یک Alert نمایش داد:
<div class="alert alert-danger" role="alert">
<h5 class="alert-heading">
خطاهای فرم
</h5>
<ul class="mb-0">
<li>
ایمیل وارد نشده است.
</li>
<li>
رمز عبور باید حداقل 8 کاراکتر باشد.
</li>
<li>
رمز عبور و تکرار آن یکسان نیستند.
</li>
</ul>
</div>این روش برای نمایش خطاهای کلی فرم مناسب است.
Alert در سمت سرور
در برنامههای واقعی، پیام Alert معمولاً به صورت مستقیم داخل HTML ثابت نوشته نمیشود.
مثلاً در یک برنامه ASP.NET Core ممکن است نتیجه عملیات از Server به Client ارسال شود:
Server
|
v
Operation
|
v
Result
|
v
Client
|
v
Bootstrap Alertبرای مثال:
{
"success": true,
"message": "اطلاعات با موفقیت ذخیره شد."
}سپس Frontend بر اساس مقدار success، Alert مناسب را ایجاد میکند.
Toast چیست؟
Toast یک اعلان کوچک و معمولاً موقتی است که بدون اشغال بخش زیادی از صفحه به کاربر نمایش داده میشود.
برای مثال:
+-------------------------+
| Success |
| Data saved successfully |
+-------------------------+Toast برای پیامهایی مانند موارد زیر بسیار مناسب است:
ذخیره موفق
حذف موفق
ارسال پیام
ورود موفق
کپی شدن متن
تغییر تنظیمات
دریافت اعلان جدید
ساخت Toast
یک Toast ساده:
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<strong class="me-auto">
سیستم
</strong>
<small>
اکنون
</small>
<button
type="button"
class="btn-close"
data-bs-dismiss="toast"
aria-label="بستن"
></button>
</div>
<div class="toast-body">
اطلاعات با موفقیت ذخیره شد.
</div>
</div>اما برای اینکه Toast نمایش داده شود، باید آن را با JavaScript فعال کنیم.
Toast با JavaScript
ابتدا Bootstrap Bundle را در صفحه قرار دهید:
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"></script>سپس:
<script>
const toastElement = document.getElementById('saveToast');
const toast = new bootstrap.Toast(toastElement);
toast.show();
</script>HTML:
<div
id="saveToast"
class="toast"
role="alert"
aria-live="assertive"
aria-atomic="true"
>
<div class="toast-header">
<strong class="me-auto">
سیستم
</strong>
<small>
اکنون
</small>
<button
type="button"
class="btn-close"
data-bs-dismiss="toast"
aria-label="بستن"
></button>
</div>
<div class="toast-body">
اطلاعات با موفقیت ذخیره شد.
</div>
</div>Toast Container
معمولاً Toast را مستقیماً در وسط صفحه قرار نمیدهیم.
بهتر است یک Container داشته باشیم:
<div class="toast-container position-fixed bottom-0 end-0 p-3">
<div
id="saveToast"
class="toast"
role="alert"
aria-live="assertive"
aria-atomic="true"
>
<div class="toast-header">
<strong class="me-auto">
سیستم
</strong>
<small>
اکنون
</small>
<button
type="button"
class="btn-close"
data-bs-dismiss="toast"
aria-label="بستن"
></button>
</div>
<div class="toast-body">
اطلاعات با موفقیت ذخیره شد.
</div>
</div>
</div>در اینجا:
position-fixedToast را نسبت به صفحه ثابت میکند.
و:
bottom-0 end-0آن را در پایین و سمت انتهایی صفحه قرار میدهد.
در صفحه RTL، این Utilityها نیز باید با مفهوم منطقی Bootstrap هماهنگ استفاده شوند.
Toast در بالای صفحه
میتوان Toast را در بالای صفحه قرار داد:
<div class="toast-container position-fixed top-0 end-0 p-3">
...
</div>Toast با دکمه
یک نمونه کاربردی:
<button
type="button"
class="btn btn-success"
id="saveButton"
>
ذخیره اطلاعات
</button>
<div class="toast-container position-fixed bottom-0 end-0 p-3">
<div
id="saveToast"
class="toast"
role="alert"
aria-live="polite"
aria-atomic="true"
>
<div class="toast-header">
<strong class="me-auto">
پیام سیستم
</strong>
<button
type="button"
class="btn-close"
data-bs-dismiss="toast"
aria-label="بستن"
></button>
</div>
<div class="toast-body">
اطلاعات ذخیره شد.
</div>
</div>
</div>
<script>
const saveButton =
document.getElementById('saveButton');
const saveToastElement =
document.getElementById('saveToast');
const saveToast =
new bootstrap.Toast(saveToastElement);
saveButton.addEventListener('click', function () {
saveToast.show();
});
</script>با کلیک روی دکمه، Toast نمایش داده میشود.
Toast با زمان مشخص
میتوان مدت نمایش Toast را نیز کنترل کرد:
const toast = new bootstrap.Toast(
toastElement,
{
delay: 3000
}
);
toast.show();در این مثال Toast تقریباً بعد از 3 ثانیه مخفی میشود.
Alert یا Toast؟
انتخاب بین این دو بسیار مهم است.
ویژگی | Alert | Toast |
|---|---|---|
پیام مهم | مناسب | مناسب |
پیام موقتی | کمتر مناسب | بسیار مناسب |
باقی ماندن در صفحه | بله | معمولاً خیر |
نیاز به JavaScript برای نمایش | خیر | معمولاً بله |
پیام بعد از ذخیره | مناسب | مناسب |
خطاهای مهم فرم | مناسب | کمتر مناسب |
اعلان کوتاه | کمتر مناسب | مناسب |
به صورت ساده:
Alert برای پیامهایی است که باید در جریان محتوای صفحه دیده شوند.
Toast برای اعلانهای کوتاه و غیرمزاحم بسیار مناسب است.
Progress چیست؟
Progress Bar برای نمایش میزان پیشرفت یک عملیات استفاده میشود.
مثلاً:
Upload
[############--------] 60%در Bootstrap میتوانیم چنین Progress Barای ایجاد کنیم.
Progress ساده
<div class="progress">
<div
class="progress-bar"
role="progressbar"
style="width: 50%;"
aria-valuenow="50"
aria-valuemin="0"
aria-valuemax="100"
>
50%
</div>
</div>در این مثال میزان پیشرفت 50 درصد است.
Progress بدون متن
گاهی فقط خود نوار را میخواهیم:
<div class="progress">
<div
class="progress-bar"
role="progressbar"
style="width: 70%;"
aria-valuenow="70"
aria-valuemin="0"
aria-valuemax="100"
></div>
</div>Progress با رنگ
میتوانیم رنگ Progress را تغییر دهیم:
<div class="progress">
<div
class="progress-bar bg-success"
style="width: 80%;"
>
80%
</div>
</div>نمونه خطا:
<div class="progress">
<div
class="progress-bar bg-danger"
style="width: 30%;"
>
30%
</div>
</div>یا هشدار:
<div class="progress">
<div
class="progress-bar bg-warning"
style="width: 60%;"
>
60%
</div>
</div>Progress چندمرحلهای
Bootstrap امکان قرار دادن چند Progress Bar داخل یک Progress Container را نیز فراهم میکند:
<div class="progress">
<div
class="progress-bar"
style="width: 30%;"
>
30%
</div>
<div
class="progress-bar bg-success"
style="width: 40%;"
>
40%
</div>
<div
class="progress-bar bg-warning"
style="width: 30%;"
>
30%
</div>
</div>مجموع بخشها در این مثال 100 درصد است.
این قابلیت برای نمایش مراحل مختلف یک فرآیند مفید است.
Progress Striped
برای ایجاد ظاهر راهراه میتوانیم از progress-bar-striped استفاده کنیم:
<div class="progress">
<div
class="progress-bar progress-bar-striped"
style="width: 70%;"
>
70%
</div>
</div>Progress Animated
برای متحرک کردن Stripeها:
<div class="progress">
<div
class="progress-bar progress-bar-striped progress-bar-animated"
style="width: 70%;"
>
70%
</div>
</div>این حالت برای عملیات در حال انجام میتواند مناسب باشد.
Progress در آپلود فایل
فرض کنیم کاربر در حال آپلود یک فایل است:
<div class="mb-2">
در حال آپلود فایل...
</div>
<div class="progress">
<div
id="uploadProgress"
class="progress-bar"
role="progressbar"
style="width: 0%;"
aria-valuenow="0"
aria-valuemin="0"
aria-valuemax="100"
>
0%
</div>
</div>با JavaScript میتوان مقدار را تغییر داد.
const progress =
document.getElementById('uploadProgress');
let value = 0;
const interval = setInterval(function () {
value += 10;
progress.style.width = value + '%';
progress.setAttribute(
'aria-valuenow',
value
);
progress.textContent =
value + '%';
if (value >= 100) {
clearInterval(interval);
}
}, 500);در این مثال برای شبیهسازی یک فرآیند از setInterval استفاده کردهایم.
در پروژه واقعی، مقدار Progress باید بر اساس وضعیت واقعی عملیات محاسبه شود.
Progress در مراحل ثبتنام
فرض کنید ثبتنام کاربر چند مرحله دارد:
Step 1 → Account
Step 2 → Profile
Step 3 → Confirmationمیتوانیم میزان پیشرفت را نمایش دهیم:
<div class="mb-2">
مرحله 2 از 3
</div>
<div class="progress">
<div
class="progress-bar"
role="progressbar"
style="width: 66%;"
aria-valuenow="66"
aria-valuemin="0"
aria-valuemax="100"
>
66%
</div>
</div>Progress در داشبورد
مثلاً میتوانیم میزان تکمیل پروفایل را نشان دهیم:
<div class="card">
<div class="card-body">
<h5 class="card-title">
تکمیل پروفایل
</h5>
<p>
پروفایل شما 75 درصد تکمیل شده است.
</p>
<div class="progress">
<div
class="progress-bar"
role="progressbar"
style="width: 75%;"
aria-valuenow="75"
aria-valuemin="0"
aria-valuemax="100"
>
75%
</div>
</div>
</div>
</div>نمونه واقعی: فرم ذخیره اطلاعات
میتوانیم Alert و Toast را با یک فرم ترکیب کنیم:
<div class="container py-5">
<div class="row justify-content-center">
<div class="col-12 col-md-8 col-lg-6">
<div class="card shadow-sm">
<div class="card-body">
<h1 class="h4 mb-4">
اطلاعات کاربری
</h1>
<div
id="errorAlert"
class="alert alert-danger d-none"
role="alert"
>
لطفاً نام و ایمیل را وارد کنید.
</div>
<form id="profileForm">
<div class="mb-3">
<label
for="name"
class="form-label"
>
نام
</label>
<input
type="text"
id="name"
class="form-control"
>
</div>
<div class="mb-3">
<label
for="email"
class="form-label"
>
ایمیل
</label>
<input
type="email"
id="email"
class="form-control"
>
</div>
<button
type="submit"
class="btn btn-primary"
>
ذخیره
</button>
</form>
</div>
</div>
</div>
</div>
</div>
<div class="toast-container position-fixed bottom-0 end-0 p-3">
<div
id="successToast"
class="toast"
role="alert"
aria-live="polite"
aria-atomic="true"
>
<div class="toast-header">
<strong class="me-auto">
سیستم
</strong>
<button
type="button"
class="btn-close"
data-bs-dismiss="toast"
aria-label="بستن"
></button>
</div>
<div class="toast-body">
اطلاعات با موفقیت ذخیره شد.
</div>
</div>
</div>
<script>
const form =
document.getElementById('profileForm');
const errorAlert =
document.getElementById('errorAlert');
const successToastElement =
document.getElementById('successToast');
const successToast =
new bootstrap.Toast(successToastElement);
form.addEventListener('submit', function (event) {
event.preventDefault();
const name =
document.getElementById('name').value.trim();
const email =
document.getElementById('email').value.trim();
if (!name || !email) {
errorAlert.classList.remove('d-none');
return;
}
errorAlert.classList.add('d-none');
successToast.show();
});
</script>در این مثال:
خطای فرم با Alert نمایش داده میشود.
پیام موفقیت با Toast نمایش داده میشود.
d-noneبرای مخفی کردن Alert استفاده شده است.JavaScript رفتار فرم را کنترل میکند.
نمونه واقعی: آپلود فایل
یک UI ساده برای آپلود فایل:
<div class="container py-5">
<div class="card">
<div class="card-body">
<h2 class="h5 mb-3">
آپلود فایل
</h2>
<input
type="file"
class="form-control mb-3"
>
<div class="mb-2">
میزان پیشرفت
</div>
<div class="progress">
<div
id="progressBar"
class="progress-bar progress-bar-striped progress-bar-animated"
role="progressbar"
style="width: 0%;"
aria-valuenow="0"
aria-valuemin="0"
aria-valuemax="100"
>
0%
</div>
</div>
</div>
</div>
</div>در پروژه واقعی میتوان Progress را به API یا Upload Service متصل کرد.
Alert، Toast و Progress در یک معماری Frontend
در یک پروژه واقعی بهتر است مسئولیت هر کامپوننت مشخص باشد:
User Action
|
v
Application Logic
|
+------> Error -------> Alert
|
+------> Success -----> Toast
|
+------> Long Process -> Progressبرای مثال هنگام آپلود فایل:
Select File
|
v
Upload Started
|
v
Progress 0% -> 25% -> 50% -> 75% -> 100%
|
v
Upload Completed
|
v
Success Toastاین الگو در بسیاری از برنامههای واقعی کاربرد دارد.
نکات Accessibility
هنگام استفاده از Alert باید نقش مناسب مشخص شود:
<div
class="alert alert-danger"
role="alert"
>
عملیات ناموفق بود.
</div>برای Toast نیز بسته به نوع پیام میتوان از aria-live مناسب استفاده کرد:
<div
class="toast"
role="alert"
aria-live="polite"
aria-atomic="true"
>
...
</div>برای Progress نیز استفاده از ویژگیهای زیر مهم است:
role="progressbar"
aria-valuenow="60"
aria-valuemin="0"
aria-valuemax="100"این اطلاعات به فناوریهای کمکی کمک میکنند وضعیت Progress را بهتر درک کنند.
Alert، Toast و Progress در طراحی Responsive
این کامپوننتها باید در موبایل نیز بهدرستی نمایش داده شوند.
برای Alert معمولاً Bootstrap به صورت پیشفرض رفتار مناسبی دارد.
برای Toast باید به محل قرارگیری توجه کنیم.
مثلاً:
<div class="toast-container position-fixed bottom-0 end-0 p-3">اگر Toast بسیار عریض باشد، ممکن است در موبایل فضای زیادی اشغال کند. بنابراین بهتر است محتوا کوتاه باشد.
برای Progress نیز بهتر است متن داخل آن خیلی طولانی نباشد:
<div class="progress">
<div class="progress-bar" style="width: 75%;">
75%
</div>
</div>اشتباهات رایج
استفاده از Alert برای همه پیامها
هر پیام کوتاهی نباید Alert باشد.
برای اعلانهای موقتی، Toast میتواند مناسبتر باشد.
استفاده از Toast برای خطاهای مهم
اگر کاربر باید حتماً یک خطای مهم را ببیند، پیام موقتی ممکن است انتخاب مناسبی نباشد.
نمایش Progress غیرواقعی
نباید یک Progress مصنوعی ایجاد کنیم که 90 درصد را نشان دهد در حالی که عملیات واقعی هنوز مقدار مشخصی ندارد.
فراموش کردن Accessibility
ویژگیهای ARIA و Roleها را در کامپوننتهای اطلاعرسانی و Progress جدی بگیرید.
استفاده بیش از حد از رنگ
رنگ باید به درک وضعیت کمک کند، نه اینکه تنها راه تشخیص وضعیت باشد.
تمرین عملی
یک صفحه مدیریت کاربر ایجاد کنید که شامل موارد زیر باشد:
فرم ویرایش کاربر
Alert برای نمایش خطا
Toast برای نمایش ذخیره موفق
Progress برای نمایش میزان تکمیل پروفایل
طراحی Responsive
استفاده از RTL
میزان تکمیل پروفایل را به صورت زیر نمایش دهید:
Profile Completion
[##############------] 70%تمرین پیشرفته
یک صفحه Upload طراحی کنید که مراحل زیر را داشته باشد:
Select File
|
v
Upload
|
v
Progress
|
v
Completedدر هنگام شروع:
Alert → Upload startedدر زمان آپلود:
Progress → 0% ... 100%پس از موفقیت:
Toast → Upload completedدر صورت خطا:
Alert → Upload failedهمچنین صفحه باید در موبایل، تبلت و دسکتاپ بهدرستی نمایش داده شود.
جمعبندی
در این مقاله با سه کامپوننت مهم Bootstrap آشنا شدیم. Alert برای نمایش پیامهایی مانند موفقیت، خطا، هشدار و اطلاعرسانی در جریان محتوای صفحه استفاده میشود و میتواند ساده یا قابل بسته شدن باشد. Toast برای نمایش اعلانهای کوتاه و موقتی بسیار مناسب است و میتوان آن را با JavaScript ایجاد، نمایش و کنترل کرد. همچنین با Progress Bar یاد گرفتیم چگونه میزان پیشرفت عملیاتهایی مانند آپلود فایل، تکمیل پروفایل یا مراحل ثبتنام را نمایش دهیم. در ادامه این کامپوننتها را با Form، Card، Grid، Flexbox و JavaScript ترکیب کردیم تا به ساختارهایی نزدیک به پروژههای واقعی برسیم. در پروژههای حرفهای، انتخاب صحیح بین Alert، Toast و Progress اهمیت زیادی دارد؛ زیرا هرکدام برای نوع متفاوتی از اطلاعات و تعامل کاربر طراحی شدهاند.
نظرات
هنوز نظری ثبت نشده است.