Donné:
Problème:
Attendu:
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()
.
@ 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).
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.