web-dev-qa-db-ja.com

AJAXフォーム送信を実装するにはどうすればよいですか?

私の仕事は、お問い合わせフォームを送信することですAJAX経由そして、「送信ありがとうございます!」フォームがあった場所に読み込まれたメッセージ。そのため、既存のお問い合わせフォームをajax化する必要があります。

D8でAJAXを使用してvalidateフォームフィールドを作成する方法の例をいくつか見つけましたが、-ajax form submissionを実装してロードする方法の例が見つかりませんAJAXを介していくつかのコンテンツ。

タスクを実装するにはどうすればよいですか?必要な機能を追加するには、お問い合わせフォームをどのように変更すればよいですか?

14

フォームでajaxを使用する場合は、次の点に注意する必要があります。

  • フォーム全体を再構築するのか、フォームの一部のみを再構築するのかを把握し、それに応じてフォームをdiv要素でラップしますID属性を持つ要素は、 「ラッパー」としてトリガー要素。 this(_$form['#prefix'] = '<div id="myform-ajax-wrapper">'; $form['#suffix'] = '</div>';_)には#prefix属性と#suffix属性を使用します。また、フォームのカスタムテンプレートがある場合[〜#〜] not [〜#〜]この場合、プレフィックスとサフィックスをレンダリングします({{ form|without('#prefix', '#suffix') }})それ以外の場合はテンプレートとフォームテーマラッパーによって、2回レンダリングされます。フォームテンプレートには実際のフォームhtml要素が含まれているため、#theme_wrappersを空の配列に設定してこれを防ぐことはできません。

  • ajax送信ハンドラーで、ラップしたフォーム全体またはその一部を返し、再構築したい(_return $form_または_return $form['myelement']_)。フォーム構造を返すだけでなく、さらにajaxコマンドを使用することもできますが、これはより高度なものです。

  • フォームを送信するまで、すべての値をフォームの状態のストレージに保存します。これを送信ハンドラ($form_state->set('somevalue', $form_state->getValue('somevalue')))で行い、最終的なフォーム送信を行わない場合は常に$form_state->setRebuild()を呼び出します。私はカスタムの送信ハンドラーを使用することを好みますが、プライマリ送信ハンドラーにロジックを追加してもまったく問題ありません。

  • 送信を実行しているボタンでは常に_#name_属性を使用します。フォーム送信ハンドラが1つしかない場合は、$for_state->getTriggeringElement()['#name']を使用して、フォームを送信した要素を検出します。

  • #ajax定義で 'trigger_as'を使用している場合、たとえばselect要素を含むフォームを送信する場合は、ボタンで行うのと同じように、常に同じ#ajax定義を使用してください。私の経験では、それは必須です-ドキュメントには記載されていませんが。

  • _#limit_validation_errors_を使用すると、非常にトリッキーになることがあり、フォームが機能しない理由を理解するのにかなり時間がかかることがあります。そのため、慎重に使用してください(これは、実際にある要素でのみフォームエラーを分離するのに適しています)コードがフォームの他の部分に影響しないように再構築します)。

  • 常にボタンを使用してフォームを送信します。トリガー要素として選択するなど、何かおもしろい場合は、#ajax設定の「trigger_as」オプションを使用し、「js-hide」クラスで実際のボタンを非表示にして、UIを改善します。

  • フォーム定義で、存在する場合はフォームの状態のストレージからデフォルト値を取得し、存在しない場合はデフォルト値をストレージに割り当てます。そうしないと、フォームが正しく機能しません。

  • $ thisなど、外部からアクセスできないものは使用しないでください。使用すると、ajaxが壊れます。常に静的Ajaxハンドラーを使用します。

  • 最終的にフォームを送信するとき、ajaxのカスタムフォーム送信ハンドラーを持っている(持っていない)ことに応じて、$form_state->setRebuild(FALSE)を呼び出してフォームの再構築を無効にします。

  • ajax submit要素(_$element['#ajax']['callback'] = '::ajaxFormRebuild';_および_$element['#submit'] = [['::ajaxFormSubmitHandler'];_)で::短縮呼び出しを使用できます。

  • ajaxコールバックは、純粋に再構築されたフォームまたはajaxコマンドを返すためのものです。変更されたフォームを返さないでください(つまり、このコールバックでフォーム配列を変更しないでください)。

26
user21641

Contact ajax モジュールを使用しています。それのいくつかの詳細(プロジェクトページから):

Contact Ajaxは、Contactフォームのajax送信をDrupal 8。

使い方

モジュールを有効にすると、各連絡先フォームに「Use ajax」チェックボックスが表示されます。このチェックボックスをオンにすると、お問い合わせフォームに次のオプションの「確認タイプ」という別のオプションが表示されます。

  • フォームの読み込み:ページを再読み込みせずにフォームを送信します。
  • カスタムメッセージから読み込む:カスタムテキストを読み込みます。
  • ノードからロード:フォームの送信後にノードをロードします。

このモジュールは、次の場合に役立ちます。

  • 確認メッセージをカスタマイズする必要があります
  • ページをリロードせずにお問い合わせフォームを送信する必要があります。
  • フォームの送信後にカスタムテキストまたは別のノードをロードする場合。
1
masdzen

このチェックリストに追加するために、モーダルウィンドウにフォームを表示している場合、エラーメッセージが表示されない可能性があります。 Ivan Jarosが言ったように、フォームにラッパーがあることを確認する必要があります。

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

また、フォームを送信する要素に以下を追加する必要があります。ほとんどの場合、それは送信ボタンです。

$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