2

おそらく何百もの思慮深い質問と同様に有用な回答を読んだ後、これは Stackoverflow に関する私の最初の投稿です。

私の言いたいことは、今日、私がやろうとしていることを行うための (汚い方法でさえも) 見つけたことがなく、答えを見つけることができなかったということです.

ちなみに…

AJAX を使用して同じフォームを再度呼び出すが、ユーザーが以前に入力した値とは異なる値を使用する

アイデア

テキストフィールドと AJAX 化された送信ボタンを備えた Drupal フォーム (Drupal フォーム API で構築された通常のフォーム) があります。このフォームは AJAX 呼び出しによって表示され、それ自体が AJAX 化されています。

「送信」をクリックすると、ユーザーがフォームに入力した内容に基づいて、データベースを調べたり、値を更新したりするなどの処理を実行したいと考えています。次に、同じフォームを再度 ajax 表示したいのですが、フォームの最初のインスタンスでユーザーが入力した値とは異なる値を使用します

処理中にやりたいことをやればすべてうまくいきますが、何をしても、何をしても同じ問題に何度も直面します。

問題

フォームの新しいインスタンスが表示されると、以前の値 (ユーザーが入力した値) が表示されます。フォームの前のインスタンスで「送信」がクリックされたときに、フォームに以前ここにあった値以外の値を表示することはできませんでした。

簡単な例

私が実際にやろうとしていることは、いくつかの ajax_commands と少しの処理で非常に複雑ですが、まったく同じ問題に直面する簡単な例を次に示します。

function ajax_first_callback_to_my_form($type = 'ajax') {
// here the first instance of the form is ajax-called. No problem with that.

    $mail = 'example@mail.com';
    $first_message = 'Please enter an email address...';

    $commands = array();
    $commands[] = ajax_command_replace('#my_ajax_wrapper', display_my_form($mail, $first_message));
    $page = array('#type' => 'ajax', '#commands' => $commands);
    return($page);

}

function display_my_form($mail, $message) {
// the function used to display the form.
// it can be called by the first ajax callback (the previous function in this example)
// or by the ajax callback triggered by clicking 'submit' on the form itself.

    $form = drupal_get_form('my_form', $mail, $message);

    $display = '<div id="my_ajax_wrapper">';
    $display .= render($form);
    $display .= '</div>';

    return $display;

}

function my_form($form, &$form_state, $mail, $message) {
// the form constructor

    $form = array (
        'email' => array (
            '#type' => 'textfield',
            '#default_value' => $mail,
            '#suffix' => '<div id="my_message">'.$message.'</div>',
        ),
        'submit' => array (
            '#type' => 'submit',
            '#ajax' => array (
                'callback' => 'my_ajax_callback', ),
        ),
    );

}

function my_ajax_callback($form, &$form_state) {
// triggered by clicking 'submit' in the form    

    $mail = $form_state['values']['email'];

    if ($mail == 'correct_mail@gmail.com') {
        $new_mail = 'different_mail@gmail.com';
        $new_message = 'You entered a correct email and here is your new one';
    } else {
        $new_mail = $mail;
        $new_message = 'You entered an incorrect mail, please correct it';
    }

    $commands = array();
    $commands[] = ajax_command_replace('#my_ajax_wrapper', display_my_form($new_mail, $new_message));
    $page = array('#type' => 'ajax', '#commands' => $commands);
    return($page);

}

function my_form_submit($form, &form_state) {
// my_form submit handler

    $form_state['rebuild'] = true; // appears necessary, otherwise won't work at all

}

さて、それはかなり長いコードでしたが、私の質問を完全に理解するのに役立ちました.

処理は正しく行われます...

my_form_submit または my_ajax_callback でやりたいことはすべて適切に行われています。display_my_form() で変数を確認すると、正しく更新されています。

...しかし、フォームの新しいインスタンスはそれを考慮していません

しかし、私が試すことができるものは何でも、次回フォームがAJAXで表示されると、メールフィールドはデフォルト値として「example@mail.com」になり(またはユーザーが入力した別のメール)、メッセージdivが入力されます「メールアドレスを入力してください...」

データベースを使用して、さまざまな関数を介して渡す代わりに $_SESSION 変数を使用して、送信後の処理を ajax コールバックの my_form_submit 関数に配置して、これを別の方法で行う多くの方法を試しました...これはどれも機能しません。

何をすべきか ?

かなり迷惑です。この問題に遭遇したのはこれが初めてではありません。前回は、AJAX を介して同じフォームを再表示するというこのアイデアを放棄するだけで、回避策を見つけることができましたが、今はこれができることに本当に感謝しています。

問題は $form_state['rebuild'] に関連しているのでしょうか?

ところで、私はそれについて興味があります: 以前にこの問題に遭遇したことがありますか? 私が見逃しているのは簡単なことですか?バグだとすれば、このバグは Drupal 関連なのか、AJAX 関連なのか...?

どんな助けやアイデアも本当に感謝しています。お時間をいただきありがとうございます。

4

3 に答える 3

1

私はこれに対する解決策を思いついた:

たとえば、この関数(AJAXコールバックによって呼び出される)を使用して、AJAXを使用して同じフォームを再度表示する場合は、何を実行しても、同じ値が何度も表示されます。

// It doesn't work :

function display_my_form($mail, $message) {  

    $form = drupal_get_form('my_form', $mail, $message);

    $display = '<div id="my_ajax_wrapper">';
    $display .= render($form);
    $display .= '</div>';

    return $display;
}

フォームを更新するときにフィールドの値を変更する場合は、フォームを再度呼び出した後、次のような行を追加して、フォームを手動で更新する必要があります。

// It works :

function display_my_form($mail, $message) {

    $form = drupal_get_form('my_form', $mail, $message); // $variables are simply ignored if the form is already displayed. Rebuilding it won't change a thing.

    $form['email']['#default_value'] = $mail; // update a part of the form
    $form['email']['#suffix'] = $message; // update another part of the form

    $display = '<div id="my_ajax_wrapper">';
    $display .= render($form);
    $display .= '</div>';

    return $display; // sends $display to our AJAX callback, and everything's fine now

}

簡単に信じられることとは異なり、(... meなど)最初にそれについて知ることができますが、フォームは、AJAXによってすでに構築およびリコールされている場合、drupal_get_formで送信される変数を考慮しません。

変数を更新して、drupal_get_formを再度実行するだけでは不十分です。drupal_get_formを実行し、その後、更新するフォームの部分を手動で更新する必要があります。

これが誰かを助けることを願っています。

于 2013-02-21T10:36:22.427 に答える
0

注: 機能させるには、これを form_submit ハンドラに追加する必要があります:

function my_form_submit($form, &$form_state)
{
    $form_state['rebuild'] = true;
}
于 2013-07-18T13:36:29.687 に答える
0

これが事実である場合、私はあなたの問題についてかなり自信を持っています:

$commands[] = ajax_command_replace('#my_ajax_wrapper', display_my_form($new_mail, $new_message));

問題は、あなたが渡しているIDだけではありません。ID「#my_ajax_wrapper」ではなく、クラスが必要です.IDは変更される可能性がありますが、この場合クラスは変更されないためです。これを試してみると、必要な結果が得られるはずです。

于 2013-07-18T10:13:10.920 に答える