2

这是我在 Stackoverflow 上的第一篇文章,在阅读了数百个深思熟虑的问题和同样有用的答案之后。

我的观点是,今天,我从来没有找到一种(甚至是肮脏的)方法来做我打算做的事情,也从来没有设法找到答案,尽管似乎不太可能没有人有同样的要求和/或问题。

也就是说,顺便说一句...

再次使用 AJAX 调用相同的表单,但使用的值与用户之前输入的值不同

这个想法

我有一个带有文本字段和 AJAX 化提交按钮的 Drupal 表单(使用 Drupal 表单 API 构建的普通表单)。此表单通过 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 将被填充与“请输入电子邮件地址...”。

我尝试了许多不同的方法,将提交后处理放在 ajax 回调中,在 my_form_submit 函数中,使用 $_SESSION 变量而不是通过不同的函数传递它们,使用数据库......这些都不起作用。

该怎么办 ?

很烦人。这不是我第一次遇到这个问题。上次我可以找到一种解决方法,只需放弃通过 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

}

与人们(例如......我)首先可以了解它的简单信念相反,当已经由 AJAX 构造和调用时,表单不考虑使用 drupal_get_form 发送的变量。

仅仅更新变量是不够的,然后再做一次 drupal_get_form 。您必须执行 drupal_get_form,然后手动更新要更新的表单部分。

希望这会对某人有所帮助。

于 2013-02-21T10:36:22.427 回答
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 回答
0

注意:要使其工作,需要在 form_submit 处理程序中添加:

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