Î N A P O I
Implementarea actualizărilor de câmp AJAX în Drupal 8

Implementarea actualizărilor de câmp AJAX în Drupal 8

Acest ghid demonstrează cum să creați un formular în Drupal 8 în care selectarea unei valori într-un câmp actualizează automat un alt câmp folosind AJAX.

Pasul 1: Crearea unui Modul Personalizat

În primul rând, creați un nou modul personalizat. Să-l numim `custom_ajax_form`.

### custom_ajax_form.info.yml name: Custom Ajax Form type: module description: 'Oferă un formular cu actualizări de câmp AJAX.' core: 8.x package: Custom

Pasul 2: Crearea Clasei Formularului

Creați o nouă clasă de formular în `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('Selectați o opțiune'), '#options' => [ '' => $this->t('- Selectați -'), '1' => $this->t('Opțiunea 1'), '2' => $this->t('Opțiunea 2'), '3' => $this->t('Opțiunea 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('Conținut dinamic'), '#readonly' => TRUE, '#value' => $this->getSecondaryFieldValue($form_state), ]; $form['submit'] = [ '#type' => 'submit', '#value' => $this->t('Trimite'), ]; return $form; } /** * Callback Ajax pentru a actualiza al doilea câmp. */ public function updateSecondaryField(array &$form, FormStateInterface $form_state) { return $form['secondary_field_wrapper']; } /** * Funcție auxiliară pentru a obține valoarea câmpului secundar. */ protected function getSecondaryFieldValue(FormStateInterface $form_state) { $trigger = $form_state->getTriggeringElement(); $value = ''; if ($trigger) { $selected_value = $form_state->getValue('primary_field');

// Într-o aplicație reală, acest lucru ar putea fi extragerea datelor dintr-un serviciu sau o bază de date $values_map = [ '1' => 'Conținut pentru Opțiunea 1', '2' => 'Conținut pentru Opțiunea 2', '3' => 'Conținut pentru Opțiunea 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('Formularul a fost trimis cu succes.')); } }

Pasul 3: Crearea unei Rute

Creați `custom_ajax_form.routing.yml`:

custom_ajax_form.dynamic_form: path: '/custom-ajax-form' defaults: _form: '\Drupal\custom_ajax_form\Form\DynamicFieldForm' _title: 'Formular AJAX Dinamic' requirements: _permission: 'access content'

Pasul 4 (Opțional): Adăugați un Link de Meniu

Creați `custom_ajax_form.links.menu.yml`:

custom_ajax_form.dynamic_form: title: 'Formular AJAX Dinamic' route_name: custom_ajax_form.dynamic_form menu_name: main

Implementare Avansată cu Referință Entitate

Iată cum să modificați formularul pentru a funcționa cu câmpuri de referință entitate:

protected function getSecondaryFieldValue(FormStateInterface $form_state) { $trigger = $form_state->getTriggeringElement(); $value = ''; if ($trigger) { $entity_id = $form_state->getValue('primary_field');

// Încărcați entitatea referențiată if ($entity_id && $entity = \Drupal::entityTypeManager()->getStorage('node')->load($entity_id)) { // Obțineți o valoare specifică a câmpului din entitatea referențiată $value = $entity->get('field_example')->value; } } return $value; }

Utilizare cu Vizualizări și Referință Entitate

Pentru a integra cu Vizualizări și câmpuri de referință entitate:

1. Creați o Vizualizare care returnează entitățile pe care doriți să le referiți 2. Modificați formularul pentru a utiliza rezultatele Vizualizării:

protected function getPrimaryFieldOptions() { $options = ['' => $this->t('- Selectați -')];

// Încărcați rezultatele vizualizării $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(); // ... restul construirii formularului }

Considerații privind Performanța

1. Adăugați metadate de cache formularului dvs.:

public function buildForm(array $form, FormStateInterface $form_state) { $form['#cache'] = [ 'contexts' => ['user.permissions'], 'tags' => ['node_list'], // Adăugați tag-uri de cache relevante ];

// ... restul construirii formularului }

2. Utilizați tag-uri de cache adecvate în callback-ul dvs. AJAX:

public function updateSecondaryField(array &$form, FormStateInterface $form_state) { $response = new AjaxResponse(); $response->addCommand(new ReplaceCommand( '#secondary-field-wrapper', $form['secondary_field_wrapper'] ));

// Adăugați metadate de cache $response->getCacheableMetadata()->addCacheTags(['node_list']);

return $response; }

Manipularea Erorilor

Adăugați manipularea corespunzătoare a erorilor la callback-ul dvs. AJAX:

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('A apărut o eroare. Încercați din nou.') . '</div>' )); return $response; } }

Această implementare oferă o bază solidă pentru actualizările de câmp bazate pe AJAX în Drupal 8, cu manipularea corespunzătoare a erorilor, cache și opțiuni de extensibilitate.