web-dev-qa-db-fra.com

Effacer les champs du formulaire après AJAX soumettre

Donné:

  • J'utilise Drupal 8.
  • J'ai un "formulaire d'ajout" personnalisé du type d'entité personnalisé.
  • Le formulaire contient une soumission ajax.

Problème:

  • Lorsque je soumets un formulaire, toutes les valeurs restent dans les champs.

Attendu:

  • Les champs du formulaire doivent être effacés après la soumission.

Code source du formulaire:

<?php

namespace Drupal\mymodule\Form;

use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Form\FormStateInterface;

/**
 * Form controller for the add/edit entity forms.
 */
class MymoduleForm extends ContentEntityForm {

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildForm($form, $form_state);

    $form['#prefix'] = "<div id=\"{$this->getFormId()}-wrapper\">";
    $form['#suffix'] = '</div>';

    $form['actions']['submit']['#ajax'] = [
      'wrapper' => $this->getFormId() . '-wrapper',
      'callback' => array($this, 'ajaxRebuildCallback'),
      'effect' => 'fade',
    ];

    return $form;
  }

  /**
   * Callback for ajax form submission.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   *
   * @return array
   *   The rebuilt form.
   */
  public function ajaxRebuildCallback(array $form, FormStateInterface $form_state) {
    drupal_set_message(t('Entity was successfully created'));

    // @todo Clear form values.
    //$form_state->setRebuild(TRUE);
    //$form_state->setValues([]);
    /*$entity = \Drupal::entityTypeManager()->getStorage('liveblog_post')->create([]);
    $form_object = \Drupal::entityTypeManager()
      ->getFormObject('liveblog_post', 'add')
      ->setEntity($entity);*/
    //$new_form_state = new FormState();
    //$form = \Drupal::formBuilder()->rebuildForm($this->getFormId(), $form_state);

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $form_state) {
    $entity = $this->getEntity();
    $entity->save();
  }

}

P.S. vous pouvez trouver mes tentatives dans la méthode ajaxRebuildCallback().

7
milkovsky

@ La réponse de Berdir m'a aidé à trouver la solution. Nous devons en effet effacer l'entrée utilisateur, mais nous ne pouvons pas simplement dire $form_state->setUserInput([]), car il existe des valeurs système qui doivent rester (par exemple form_id, form_token, _triggering_element_name, Etc.).

J'ai créé un méthode personnalisée pour cela:

  /**
   * Clears form input.
   *
   * @param array $form
   *   The form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  protected function clearFormInput(array $form, FormStateInterface $form_state) {
    // Replace the form entity with an empty instance.
    $this->entity = $this->entityTypeManager->getStorage('my_entity_type')->create([]);
    // Clear user input.
    $input = $form_state->getUserInput();
    // We should not clear the system items from the user input.
    $clean_keys = $form_state->getCleanValueKeys();
    $clean_keys[] = 'ajax_page_state';
    foreach ($input as $key => $item) {
      if (!in_array($key, $clean_keys) && substr($key, 0, 1) !== '_') {
        unset($input[$key]);
      }
    }
    $form_state->setUserInput($input);
    // Rebuild the form state values.
    $form_state->setRebuild();
    $form_state->setStorage([]);
  }

J'appelle $this->clearFormInput($form, $form_state); dans la méthode MymoduleForm::save() (la toute dernière étape de la soumission).

8
milkovsky

Vous recherchez https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Form%21FormStateInterface.php/function/FormStateInterface%3A%3AsetUserInput/8.2.x .

Les valeurs sont l'entrée validée, pour définir les valeurs par défaut, le système de formulaire respecte l'entrée utilisateur d'origine, que vous pouvez modifier avec la méthode ci-dessus.

Cependant, pour les formulaires d'entité, c'est un peu plus compliqué. $ this-> entity est une référence à l'entité, vous l'avez toujours et elle y reviendra. Ce que vous devez probablement faire est de créer une nouvelle entité dans save, l'assigner à $ this-> entity, puis vider l'entrée utilisateur et $ form_state-> setRebuild (). Cela devrait ensuite reconstruire le formulaire avec une entité nouvelle et vide.

8
Berdir