Implementierung von AJAX-Feldaktualisierungen in Drupal 8
Dieser Leitfaden zeigt, wie man ein Formular in Drupal 8 erstellt, bei dem die Auswahl eines Wertes in einem Feld automatisch ein anderes Feld mit AJAX aktualisiert.
Schritt 1: Erstellen Sie ein benutzerdefiniertes Modul
Erstellen Sie zunächst ein neues benutzerdefiniertes Modul. Nennen wir es `custom_ajax_form`.
### custom_ajax_form.info.yml name: Custom Ajax Form type: module description: 'Bietet ein Formular mit AJAX-Feldaktualisierungen.' core: 8.x package: Custom
Schritt 2: Erstellen Sie die Formular-Klasse
Erstellen Sie eine neue Formular-Klasse in `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('Wählen Sie eine Option'), '#options' => [ '' => $this->t('- Auswählen -'), '1' => $this->t('Option 1'), '2' => $this->t('Option 2'), '3' => $this->t('Option 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('Dynamischer Inhalt'), '#readonly' => TRUE, '#value' => $this->getSecondaryFieldValue($form_state), ]; $form['submit'] = [ '#type' => 'submit', '#value' => $this->t('Absenden'), ]; return $form; } /** * Ajax-Callback zur Aktualisierung des sekundären Feldes. */ public function updateSecondaryField(array &$form, FormStateInterface $form_state) { return $form['secondary_field_wrapper']; } /** * Hilfsfunktion, um den Wert des sekundären Feldes zu erhalten. */ protected function getSecondaryFieldValue(FormStateInterface $form_state) { $trigger = $form_state->getTriggeringElement(); $value = ''; if ($trigger) { $selected_value = $form_state->getValue('primary_field');
// In einer echten Anwendung könnte dies Daten von einem Dienst oder einer Datenbank abrufen $values_map = [ '1' => 'Inhalt für Option 1', '2' => 'Inhalt für Option 2', '3' => 'Inhalt für Option 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('Formular erfolgreich abgesendet.')); } }
Schritt 3: Erstellen Sie eine Route
Erstellen Sie `custom_ajax_form.routing.yml`:
custom_ajax_form.dynamic_form: path: '/custom-ajax-form' defaults: _form: '\Drupal\custom_ajax_form\Form\DynamicFieldForm' _title: 'Dynamisches AJAX-Formular' requirements: _permission: 'access content'
Schritt 4 (Optional): Fügen Sie einen Menülink hinzu
Erstellen Sie `custom_ajax_form.links.menu.yml`:
custom_ajax_form.dynamic_form: title: 'Dynamisches AJAX-Formular' route_name: custom_ajax_form.dynamic_form menu_name: main
Erweiterte Implementierung mit Entity Reference
Hier ist, wie man das Formular modifiziert, um mit Entity-Reference-Feldern zu arbeiten:
protected function getSecondaryFieldValue(FormStateInterface $form_state) { $trigger = $form_state->getTriggeringElement(); $value = ''; if ($trigger) { $entity_id = $form_state->getValue('primary_field');
// Laden Sie die referenzierte Entität if ($entity_id && $entity = \Drupal::entityTypeManager()->getStorage('node')->load($entity_id)) { // Holen Sie sich einen spezifischen Feldwert von der referenzierten Entität $value = $entity->get('field_example')->value; } } return $value; }
Verwendung mit Views und Entity Reference
Um mit Views und Entity-Reference-Feldern zu integrieren:
1. Erstellen Sie eine Ansicht, die die Entitäten zurückgibt, auf die Sie verweisen möchten 2. Modifizieren Sie das Formular, um die Ergebnisse der Ansicht zu verwenden:
protected function getPrimaryFieldOptions() { $options = ['' => $this->t('- Auswählen -')];
// Laden Sie die Ergebnisse der Ansicht $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(); // ... Rest des Formularaufbaus }
Leistungsüberlegungen
1. Fügen Sie Ihrer Form Caching-Metadaten hinzu:
public function buildForm(array $form, FormStateInterface $form_state) { $form['#cache'] = [ 'contexts' => ['user.permissions'], 'tags' => ['node_list'], // Fügen Sie relevante Cache-Tags hinzu ];
// ... Rest des Formularaufbaus }
2. Verwenden Sie geeignete Cache-Tags in Ihrem AJAX-Callback:
public function updateSecondaryField(array &$form, FormStateInterface $form_state) { $response = new AjaxResponse(); $response->addCommand(new ReplaceCommand( '#secondary-field-wrapper', $form['secondary_field_wrapper'] ));
// Fügen Sie Cache-Metadaten hinzu $response->getCacheableMetadata()->addCacheTags(['node_list']);
return $response; }
Fehlerbehandlung
Fügen Sie Ihrer AJAX-Callback-Funktion eine ordnungsgemäße Fehlerbehandlung hinzu:
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('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.') . '</div>' )); return $response; } }
Diese Implementierung bietet eine solide Grundlage für AJAX-basierte Feldaktualisierungen in Drupal 8, mit ordnungsgemäßer Fehlerbehandlung, Caching und Erweiterungsoptionen.