it-swarm.com.de

Wie schließe ich modal nach dem Absenden des Formulars?

Ich erstelle ein Entitätsreferenz-Widget, das neben dem Eingabefeld den Referenzlink zum Bearbeitungsformular der Zielentität anzeigt. Ich mache es in einem Modal mit den folgenden Attributen auf dem Link zu öffnen:

 'class' => ['use-ajax'],
          'data-dialog-type' => 'modal',
          'data-dialog-options' => json_encode([
            'height' => 700,
            'width' => 900,
          ]),

Das funktioniert perfekt. Wenn ich jedoch im modalen Formular auf "Senden" klicke, werde ich zur Seite mit der referenzierten Entitätsansicht weitergeleitet, anstatt dass das Modal geschlossen wird und ich auf dem ursprünglichen Formular bleibe, in dem dieses Widget verwendet wird.

Gibt es spezielle Attribute (wie "Datendialogtyp"), die der Senden-Schaltfläche des Modalformulars mitteilen, dass das Modal geschlossen werden soll, anstatt zur ursprünglichen Ansicht umzuleiten?

[~ # ~] update [~ # ~]

Das Hinzufügen zur URL löst das Problem so ziemlich:

    'query' => [
      'destination' => $this->requestStack->getCurrentRequest()->getRequestUri(),
    ],

Dadurch wird die Seite auf die Originalseite umgeleitet, wobei die potenziellen Werte aktualisiert werden (Titel des referenzierten Elements), was eigentlich eine ziemlich gute Sache ist!

Trotzdem interessiere ich mich immer noch für die "Ajax Submit" -Version!

3
ssibal

Sie müssen Ihr eigenes EntityEditForm implementieren und verwenden - ist dies der Fall? Fahren Sie dann mit dem letzten Codeblock fort: D.

Andernfalls müssen Sie dies zuerst ausführen. In dieser Antwort ( Überschreiben eines Formulars zum Hinzufügen/Bearbeiten einer Entität durch alterroute ) finden Sie einen Ansatz zum "Einfügen" eines benutzerdefinierten Formulars. Hier der entscheidende Code dazu (angepasst an NodeForm):

modules/custom/form_overwrite/form_overwrite.services.yml

services:
    route_subscriber:
        class: Drupal\form_overwrite\Routing\RouteSubscriber
        tags: 
 - {name: event_subscriber }

modules/custom/form_overwrite/src/Routing/RouteSubscriber.php

 <?php

/**
 * @file
 * Contains \Drupal\form_overwrite\Routing\RouteSubscriber.
 */

namespace Drupal\form_overwrite\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Listens to the dynamic route events.
 */
class RouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
     if ($route = $collection->get('entity.node.edit_form')) {
  $route->setDefault('_entity_form', '\Drupal\form_overwrite\Form\NewEditForm');
     }

   }
}

modules/custom/form_overwrite/src/Form/NewEditForm.php

<?php

namespace Drupal\form_overwrite\Form;

use Drupal\node\NodeForm;


/**
 * Form handler for the node edit forms.
 */
class NewEditForm extends NodeForm {}

Dort stellen Sie sicher, dass das #ajax eingestellt ist, wie:

<?php

public function form(array $form, FormStateInterface $form_state) {
   ...
   $form['actions']['DESIRED_EXISTING_ACTION'] = array(
      ...
      '#type' => 'submit',
      '#ajax' => array(
        'callback' => '::ajaxSubmit',
        'event' => 'click',
      ),
      ...
    );
   ...
}

und überschreiben Sie die Funktion ajaxSubmit, indem Sie CloseModalDialogCommand hinzufügen, wie:

public function ajaxSubmit(array &$form, FormStateInterface $form_state) {
    $response = new AjaxResponse();

    if ($form_state->getErrors()) {
      ...
    }
    else {
      ...
      $response->addCommand(new \Drupal\Core\Ajax\CloseModalDialogCommand\CloseModalDialogCommand());
    }

    return $response;
  }
4
rémy

Ich habe dies gelöst, indem ich nur einen Ereignisabonnenten in einem benutzerdefinierten Modul verwendet habe.

modalCloseSubscriber.php

<?php

namespace Drupal\custom_module\EventSubscriber;

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CloseDialogCommand;
use Drupal\Core\Session\AccountProxyInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
 * Custom module event subscriber.
 */
class ModalCloseSubscriber implements EventSubscriberInterface {

  /**
   * Current logged in user.
   *
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
  protected $currentUser;

  /**
   * Constructs event subscriber.
   *
   * @param \Drupal\Core\Session\AccountProxyInterface $current_user
   *   Current logged in user.
   */
  public function __construct(AccountProxyInterface $current_user) {
    $this->currentUser = $current_user;
  }

  /**
   * Kernel response event handler.
   *
   * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
   *   Response event.
   */
  public function onKernelResponse(FilterResponseEvent $event) {
    $response = $event->getResponse();
    if (!$response instanceof AjaxResponse) {
      return;
    }
    if ($response->getCommands()) {
      $commands = $response->getCommands();
      if (empty($commands)) {
        return;
      }
      elseif (!empty($commands)) {
        foreach ($commands as $command) {
          if ($command['command'] == 'insert' && $command['selector'] == '#layout-builder') {
            // leave blank for default modal window to close.
            $response->addCommand(new CloseDialogCommand());
          }
        }
      }
    }

  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    return [
      KernelEvents::RESPONSE => ['onKernelResponse'],
    ];
  }

}

Dies schließt das Modal, nachdem ich einen Block mit Layout Builder erstellt habe.

2
Kllrthr