ボタンが付いたフォームがあり、これを押すと、ajaxリクエストを介してフォームの別の部分が再構築されます。
ボタンをクリックするとフォームが再構築され、フォームから値を保存してフォームの一部を返す私のajaxコールバックが呼び出されます。
問題は、値を保存するコールバックの前にフォームが再構築され、フォームの構築方法が変更されることです。
もう一度ajaxボタンをクリックすると、フォームがビルドされたときの前回のajaxリクエストの値と同じように正しく機能します。
フォームが再構築される前にコールバック関数を実行するにはどうすればよいですか?
_function emtr_shift_plan_form($form, &$form_state) {
ddl('build'); // log that this function is being called
$form['save'] = array(
'#type' => 'button',
'#submit' => array('emtr_shift_plan_form_ajax_submit'),
'#value' => 'Save',
'#ajax' => array(
'callback' => 'emtr_shift_plan_form_ajax_submit',
'wrapper' => 'postions',
),
'#id' => 'ajax-save-form-values',
);
$form['postions'] = array(
'#type' => ' container',
'#prefix' => '<div id="postions">',
'#suffix' => '</div>',
);
// code here to populate the positions container
}
function emtr_shift_plan_form_ajax_submit($form, &$form_state) {
ddl('ajax submit'); // log the ajax callback is being called
$form_state['rebuild'] = TRUE; // As the form has already been rebuilt at this point what effect can this have?!?
emtr_shift_plan_form_save($form, $form_state); // save the values
// This is the point at which I want the form to be rebuilt
return $form['positions'];
}
_
編集:
回避策として、$form = drupal_rebuild_form('emtr_shift_plan_form', $form_state);
を使用してajaxコールバックで2回目にフォームを手動で再構築することは可能ですが、フォームを2回構築するのは非効率的です。 Ajaxリクエストごとにフォームを2回ビルドするのではなく、これらのイベントの順序を入れ替えることはできますか?
私はこの質問が3歳であることを知っていますが、同様の問題を検索しているときに出くわしました。
これを機能させるには、アプローチを変更する必要があります。 AJAXリクエストを送信するときの操作の順序は次のとおりです:
$form_state
変数。デモのためにコードを少し作り直しました。
// AJAX FLOW: 2. Form rebuild is fired.
function emtr_shift_plan_form($form, &$form_state) {
ddl('build'); // log that this function is being called
$form['save'] = array(
'#type' => 'button',
'#submit' => array('emtr_shift_plan_form_button_submit'),
'#value' => 'Save',
'#ajax' => array(
'callback' => 'emtr_shift_plan_form_ajax',
'wrapper' => 'postions',
),
'#id' => 'ajax-save-form-values',
);
$form['postions'] = array(
'#type' => ' container',
'#prefix' => '<div id="postions">',
'#suffix' => '</div>',
);
// code here to populate the positions container
if (isset($form_state['saved_values'])) {
// do stuff.
}
}
// AJAX FLOW: 1. Button submit is fired.
function emtr_shift_plan_form_button_submit($form, &$form_state) {
// log the ajax callback is being called
ddl('ajax submit');
// save the values. Make sure the data is stored somehow so your form can get at it.
$form_state['saved_values'] = emtr_shift_plan_form_save($form, $form_state);
// rebuild flag here will trigger emtr_shift_plan_form() to be run
$form_state['rebuild'] = TRUE;
}
// AJAX FLOW: 3. Button callback is fired.
function emtr_shift_plan_form_ajax($form, &$form_state) {
return $form['positions'];
}
それが誰かのためにいくつかの光を当てることを願っています。
このようにして、送信とコールバックを異なるものにして、それが役立つかどうかを確認できます。
$form['save'] = array(
'#type' => 'button',
'#submit' => array('emtr_shift_plan_form_ajax_submit'),
'#value' => 'Save',
'#ajax' => array(
'callback' => 'emtr_shift_plan_form_ajax',
'wrapper' => 'postions',
),
'#id' => 'ajax-save-form-values',
);
function emtr_shift_plan_form_ajax($form, &$form_state){
return $form['positions'];
}
function emtr_shift_plan_form_ajax_submit($form, &$form_state) {
ddl('ajax submit'); // log the ajax callback is being called
$form_state['rebuild'] = TRUE; // As the form has already been rebuilt at this point what effect can this have?!?
emtr_shift_plan_form_save($form, $form_state); // save the values
// This is the point at which I want the form to be rebuilt
}