web-dev-qa-db-fra.com

Formulaire personnalisé utilisant un modèle personnalisé, soumettez le formulaire n'appelez pas ses gestionnaires de validation et de soumission

J'ai créé un module personnalisé simple où j'ai créé un formulaire de classe à l'aide d'un formulaire de modèle personnalisé. Si je n'utilise pas mon modèle personnalisé (je commente mon hook _theme de mon .module), lorsque je soumets mon formulaire, les gestionnaires de méthodes de classe valident et soumettent sont appelés. Mais lorsque j'utilise mon modèle de formulaire personnalisé, si je soumets mon formulaire, valide et soumets des gestionnaires de méthodes de classe ne sont pas appelés, je ne comprends pas pourquoi.

Ceci est mon code; Je commence par mes modèles/formulaire - modèle myformtest-form.html.twig.

<h1>TEST</h1>
<form{{ element }}></form>

Mon code myformtest.module est le suivant.

/**
 * Implements hook_theme().
 */
function myformtest_theme($existing, $type, $theme, $path)
{
  return array(
    'form__myformtest_form' => array(
      'render element' => 'form',
      'template' => 'form--myformtest-form',
    ),
  );
}

Si je commente ce crochet, mon formulaire utilise le modèle de formulaire de thème par défaut. Dans ce cas, soumettez le formulaire appelez validate et soumettez les méthodes des gestionnaires de classe. Si je ne commente pas ce crochet, mon formulaire utilise mon modèle personnalisé. Ensuite, lorsque j'accède à ma page de formulaire personnalisé et que je valide le formulaire, le gestionnaire de validation et de soumission n'est jamais appelé.

Il s'agit du code simple de ma classe src/Form/MyformtestForm.php.

class MyformtestForm extends FormBase {
  //...
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['textfieldtest'] = [
      '#type' => 'textfield',
      '#title' => $this->t('textfieldtest'),
      '#maxlength' => 64,
      '#size' => 64,
    ];

    $form['submit'] = [
        '#type' => 'submit',
        '#value' => t('Submit'),
    ];

    return $form;
  }

  public function validateForm(array &$form, FormStateInterface $form_state) {
    ksm("MyformtestForm Validate handler!");
    // logs never displayed when I use my custom template. If I don't use the custom template, this log appears.
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {
    ksm("MyformtestForm Submit handler");
    // logs never displayed when I use my custom template. If I don't use the custom template, this log appears.
  }

Pourquoi les gestionnaires ne sont-ils pas appelés lorsque mon formulaire utilise mon remplacement personnalisé? Comment puis-je les appeler?

Ce sont les variables existant dans mon modèle personnalisé lorsque je charge ma page de formulaire.

screenshot

3
matthieu lopez

Vous avez besoin d'un "crochet de base" là-dedans, je crois.

Voici un exemple:

/**
 * Implements hook_theme().
 */
function formcustomtemplate_theme() {
  return array(
    'form__my_form_test' => array(
      'render element' => 'form',
      'template' => 'form--myformtest-form',
      'base hook' => 'form',
    ),
  );
}

Si vous utilisez un thème personnalisé et que vous n'avez pas besoin du modèle dans votre module, l'approche de création d'un nouveau crochet de thème pour votre formulaire personnalisé n'est pas nécessaire.
Plutôt que de créer un nouveau crochet de thème, utilisez hook_theme_suggestions_alter dans votre thème:

/**
 * Implements hook_theme_suggestions_alter().
 */
function mytheme_theme_suggestions_alter(array &$suggestions, array $variables, $hook) {

  if ($hook == 'form' & !empty($variables['element']['#theme'])) {
    $suggestions[] = 'form__' . $variables['element']['#theme'][0];
  }

}

puis créez le modèle approprié dans votre thème.

puis pour voir la sortie des suggestions de thème sur la page, activez twig debugging:

https://drupalize.me/blog/201405/lets-debug-twig-drupal-8

Vous verrez des suggestions de modèles dans le balisage:

<!-- FILE NAME SUGGESTIONS:
   * form--myformtest-form.html.twig
   x form.html.twig
-->

Vous pouvez voir qu'il ne récupère pas encore votre modèle, alors créez un fichier de modèle en copiant le formulaire.html.twig et en le renommant.

Pour vérifier où Drupal recherche des modèles à l'aide du crochet "formulaire", vous pouvez imprimer le registre des thèmes à partir de hook_theme_registry_alter:

 "form" => array:6 [▼
    "template" => "form"
    "path" => "themes/custom/mycustomtheme/templates/form"
    "type" => "theme_engine"
    "theme path" => "themes/custom/mycustomtheme”
    "render element" => "element"
    "preprocess functions" => array:4 [ …4]

Cela vous permet de savoir que vous devez placer le modèle dans ce répertoire.

3
oknate

Cela peut s'avérer utile pour les personnes qui souhaitent styliser chaque élément du formulaire.

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */

function MODULE_NAME_form_YOUR_FORM_ID_alter(&$form, FormStateInterface &$form_state) {
  $form['#theme'] = ['CUSTOM_NAME'];
}

Ensuite, j'ai installé mon crochet avec l'élément nécessaire.

/**
 * Implements hook_theme().
 */
function MODULE_NAME_theme($existing, $type, $theme, $path) {
  return [
    'CUSTOM_NAME' => [
      'render element' => 'form',
    ],
  ];
}

J'ai nommé mon modèle en conséquence (CUSTOM_NAME.html.twig). Ici, vous pouvez rendre votre $form éléments en conséquence (ex: {{ form.name }}, provenir de $form['name']).

Et enfin, croyez-moi, et surtout, n'oubliez pas d'inclure les variables form_build_id et form_token.

  {{ form.form_build_id }} {# required #}
  {{ form.form_id }} {# required #}
  {{ form.form_token }} {# required #}

La réponse à la question est déjà choisie, celle-ci est simple car elle permet d'expliquer comment structurer votre formulaire de manière plus approfondie.

À votre santé

1
Postovan Dumitru

si vous avez travaillé avec drupal 7, dans drupal 7 nous rendonsdrupal_render_children($form); dans nos balises à drupal render champs cachés et csrf, selon From.html.twig

Variables disponibles

attributes: A list of HTML attributes for the wrapper element.
children: The child elements of the form.

si vous voulez d'abord rendre les éléments comme vous le souhaitez, vous devez enfin rendre {{ children}} as drupal 7.

Donc rendez d'abord vos éléments de désir puis rendez {{ children }}, vous devriez essayer quelque chose comme

<h1>TEST</h1>
<div class="myclass">{{ element }} </div>
// other elements
// and finally
{{ children }}
0
Yusef

Je pense aussi que le rendu de votre formulaire est le problème. Jetez un œil aux modèles de formulaire par défaut dans core, comme form.html.twig.

https://api.drupal.org/api/drupal/core!modules!system!templates!form.html.twig/8.2.x

Puissiez-vous l'essayer de cette manière et utiliser {{children}} ou rendre les champs étape par étape avec quelque chose comme {{element.textfieldtest}}.

J'utiliserais donc ce code

<h1>TEST</h1>
<form{{ attributes }}>
  {{ children }}
</form>

Vous pouvez également vider la sortie dans le modèle avec {{ dump }} et regardez quelles variables vous avez. Voici un lien pour activer le twig debugging https://www.drupal.org/docs/8/theming/twig/debugging-twig-templates

0
Chris4783