web-dev-qa-db-fra.com

Comment puis-je implémenter AJAX soumission de formulaire?

Ma tâche est de soumettre le formulaire de contact via AJAX puis de montrer "Merci pour la soumission!" message, chargé à l'endroit où se trouvait le formulaire. J'ai donc besoin d'ajaxifier le formulaire de contact existant.

J'ai trouvé quelques exemples comment valider les champs de formulaire en utilisant AJAX dans D8, mais je ne trouve aucun exemple comment implémenter soumission de formulaire ajax = et charger du contenu via AJAX alors.

Comment mettre en œuvre ma tâche? Comment dois-je modifier le formulaire de contact pour ajouter les fonctionnalités requises?

14
Sergey Kravchenko

Lorsque vous travaillez avec ajax dans des formulaires, vous devez garder à l'esprit les éléments suivants:

  • savoir si vous reconstruisez le formulaire entier ou seulement une partie de celui-ci et envelopper le formulaire en conséquence avec l'élément div qui a attribut ID que vous utiliserez dans la définition #ajax sur le élément déclencheur en tant que "wrapper". Utilisez les attributs #prefix et #suffix pour cela ($form['#prefix'] = '<div id="myform-ajax-wrapper">'; $form['#suffix'] = '</div>';). Gardez également à l'esprit que si vous avez un modèle personnalisé pour votre formulaire pour PAS rendre le préfixe et le suffixe dans ce cas ({{ form|without('#prefix', '#suffix') }}) sinon ils seront rendus deux fois - par votre modèle et également par l'encapsuleur de thème de formulaire. Vous ne pouvez pas empêcher cela en définissant #theme_wrappers sur un tableau vide car le modèle de formulaire contient l'élément HTML réel du formulaire.

  • dans votre gestionnaire de soumission ajax, renvoyez le formulaire entier ou une partie de celui-ci que vous avez encapsulé et que vous souhaitez reconstruire (return $form ou return $form['myelement']). Vous pouvez également utiliser des commandes ajax au lieu de simplement renvoyer la structure du formulaire, mais ce sont des choses plus avancées.

  • stocker chaque valeur dans le stockage de l'état du formulaire jusqu'à ce que vous soumettiez le formulaire. Faites cela dans le gestionnaire de soumission ($form_state->set('somevalue', $form_state->getValue('somevalue'))) et appelez toujours $form_state->setRebuild() si vous ne faites pas la soumission du formulaire final. Je préfère avoir des gestionnaires de soumission personnalisés, mais avoir plus de logique dans le gestionnaire de soumission principal est également tout à fait correct.

  • utilisez toujours l'attribut #name sur le bouton qui effectue la soumission et si vous n'avez qu'un seul gestionnaire de soumission de formulaire, utilisez $for_state->getTriggeringElement()['#name'] pour détecter quel élément a soumis le formulaire.

  • si vous utilisez 'trigger_as' dans la définition #ajax, dans le cas où vous souhaitez soumettre le formulaire avec l'élément select par exemple, utilisez toujours la même définition #ajax comme vous le faites sur le bouton. D'après mon expérience, cela est nécessaire - bien que cela ne soit pas indiqué dans la documentation.

  • l'utilisation de #limit_validation_errors peut parfois être très délicate et comprendre pourquoi le formulaire ne fonctionne pas peut prendre un certain temps, alors utilisez-le avec précaution (cela est bon pour isoler les erreurs de formulaire uniquement sur les éléments que vous utilisez) en cours de reconstruction afin que votre code n'influence pas les autres parties du formulaire).

  • utilisez toujours des boutons pour soumettre le formulaire et si vous voulez avoir quelque chose de fantaisiste, comme choisir d'être l'élément déclencheur, utilisez l'option 'trigger_as' de la configuration #ajax et cachez le vrai bouton avec la classe 'js-hide' pour une bonne interface utilisateur.

  • dans la définition de formulaire, obtenez les valeurs par défaut du stockage de l'état du formulaire si elles existent ou affectez-les dans le stockage si ce n'est pas le cas. Sinon, le formulaire ne fonctionnera pas correctement.

  • n'utilisez pas $ this ou toute autre chose à laquelle vous n'avez pas accès en externe, sinon cela cassera l'ajax. utilisez toujours des gestionnaires ajax statiques.

  • lors de la soumission finale du formulaire, selon que vous n'avez (pas) de gestionnaire de soumission de formulaire personnalisé pour ajax, désactivez la reconstruction du formulaire en appelant $form_state->setRebuild(FALSE).

  • vous pouvez utiliser les appels raccourcis :: dans l'élément de soumission ajax ($element['#ajax']['callback'] = '::ajaxFormRebuild'; et $element['#submit'] = [['::ajaxFormSubmitHandler'];).

  • le rappel ajax consiste uniquement à renvoyer le formulaire reconstruit ou les commandes ajax. Ne retournez jamais de formulaire modifié (c.-à-d. Ne modifiez pas le tableau de formulaires dans ce rappel).

26
user21641

J'utilise le module Contact ajax . Quelques détails supplémentaires (à partir de sa page de projet):

Contact Ajax implémente la soumission ajax pour le formulaire de contact dans Drupal 8.

Comment ça fonctionne

Après avoir activé le module, chaque formulaire de contact affichera une case à cocher "Utiliser ajax". Lorsque cette case est cochée, le formulaire de contact vous montrera une autre option "Type de confirmation" avec ces options:

  • Charger le formulaire: enverra le formulaire sans recharger la page.
  • Charger depuis un message personnalisé: chargez un texte personnalisé.
  • Charger depuis le nœud: charger un nœud après la soumission du formulaire.

Ce module pourrait vous aider si:

  • vous devez personnaliser le message de confirmation
  • vous devez soumettre un formulaire de contact sans recharger la page.
  • vous souhaitez charger un texte personnalisé ou un autre nœud après la soumission du formulaire.
1
masdzen

Pour ajouter à cette liste de contrôle, si vous affichez un formulaire dans une fenêtre modale, il est possible que les messages d'erreur ne s'affichent pas. Comme l'a dit Ivan Jaros, vous devez vous assurer que le formulaire a un wrapper:

$form['#prefix'] = '<div id="my-form-wrapper-id">';
$form['#suffix'] = '</div>';

Vous devrez également ajouter ce qui suit à l'élément qui soumet le formulaire. Dans la plupart des cas, ce serait votre bouton d'envoi:

$form['submit'] = [
    '#type' => 'submit',
    '#value' => $this->t('Save Changes'),
    '#attributes' => [
        'class' => [
            'btn',
            'btn-md',
            'btn-primary',
            'use-ajax-submit'
        ]
    ],
    '#ajax' => [
        'wrapper' => 'my-form-wrapper-id',
    ]
];
1
IslandDev