Item Collector
کامپوننت x-item-collector برای جمعآوری و مدیریت آیتمها در فرمها استفاده میشود. این کامپوننت امکان افزودن، ویرایش و حذف آیتمها را به صورت داینامیک فراهم میکند و کنترل کاملی روی ظاهر و رفتار آیتمها دارد.
ویژگیها
- افزودن و مدیریت داینامیک آیتمها
- تعیین حداکثر تعداد آیتمها (
max) - امکان غیرفعالسازی ویرایش یا حذف آیتمها (
editable,clearable) - پشتیبانی از مقدار اولیه (
values) - شخصیسازی کلاس کانتینر و آیتمها (
containerClass,itemsClass) - تعیین جهت نمایش آیتمها (
itemsOrientation) - امکان تعیین عنوان برای بخش آیتمها (
itemsTitle) - شخصیسازی متن دکمه افزودن (
buttonText)
ورودیهای کامپوننت
x-item-collector
| نام پراپ | نوع داده | مقدار پیشفرض | توضیحات |
|---|---|---|---|
name | string | — | نام فیلد (اجباری) |
id | string | null | شناسه یکتا برای کامپوننت |
containerClass | string | null | کلاس CSS سفارشی برای کانتینر اصلی |
gridClass | string | null | کلاس CSS سفارشی برای چیدمان فیلدها |
itemsClass | string | null | کلاس CSS سفارشی برای بخش آیتمها |
itemsOrientation | string | "horizontal" | جهت نمایش عنوان آیتمها (vertical یا horizontal) |
itemsTitle | string | null | عنوان نمایش داده شده برای بخش آیتمها |
itemsTitleSelector | string | null | سلکتور CSS برای انتخاب عنصر عنوان آیتمها |
itemsLayout | string | "grid" | نوع چیدمان آیتمها (grid یا flow) |
disabled | bool | false | غیرفعالسازی کامپوننت |
max | int | null | حداکثر تعداد آیتمهای قا بل افزودن |
buttonText | string | "افزودن" | متن دکمه افزودن آیتم |
values | array | null | آرایه مقادیر اولیه برای آیتمها |
clearable | bool | true | امکان حذف آیتمها |
editable | bool | true | امکان ویرایش آیتمها |
suppressLogicMessages | bool | false | غیرفعالسازی پیامهای منطقی |
useDeleteAction | bool | false | فعالسازی اکشن سفارشی حذف آیتمها از طریق callback |
-
برای تنظیم تعداد ستونها در اندازههای مختلف صفحه، از کلاسهای بوت استرپی
row-cols-sm-*یاrow-cols-md-*یاrow-cols-lg-*یا غیره در itemsClass استفاده نمایید. -
برای جلوگیری از درج مقادیر تکراری برای هر فیلد آیتم کالکتور، کافی است که اتریبیوت
data-prevent-duplicatesرا به کامپوننت مورد نظر اضافه کنید -
پراپرتی
itemsLayoutدر حالتgrid، آیتمها را به صورت ساختارمند و منظم نمایش میدهد و در حالتflow، عناصر به صورت متوالی و با فاصله مناسب کنار هم قرار میگیرند.
ولیدیشن در item-collector نیازمند توجه ویژه است:
-
اگر میخواهید مطمئن شوید که حتماً آیتمی در کامپوننت وارد شده باشد، باید از ولیدیشن
requiredبرای نام اصلی مانندitem-collector-nameاستفاده کنید. -
فیلدهای داخلی آیتم کالکتور (مثل x) قوانین خاص خود را دارند. هنگام درج آیتم، با توجه به مقادیر این فیلدها تعدادی اینپوت هیدن به صورت اندیسی به کامپوننت اضافه میشود و تا زمانی که آیتمی اضافه نشده باشد، این فیلدها اصلاً وجود ندارند. بنابراین ولیدیشن مستقیم روی آنها (مانند
item-collector-name.*.x) فقط زمانی اجرا میشود که آیتم اضافه شده باشد. -
اگر میخواهید هنگام درج آیتم جدید، فیلدی اعتبارسنجی شود، باید ولیدیشن را روی همان فیلد اصلی (مثل x) قرار دهید، نه روی
item-collector-name.*.x. با این حال، برای این فیلد یک نکته مهم وجود دارد: در صورتی که فیلد x را به صورت «required» تعریف کنید، حتی بعد از درج آیتم نیز فرم قابل ارسال نیست (زیرا فیلد x خالی میماند). این موضوع از سمت زیرساخت مدیریت شده است؛ کافی است پراپrequiredرا به فیلد مورد نظر بدهید تا به درستی کنترل شود. -
سایر ولیدیشنها (مانند قواعد max، numeric و...) را میتوانید از طریق ruleها روی فیلدها تنظیم کنید.
-
اگر میخواهید مقدار تکراری درج نشود، کافی است برای آن فیلد data-prevent-duplicates را اضافه کنید.
برای مقداردهی جاوااسکریپتی میتوانید به صورت زیر عمل کنید
const instance = $("#item-collector-sample").data("instance");
instance.setValues([
{
specialty: {
text: "رشته تخصصی",
value: "حساب",
},
credit_coefficient: {
text: "ضریب اعتبار",
value: "12",
},
created_at: {
text: "تاریخ ایجاد",
value: "1404/06/18",
},
province: {
text: "استان",
value: [
{
label: "تهران",
value: "1",
},
],
},
"cities[]": {
text: "شهر",
value: [
{
label: "ساری",
value: "1",
},
{
label: "شیراز",
value: "2",
},
],
},
},
]);
مثالها
نمونه پایه
$data = [
[
'specialty' => [
'text' => 'رشته تخصصی',
'value' => 'حساب',
],
'credit_coefficient' => [
'text' => 'ضریب اعتبار',
'value' => '12',
],
'created_at' => [
'text' => 'تاریخ ایجاد',
'value' => '1404/06/18',
],
'province' => [
'text' => 'استان',
'value' => [
[
'label' => 'تهران',
'value' => '1',
],
],
],
'cities[]' => [
'text' => 'شهر',
'value' => [
[
'label' => 'ساری',
'value' => '1',
],
[
'label' => 'شیراز',
'value' => '2',
],
],
],
],
];
<x-item-collector name="item-collector" :values="$data">
<x-text-input name="specialty" label="رشته تخصصی" />
<x-number-input name="credit_coefficient" label="ضریب اعتبار" required show-separator />
<x-datetime-picker name="created_at" label="تاریخ ایجاد" required />
<x-select
name="province"
label="استان"
:items="[
['id' => '1', 'name' => 'تهران', 'value' => '1'],
['id' => '2', 'name' => 'اصفهان', 'value' => '2'],
['id' => '3', 'name' => 'گلستان', 'value' => '3'],
['id' => '4', 'name' => 'مازندران', 'value' => '4'],
['id' => '5', 'name' => 'فارس', 'value' => '5'],
['id' => '6', 'name' => 'خراسان رضوی', 'value' => '6'],
]"
/>
<x-multi-select
name="cities"
label="شهر"
:items="[
['id' => '1', 'name' => 'ساری', 'value' => '1'],
['id' => '2', 'name' => 'شیراز', 'value' => '2'],
['id' => '3', 'name' => 'بابل', 'value' => '3'],
['id' => '4', 'name' => 'مشهد', 'value' => '4'],
['id' => '5', 'name' => 'اصفهان', 'value' => '5'],
['id' => '6', 'name' => 'کرج', 'value' => '6'],
['id' => '7', 'name' => 'گرگان', 'value' => '7'],
['id' => '8', 'name' => 'تهران', 'value' => '8'],
]"
/>
</x-item-collector>
<x-item-collector name="item-collector-simple" items-title="قسط" :editable="false" :max="2">
<x-number-input name="payment-amount" label="مبلغ قسط" show-separator suffix="ریال" />
<x-datetime-picker name="payment-date" label="تاریخ قسط" />
</x-item-collector>
<x-item-collector
name="item-collector-row"
items-layout="flow"
grid-class="d-md-flex"
items-orientation="vertical"
items-title-selector="#item-collector-select"
>
<x-text-input containerClass="flex-fill" required name="field-1" label="برنامهها" />
<x-select
id="item-collector-select"
containerClass="flex-fill"
required
name="field-2"
label="دستگاه مجری"
:items="[
['id' => '1', 'name' => 'تهران', 'value' => '1'],
['id' => '2', 'name' => 'اصفهان', 'value' => '2'],
['id' => '3', 'name' => 'گلستان', 'value' => '3'],
['id' => '4', 'name' => 'مازندران', 'value' => '4'],
['id' => '5', 'name' => 'فارس', 'value' => '5'],
['id' => '6', 'name' => 'خراسان رضوی', 'value' => '6'],
]"
/>
<x-text-input containerClass="flex-fill" required name="field-3" label="اولویت" />
</x-item-collector>
Item Collector Delete Action
معرفی
در ItemCollectorBaseController قابلیتی به نام delete action وجود دارد که اجازه میدهد قبل از حذف یک آیتم، یک منطق سفارشی اجرا شود.
با استفاده از این قابلیت میتوان قبل از حذف:
- پیام تایید نمایش داد.
- شرایط حذف را بررسی کرد.
- درخواست حذف به سرور ارسال کرد.
- در صورت نیاز از حذف آیتم جلوگیری کرد.
در صورت فعال بودن این قابلیت، ابتدا callback مربوط به delete اجرا میشود و نتیجه آن مشخص میکند که آیتم حذف شود یا خیر.
نحوه استفاده
برای تعریف رفتار حذف باید از متد onAction استفاده شود:
instance.onAction("delete", async () => {
return true;
});
نکته مهم:
Callback مربوط به delete باید حتماً یک Promise برگرداند تا کنترلر بتواند منتظر نتیجه عملیات بماند.
بنابراین callback باید به صورت async تعریف شود یا یک Promise را return کند.
مثال تایید حذف
instance.onAction("delete", async () => {
const alert = await showConfirmationMessage({
type: "danger",
title: "تایید حذف",
text: "آیا از حذف این آیتم مطمئن هستید؟"
});
return alert.isConfirmed;
});
instance.onAction("delete", () => {
return new Promise(async (resolve) => {
try {
const response = await fetch("/api/delete-item", {
method: "DELETE"
});
resolve(response.ok);
} catch (error) {
resolve(false);
}
});
});
در این مثال:
- اگر کاربر تایید کند → Promise مقدار
trueبرمیگرداند و آیتم حذف میشود. - اگر کاربر لغو کند → Promise مقدار
falseبرمیگرداند و آیتم حذف نمیشود.