13

Drupal 7 でフォームを作成し、AJAX を使用したいと考えています。これを送信ボタン配列に追加しました:

"#ajax" => array(
  "callback" => "my_callback",
  "wrapper" => "details-container",
  "effect" => "fade"
)

これは機能しますが、検証関数全体が無視されます。my_callback()が呼び出される前にフォームを検証するにはどうすればよいですか? また、AJAX フォームにステータス メッセージやエラー メッセージを表示するにはどうすればよいでしょうか。

4

6 に答える 6

20

この質問と回答は、正しい解決策を導くのに役立ちましたが、正確には明確ではありません。そうしましょう。

非常に注意すべきこと:

  1. 検証エラー メッセージは、#ajax['wrapper']
  2. Drupal Forms API の ajax ラッパーのドキュメントで、「要素のコンテンツだけでなく、この ID を持つ要素全体が置き換えられる」と記載されている箇所に注意してください。
  3. その要素は置き換えられるため、再度提供した方がよいでしょう。 それが、マリウス・イリーの答えが機能する理由です-配列との#markupためではなく、ラッパーIDが設定されたdivを含めているためです。

マリウスが上記のコメントに入れたことに基づいて、私のために働いていたコードは次のとおりです。

function dr_search_test_form($form, &$fstate) {
  $form["wrapper"] = array("#markup" => "<div id='test-ajax'></div>");

  $form["name"] = array(
    "#type" => "textfield",
    "#required" => true,
    "#title" => "Name"
  );

  $form["submit"] = array(
    "#type" => "submit",
    "#value" => t("Send"),
    "#ajax" => array(
      "callback" => "dr_search_test_form_callback",
      "wrapper" => "test-ajax",
      "effect" => "fade",
    ),
  );
  return $form;
}

function dr_search_test_form_callback($form, &$fstate) {
  return "<div id='test-ajax'>Wrapper Div</div>";
}

function dr_search_test_form_validate($form, &$fstate) {
  form_set_error("name", "Some error to display.");
}
于 2012-06-28T02:54:43.783 に答える
10

この問題に対する優れた解決策を見つけました。

クレジットはこの男のブログに送られます:

http://saw.tl/validate-form-ajax-submit-callback

彼が提案する解決策は次のとおりです。

// when creating or altering the form..
{
  $form['#prefix'] = '<div id="formwrapper">';
  $form['#suffix'] = '</div>';
  // the submit button
  $form['save']['#ajax'] = array(
    'callback' => 'mymodule_form_ajax_submit',
    'wrapper' => 'formwrapper',
    'method' => 'replace',
    'effect' => 'fade',
  );
 // ...
}

function mymodule_from_ajax_submit($form, &$form_state) {
  // validate the form
  drupal_validate_form('mymodule_form_id', $form, $form_state);
  // if there are errors, return the form to display the error messages
  if (form_get_errors()) {
    $form_state['rebuild'] = TRUE;
    return $form;
  }
  // process the form
  mymodule_form_id_submit($form, $form_state);
  $output = array(
    '#markup' => 'Form submitted.'
  );
  // return the confirmation message
  return $output;
}
于 2014-03-06T13:46:25.503 に答える
9

これはどれも私にとってはうまくいきません。フォーム送信の ajax 関数は、コールバック関数を直接呼び出すだけで、検証、送信をバイパスし、ボタンを複数回クリックできないようにします。検証メッセージは表示されません。Joshua Stewardson のコードを文字通りコピーして貼り付けましたが、うまくいきませんでした。

この使用例が非常に難しく、文書化されていないという事実は、非常に動揺しています。私には、これが AJAX フォーム API の最も基本的な要求のように思えます。わかりました、私の欲求不満を解決策にぶつけました。

これを機能させるために私が最終的に行ったことは次のとおりです。ハッキーで遅れているように感じます。1 つのページにフォームのインスタンスが複数ある場合も壊れますが、これが最善の方法でした。誰かがこれに光を当てることができるなら、してください!

基本的に、コールバック内でフォーム全体をそれ自体に置き換え、設定されたメッセージを手動でフォーム オブジェクトに追加する必要があります。これを行うには、ラッパーをフォームの ID として宣言します (ID が更新されるため、1 つのページにフォームのインスタンスが複数ある場合は壊れます)。

function productsearchbar_savesearch_form($form, &$form_state) {

  $form["wrapper"] = array("#markup" => "<div class='inline-messages'></div>");

  $form["name"] = array(
    "#type" => "textfield", 
    "#required" => true,
    "#title" => "Name"
  );

  $form["submit"] = array(
    "#type" => "submit", 
    "#value" => "Send", 
    "#ajax" => array(
      "callback" => "productsearchbar_savesearch_form_callback", 
      "wrapper" => "productsearchbar-savesearch-form", 
      "effect" => "fade"
    )
  );

  return $form;
}

function productsearchbar_savesearch_form_callback($form, &$form_state) {
  $messages = theme('status_messages');

  if($messages){
    $form["wrapper"] = array("#markup" => "<div class='inline-messages'>$messages</div>");
  }
  return $form;
}

function productsearchbar_savesearch_form_validate($form, &$form_state) {
  if ($form_state['values']['name'] == '') {
   form_set_error('', t('Name field is empty!'));
  }
}

function productsearchbar_savesearch_form_submit($form, &$form_state) {
  drupal_set_message(t('Your form has been saved.'));
}
于 2012-12-11T16:05:06.777 に答える
7

わかりました、わかりました。どうやら、テキストメッセージだけでなく、ajaxコールバック関数で配列を返す必要があります...

このようなもの:

return array("#markup" => "<div id='wrapper'></div>");
于 2011-10-27T08:06:10.647 に答える