it-swarm.com.de

Ändern Sie ein vorhandenes Formular

Wir haben gerade mit Drupal 8) angefangen und sind sehr schnell auf unser erstes Problem gestoßen.

Wie soll ich ein vorhandenes Formular in Drupal 8) ändern?

Wir müssen die Speichermethode für das Knotenformular ändern, um eine Umleitung zu einer anderen Seite durchzuführen. Wir möchten die Knotenform so ändern, dass sie zu einer mehrstufigen Form wird. Nachdem der Benutzer neue Inhalte erstellt hat, wird er in ein neues Formular (das wir erstellt haben) umgeleitet, um weitere Informationen zu erhalten.

Wir haben unser Problem bei der Implementierung von hook_entity_type_alter() gelöst.

function mymodule_entity_type_alter(&$entity_info) {
  $handlers = $entity_info['node']->get('handlers');
  $handlers['form']['default'] =    'Drupal\mymodule\Form\MyExtendedNodeForm';
  $handlers['form']['edit'] = 'Drupal\mymodule\Form\MyExtendedNodeForm';
  $entity_info['node']->set('handlers', $handlers);
}

Anschließend haben wir eine neue Formularklasse erstellt, die das Knotenformular erweitert und die Speichermethode ändert.

class MyExtendedNodeForm extends NodeForm {

    public function save(array $form, FormStateInterface $form_state) {
      parent::save($form, $form_state);
      $node = $this->entity;
      $form_state->setRedirect('entity.regions.add_form', ['nid' => $node->id()]);
  }

}

Das funktioniert perfekt, aber ist es gut? Wenn ein anderes Modul dasselbe tut, wird unser Code nicht mehr ausgeführt.

12
Jens Steppe

Ich musste gestern genau das Gleiche tun und suche immer noch nach einem Drupal 8-Weg, um dies zu tun, habe ihn aber nicht gefunden. Am Ende habe ich es so gemacht:

<?php

/**
 * @file
 * This is my module.
 */

use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * Implements hook_form_alter().
 */
function MODULE_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'user_form') {
    $form['actions']['submit']['#submit'][] = '_MODULE_goto';
  }
}

/**
 * Make the form go to route.id.
 */
function _MODULE_goto($form, FormStateInterface $form_state) {
  $form_state->setRedirect('route.id');
}

Ich bin immer noch sehr daran interessiert, es anders zu machen, mein Modul sah ohne die .module-Datei so sauber aus :).

5
Dagomar

Ich verwende Drupal 8.1.1 und habe versucht, Benutzer umzuleiten, nachdem sie ihr Konto geändert haben, d. H. Auf die Schaltfläche Speichern auf der Seite/user/edit geklickt. Ich habe dies zunächst versucht:

/**
 * Implements hook_form_alter().
*/
function MODULE_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'user_form') {
    $form['#submit'][] = '_MODULE_goto';
  }
}

Während das für die user_login_form, es würde nicht funktionieren für user_form. Zum user_form Ich musste verwenden

$form['actions']['submit']['#submit'][] = '_MODULE_goto';

Ich hoffe, das hilft anderen, die über das gleiche Problem stolpern!

4
Eric C.

Nun, ich wollte das Formular site_information_settings Ändern, um einige Felder hinzuzufügen.

Als Sie hatte ich die Wahl zwischen

  • hook_form_alter (Oder hook_form_FORM_ID_alter)
  • erweitern Sie die ursprüngliche Formularklasse

Wollte einige OOP machen, also fing ich an, einen Routenabonnentendienst zu schreiben, der das Attribut system.site_information_settings Der Route _form Ändert.

Dann, in meiner neuen Klasse, die SiteInformationForm erweitert, nachdem die Felder und ihre Validatoren hinzugefügt und die Submit-Funktion erweitert wurden, fühlte ich mich genauso wie Sie ... Was nun, wenn ein anderes Modul das neu schreibt? auch die Route des Formulars, um eine eigene Klasse zu verwenden?

Zurück zum Anfang hatte ich die Wahl zwischen zwei Optionen ... anscheinend habe ich die falsche ausgewählt.

hook_form_alter/hook_form_FORM_ID_alter Scheint der beste Weg zu sein, ein vorhandenes Formular zu ändern.

2
MacSim

Sie können einen neuen EventSubscriber erstellen, der das Ereignis KernelEvents :: REQUEST abhört, und dann reagieren, wenn Sie ein Knotenformular senden, z. B. this

Auf jeden Fall funktioniert der hook_form_alter Weg ok.

0
ruloweb

Es sieht so aus, als ob Sie die Speichermethode nicht wirklich ändern möchten, sondern die Umleitung, wenn ein Knoten gespeichert wird.

In dieser Situation tun Sie ähnlich wie Drupal 7, hook_form_alter zusammen mit einem benutzerdefinierten Submit-Handler (auf dem Formular oder der Schaltfläche, je nach Formular und Anforderung) wäre eine gute Lösung.

Was Sie in der Frage beschreiben, funktioniert auch, aber ich würde vermeiden, die Basisklasse zu überschreiben, es sei denn, ich möchte tatsächlich etwas in der Klasse ändern.

Die Speichermethode wird sowieso nur als Submit-Handler verwendet. Es macht also wenig Sinn, sie nur zu überschreiben, um eine Umleitung hinzuzufügen.

0
googletorp

Ich denke, die bessere Methode ist es, immer noch einen der Hooks aus der form_alter-Familie zu verwenden, einen Submit-Handler anzuhängen und innerhalb dessen Ihre Weiterleitung festzulegen.

Die Erweiterung der Basisklassen dazu ist meiner Meinung nach haarig. Zumal sich keine Funktion ändert, sondern nur umleiten.

0
Kevin

Was ich bisher gefunden habe: Das Implementieren eines Formularänderungs-Hooks und der Versuch, die Validierungs-/Submit-Handler im Formularänderungs-Hook selbst zu ändern, funktioniert nur, wenn Sie die Handler $ form ['# validate]/$ form [#submit'] ändern. (Der Aufruf von form_state-Funktionen funktioniert im Formular alter hook selbst nicht.)

Wenn Sie dies jedoch in einem Validierungshandler versuchen, funktioniert dies in der Regel:

// Load form submit handlers.
$submit_handlers = $form_state->getSubmitHandlers();

// Drop the core entity submitForm function.
$key_core_submit = array_search('::submitForm', $submit_handlers);
if ($key_core_submit !== FALSE) {
  unset($submit_handlers[$key_core_submit]);
  // Add your own submit handler.
  array_unshift($submit_handlers, 'yourmodule_submit_handler');
}
// Update submit handlers.
$form_state->setSubmitHandlers($submit_handlers);

Dies liegt daran, dass das Formular jetzt vollständig erstellt wurde, was im Formular-Alter-Hook selbst nicht der Fall ist.

Die Idee ist: Sie können einen Validierungshandler als letzten hinzufügen, andere Handler auswerten, die für die Übermittlung vorhanden sind, und sie genau dort ändern.

Wenn Sie auch die Validierungshandler ändern möchten, stellen Sie sicher, dass Ihre Handler vor allen anderen ausgeführt werden, und ändern Sie die gewünschten Informationen im Validierungshandler.

Ich bin immer noch auf der Suche nach einem besseren Weg und muss nur immer die Validierungs-/Submit-Handler für das Benutzerregisterformular ersetzen. Es könnten aber auch andere Module existieren, die meine Modulimplementierung beschädigen. Mein Modul müsste also in der Lage sein, nach diesen zu suchen, und das ist auf diese Weise möglich. Ich frage mich, ob es eine Entitätsform nach der Build-Funktion gibt, um dies zu erreichen. (etwas, das ausgeführt wird, wenn das Formular ausgefüllt wurde und geliefert werden soll) (das ist für diesen einfachen Fall nicht zu komplex)

Das Umgehen der Umleitung der save () -Methode ist nicht möglich, das Deaktivieren von save () erfolgt jedoch auf diese Weise (+ implementieren Sie Ihre eigene). Eine Klasse ist zwar schöner und bietet einen einfacheren Zugriff auf Objekte/usw., aber das Überschreiben einer Kernklasse führt tatsächlich zu Problemen, wenn andere Module diese verwenden möchten. Dies ist nicht der Fall, wenn Sie diesen Code verwenden.

0
Rob C

Nachdem ich dieses Problem überprüft habe, habe ich Folgendes gefunden, das zu Ihrem Fall passen sollte:

/**
 * Implements hook_entity_type_alter().
 */
function mymodule_entity_type_alter(&$entity_info) {
 $entity_info['node']->setFormClass('edit','Drupal\mymodule\Form\CustomNodeForm');
}
0
Ioana Todea