
تنفيذ تحديثات الحقول AJAX في Drupal 8
يوضح هذا الدليل كيفية إنشاء نموذج في Drupal 8 حيث يتم تحديث حقل آخر تلقائيًا عند تحديد قيمة في حقل باستخدام AJAX.
الخطوة 1: إنشاء وحدة مخصصة
أولاً، قم بإنشاء وحدة مخصصة جديدة. دعنا نسميها `custom_ajax_form`.
### custom_ajax_form.info.yml
name: Custom Ajax Form
type: module
description: 'يوفر نموذجًا مع تحديثات الحقل AJAX.'
core: 8.x
package: Custom
الخطوة 2: إنشاء فئة النموذج
قم بإنشاء فئة نموذج جديدة في `src/Form/DynamicFieldForm.php`:
<?php
namespace Drupal\custom_ajax_form\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
class DynamicFieldForm extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'dynamic_field_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['primary_field'] = [
'#type' => 'select',
'#title' => $this->t('اختر خيارًا'),
'#options' => [
'' => $this->t('- اختر -'),
'1' => $this->t('الخيار 1'),
'2' => $this->t('الخيار 2'),
'3' => $this->t('الخيار 3'),
],
'#ajax' => [
'callback' => '::updateSecondaryField',
'wrapper' => 'secondary-field-wrapper',
'event' => 'change',
],
];
$form['secondary_field_wrapper'] = [
'#type' => 'container',
'#attributes' => ['id' => 'secondary-field-wrapper'],
];
$form['secondary_field_wrapper']['secondary_field'] = [
'#type' => 'textfield',
'#title' => $this->t('المحتوى الديناميكي'),
'#readonly' => TRUE,
'#value' => $this->getSecondaryFieldValue($form_state),
];
$form['submit'] = [
'#type' => 'submit',
'#value' => $this->t('إرسال'),
];
return $form;
}
/**
* الرد الأجاكس لتحديث الحقل الثانوي.
*/
public function updateSecondaryField(array &$form, FormStateInterface $form_state) {
return $form['secondary_field_wrapper'];
}
/**
* دالة مساعدة للحصول على قيمة الحقل الثانوي.
*/
protected function getSecondaryFieldValue(FormStateInterface $form_state) {
$trigger = $form_state->getTriggeringElement();
$value = '';
if ($trigger) {
$selected_value = $form_state->getValue('primary_field');
// في تطبيق حقيقي، يمكن أن يكون هذا جلب البيانات من خدمة أو قاعدة بيانات
$values_map = [
'1' => 'المحتوى للخيار 1',
'2' => 'المحتوى للخيار 2',
'3' => 'المحتوى للخيار 3',
];
$value = isset($values_map[$selected_value]) ? $values_map[$selected_value] : '';
}
return $value;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
\Drupal::messenger()->addMessage($this->t('تم إرسال النموذج بنجاح.'));
}
}
الخطوة 3: إنشاء مسار
أنشئ `custom_ajax_form.routing.yml`:
custom_ajax_form.dynamic_form:
path: '/custom-ajax-form'
defaults:
_form: '\Drupal\custom_ajax_form\Form\DynamicFieldForm'
_title: 'نموذج AJAX الديناميكي'
requirements:
_permission: 'access content'
الخطوة 4 (اختياري): إضافة رابط للقائمة
أنشئ `custom_ajax_form.links.menu.yml`:
custom_ajax_form.dynamic_form:
title: 'نموذج AJAX الديناميكي'
route_name: custom_ajax_form.dynamic_form
menu_name: main
التنفيذ المتقدم مع الإشارة إلى الكيان
هنا كيفية تعديل النموذج للعمل مع حقول الإشارة إلى الكيان:
protected function getSecondaryFieldValue(FormStateInterface $form_state) {
$trigger = $form_state->getTriggeringElement();
$value = '';
if ($trigger) {
$entity_id = $form_state->getValue('primary_field');
// تحميل الكيان المشار إليه
if ($entity_id && $entity = \Drupal::entityTypeManager()->getStorage('node')->load($entity_id)) {
// الحصول على قيمة حقل معين من الكيان المشار إليه
$value = $entity->get('field_example')->value;
}
}
return $value;
}
الاستخدام مع Views و Entity Reference
للتكامل مع Views وحقول الإشارة إلى الكيان:
1. إنشاء View يعيد الكيانات التي ترغب في الإشارة إليها
2. قم بتعديل النموذج لاستخدام نتائج العرض:
protected function getPrimaryFieldOptions() {
$options = ['' => $this->t('- اختر -')];
// تحميل نتائج العرض
$view = Views::getView('your_view_name');
if ($view) {
$view->execute();
foreach ($view->result as $row) {
$entity = $row->_entity;
$options[$entity->id()] = $entity->label();
}
}
return $options;
}
public function buildForm(array $form, FormStateInterface $form_state) {
$form['primary_field']['#options'] = $this->getPrimaryFieldOptions();
// ... باقي بناء النموذج
}
الاعتبارات الأدائية
1. أضف بيانات التخزين المؤقتة إلى نموذجك:
public function buildForm(array $form, FormStateInterface $form_state) {
$form['#cache'] = [
'contexts' => ['user.permissions'],
'tags' => ['node_list'], // أضف العلامات المناسبة للتخزين المؤقت
];
// ... باقي بناء النموذج
}
2. استخدم العلامات المناسبة للتخزين المؤقت في الرد الأجاكس:
public function updateSecondaryField(array &$form, FormStateInterface $form_state) {
$response = new AjaxResponse();
$response->addCommand(new ReplaceCommand(
'#secondary-field-wrapper',
$form['secondary_field_wrapper']
));
// أضف بيانات التخزين المؤقت
$response->getCacheableMetadata()->addCacheTags(['node_list']);
return $response;
}
معالجة الأخطاء
أضف معالجة الأخطاء المناسبة إلى الرد الأجاكس:
public function updateSecondaryField(array &$form, FormStateInterface $form_state) {
try {
return $form['secondary_field_wrapper'];
}
catch (\Exception $e) {
watchdog_exception('custom_ajax_form', $e);
$response = new AjaxResponse();
$response->addCommand(new ReplaceCommand(
'#secondary-field-wrapper',
'<div class="messages messages--error">' . $this->t('حدث خطأ. الرجاء المحاولة مرة أخرى.') . '</div>'
));
return $response;
}
}
هذا التنفيذ يوفر أساسًا صلبًا لتحديثات الحقل المستندة إلى AJAX في Drupal 8، مع معالجة الأخطاء المناسبة، والتخزين المؤقت، وخيارات التوسعة.