web-dev-qa-db-ja.com

AJAXを使用してフォームを検証および送信する方法

Form APIを使用してWebフォームを作成しました。 #AJAXフィールドオプションを使用して、各フィールドにAJAX検証を追加しています。

AJAXを使用して、ページを再読み込みせずにフォームを検証して送信することは可能ですか。検証が失敗した場合はエラーメッセージを表示し、検証が成功した場合はメッセージを表示します(理想的にはライトボックス)、フォームフィールドをリセットします。

これまでの私のコード:

$form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Name'),
    '#default_value' => '',
    '#maxlength' => '128',
    '#required' => TRUE,
    '#ajax' => array(
        'callback' => '_validate_name',
        'wrapper' => 'name-error-icon-container',
        'method' => 'html',
        'effect' => 'none',
        'progress' => array(
            'message' => NULL,
        ),
    ),
);

$form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Submit',
    '#ajax' => array(
        'callback' => '_handle_form_submit',
        'effect' => 'fade',
    ),
);

コールバック関数は次のようになります。

function _validate_name($form, $form_state) {

    if ($form_state['values']['name'] != '') {
    $output = 'OK';
    }
    else {
      $output = 'Enter a value';
    }

   return $output;

}

function _handle_form_submit($form, $form_state) {
}

しかし、_handle_form_submit関数を検証してメッセージを返すか、フォームを送信してフィールドをリセットするために何を行うべきかわかりませんか?

12
Camsoft

私はこれが数年前からうそをついている質問であることを知っていますが、他のどの回答も本当にDrupal 7 ajaxフォーム送信のポイントを獲得することになるとは思わないので、私はそれを説明しようとします。

良い習慣に従って、フォームがajaxなしでも機能することを確認してください。ajax送信ハンドラはフォームを返すだけです。それ以外はすべて、検証と送信関数に含める必要があります。

function ex_form($form, $form_state) {
  $form['name'] = array(
    '#type' => 'textfield',
     '#title' => t('Name'),
     '#default_value' => '',
     '#maxlength' => '128',
     '#required' => TRUE,
  );

  $form['submit'] = array(
   '#type' => 'submit',
   '#value' => 'Submit',
   '#ajax' => array(
     'callback' => 'ex_form_ajax_handler',
     'effect' => 'fade',
   ),
  );
}

function ex_form_submit(&$form, &$form_state) {
  // Submit logic - runs when validation is ok
  // You can alter the form here to be just a markup field if you want.
}

function ex_form_validate(&$form, &$form_state) {
  // Validation logic - invalidate using form_set_error() or form_error()
}

function ex_form_ajax_handler(&$form, &$form_state) {
  return $form;
}
11
OWast

2011年10月17日のmaxtoreteによる投稿 は、form_validate()form_submit()の両方を使用したより完全な例を示しているようです

(まだテストしていません。)

また、 stack overflow でのJoshua Stewardsonの回答には、素晴らしい作業例があります。

function dr_search_test_form($form, &$fstate) {

  $form['wrapper'] = [
    '#markup' => '<div id="test-ajax"></div>',
  ];

  $form['name'] = [
    '#type'     => 'textfield',
    '#required' => TRUE,
    '#title'    => 'Name',
  ];

  $form['submit'] = [
    '#type'  => 'submit',
    '#value' => 'Send',
    '#ajax'  => [
      '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.');
}

ジョシュアは、検証エラーメッセージが#ajax['wrapper']要素を完全に置き換えるため、コールバックでは、この要素を置き換えるときにこの要素を再度供給する必要があります。

3
ErichBSchulz

一般に、検証とフォーム送信の処理は、通常の_validate()および_submit()コールバックで行われる必要があります。つまり、フォームはajaxがなくても機能するはずです。

#ajaxコールバックが行うべきほとんど唯一のことは、定義されたラッパーに従って、置き換えられるフォームの一部を返すことです。

2
Berdir

私の場合、submitタイプを使用するとフォームが常に送信されるため、#ajaxを指定してbuttonに変更しました。次に、ajaxコールバックで検証を行う必要がありました。

私はctoolsペインを作成していました。それがそれに影響を与えるかどうかはわかりません。

function mymodule_form($form, &$form_state) {
  ...
  $form['button'] = array(
    '#type' => 'button',
    '#value' => t('Subscribe'),
    '#ajax' => array(
      'callback' => '_mymodule_ajax',
    ),
  );
  return $form;
}

function _mymodule_ajax($form, &$form_state) {
  if ( ! valid_email_address($form_state['values']['email']) ) {
    form_set_error($form, t('Please enter a valid email address.'));
  } else {
    $form = array(
      '#markup' => t('You have subscribed.'),
    );
  }
  return $form;
}
0
user1359

2つの方法があります

1)

function abc_form_validate(&$form, &$form_state) {
  // Validation logic - invalidate using form_set_error() or form_error()
}

function abc_form_ajax_handler(&$form, &$form_state) {
  return $form;
}

2)モジュールの例 http://cgit.drupalcode.org/examples/tree/ajax_example/ajax_example.module?id=refs/heads;id2=7.x-1.x#l402

0
Drock