النماذج
يرسل كل عنصر كما يرسل الحقل الأصلي.
عندما تعطي العنصر اسماً عبر name، يرسل ضمن FormData، وهي الصيغة التي يقرؤها النموذج العادي و<Form> في Inertia وإجراءات React Router وإجراءات الخادم. لا حاجة إلى ربط onChange ولا إلى حقول مخفية إضافية.
الإرسال الأصلي في DatePicker وDateRangePicker وTagInput وFileUpload وDropdown وRating، والدالة parseDateOnly، يتطلب @dev-dga/react 1.4.0 أو أحدث.
ما يرسله كل عنصر
القواعد مطابقة للحقول الأصلية: العنصر المعطل لا يرسل، وrequired يمنع الإرسال ما دام العنصر فارغاً، وإعادة تعيين النموذج ترجع القيمة الأولى.
| العنصر | يرسل | ملاحظات |
|---|---|---|
TextInput وTextarea وSearchBox | النص | حقل أصلي، وكل خصائص الحقل تمر إليه. |
NumberInput | رقم عشري بلا تنسيق، مثل "1234.5" | بلا فواصل آلاف، وبأرقام لاتينية دائماً. الفارغ يرسل "". |
Select | القيمة المختارة | الفارغ يرسل "". |
Dropdown | القيمة المختارة | مع multiple يرسل قيداً لكل قيمة بالاسم نفسه. الاختيار الواحد الفارغ يرسل "". |
Checkbox | قيمة value أو "on" | غير المحدد لا يرسل. أعط المجموعة اسماً واحداً واقرأها بـ getAll. |
RadioGroup | القيمة المختارة | لا يرسل شيء بلا اختيار. |
Switch | "on" | المطفأ لا يرسل. |
Slider | القيمة | يرسل النطاق name[] مرة لكل مقبض، ويضيف Radix القوسين. |
Rating | رقم نصي، مثل "4" أو "3.5" | بلا تقييم يرسل "0". |
TagInput | قيداً لكل وسم | لا يرسل شيء بلا وسوم، ولا يرسل النص المكتوب قبل اعتماده أبداً. |
InputOTP | الرمز المدخل | حقل أصلي تحت الخانات. |
DatePicker | تاريخ ميلادي YYYY-MM-DD | حتى عند عرض الهجري. الفارغ يرسل "". |
DateRangePicker | تاريخ ميلادي YYYY-MM-DD باسمي startName وendName | يرسل كل طرف وحده. |
FileUpload | كل ملف في القائمة (multipart) | الحقل الأصلي يعكس files، بما فيها الملفات المسحوبة. إعادة التعيين تترك files لك. |
ContentSwitcher وToggle | لا شيء | هذه مبدلات للعرض فقط. للاختيار داخل نموذج استخدم RadioGroup أو Checkbox. |
القيم المتعددة
يرسل TagInput وDropdown مع multiple ومجموعات Checkbox قيداً واحداً في FormData لكل قيمة، بالاسم الذي تمرره كما هو، مثل <select multiple> الأصلي. اقرأها بـ formData.getAll(name). لا تبني PHP وLaravel مصفوفة إلا من أسماء تنتهي بـ []، لذا مرر name="tags[]" هناك.
النماذج العادية
ضع العناصر داخل <form> واقرأ FormData في معالج الإرسال. هذا هو العقد الذي تقوم عليه كل التكاملات التالية.
<Form> في Inertia
تبني Inertia بياناتها من new FormData(form)، لذا لا تحتاج العناصر المسماة إلى ربط إضافي. وتمرر أخطاؤها مباشرة إلى خاصيتي error وerrorMessage في كل عنصر.
تطلق الدالة reset() الكاملة حدث reset الذي تستمع إليه العناصر، بينما لا تطلق إعادة تعيين حقول بعينها، مثل resetOnSuccess={["name"]}، أي حدث. لذا تحتفظ العناصر التي تدير حالتها بنفسها (منتقيا التاريخ وTagInput وDropdown وRating وNumberInput وInputOTP) بقيمتها الحالية. أعد تعيين النموذج كله، أو تحكم في هذه الحقول بنفسك.
إجراءات React Router
يرسل <Form> في React Router بيانات FormData نفسها إلى إجراء المسار. اقرأها بـ request.formData() وأعد أخطاء التحقق من الإجراء.
إجراءات الخادم
مرر إجراء الخادم إلى خاصية action في النموذج. ترجع useActionState نتيجة الإجراء، مما يعيد أخطاء الحقول من الخادم إلى العناصر.
النماذج داخل Modal
تقبل ModalContent الخاصيتين title وfooter، مما يضع زر الإرسال في التذييل خارج <form>. تحفظ ثلاث قواعد عمل هذا الترتيب:
- أعط النموذج معرف id، وأعط زر التذييل form={formId}. يرسل الزر ذلك النموذج، ويرسله مفتاح Enter من أي حقل عبر الزر نفسه.
- مرر حالة الانتظار إلى خاصية loading في الزر. الزر في حالة التحميل معطل، مما يمنع إرسال النموذج مرتين بنقرة ثانية أو بمفتاح Enter.
- اعرض خطأ الخادم الذي لا يخص حقلاً بعينه في InlineAlert فوق الحقول، واعرض خطأ كل حقل على حقله.
<Form> في Inertia
إجراء الخادم
تبقى حالة الانتظار خارج النموذج لأن الزر خارجه. أغلق Modal عند النجاح: تستدعي Inertia الدالة onSuccess فقط حين يعود الخادم دون أخطاء. تتطلب الخصائص title، description، وfooter الإصدار 1.6.0 أو أحدث من @dev-dga/react.
أخطاء التحقق من الخادم
يقبل كل حقل error (حالة الخطأ) وerrorMessage (النص تحت الحقل). ويضبطان معاً aria-invalid ويربطان aria-describedby بالرسالة، مما يجعل قارئات الشاشة تقرأ رسالة الخادم مع الحقل.
اضبط error وerrorMessage معاً. تبقى الرسالة دون error مخفية، بينما يعلّم error وحده الحقل دون أن يخبر المستخدم بالسبب.
التواريخ القادمة من الخادم
يرسل الخادم التواريخ نصوصاً بصيغة YYYY-MM-DD. حولها بـ parseDateOnly التي تبني Date عند منتصف الليل بالتوقيت المحلي وتطلق RangeError لأي صيغة أخرى. في المقابل، تقرأ new Date("2026-10-20") النص بتوقيت UTC، مما يظهر 19 أكتوبر في أي منطقة غرب UTC.