这是我在Stackoverflow上发表的第一篇文章,在阅读了数百个深思熟虑的问题后,也就是有用的答案。
我的观点是,今天,我从来没有找到一种(甚至是肮脏的)方式来做我打算做的事情,并且从未设法找到答案,尽管似乎很不可能没有人有同样的要求和/或问题
顺便说一句......
我有一个Drupal表单(使用Drupal Form API构建的普通表单),包含文本字段和一个AJAX-ified提交按钮。这个表单是通过AJAX调用显示的,本身就是AJAX-ified,所以。
当我点击“提交”时,我想做一些事情,比如查看数据库,更新某些值等,根据用户在表单中输入的内容。然后,我希望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将填写“请输入电子邮件地址......”。
我尝试了许多不同的方法,将后提交处理放在my_form_submit函数中的ajax回调中,使用$ _SESSION变量,而不是使用数据库传递它们通过不同的函数...没有这个的工作原理。
相当讨厌。这不是我第一次遇到这个问题。上次我找到一个解决方法,只是放弃了通过AJAX重新显示相同形式的想法,但现在我真的很希望能够做到这一点。
问题可能与$ form_state ['rebuild']有关吗?
顺便说一句,我很好奇:你以前遇到过这个问题吗?我错过了一些简单的东西吗?如果它是一个bug,这个bug可能是与Drupal相关的,还是与AJAX相关的......?
任何帮助或想法都将得到真正的赞赏。谢谢你的时间。
答案 0 :(得分: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
}
与简单的信念相反,一个(例如......我)可以首先了解它,该形式没有考虑使用drupal_get_form发送的变量,当已经构建并由AJAX调用时。
仅更新变量是不够的,并再次执行drupal_get_form。您必须执行drupal_get_form,然后手动更新要更新的表单部分。
希望这会对某人有所帮助。
答案 1 :(得分:0)
如果是这种情况,我对你的问题非常有信心:
$ commands [] = ajax_command_replace('#my_ajax_wrapper',display_my_form($ new_mail,$ new_message));
问题不在于它只是你传递的id。你需要一个类而不是id“#my_ajax_wrapper”,因为id可能会被改变但是在这种情况下类不会。 试试这个你应该得到你想要的结果。
答案 2 :(得分:0)
注意:要使其工作,需要在form_submit处理程序中添加它:
function my_form_submit($form, &$form_state)
{
$form_state['rebuild'] = true;
}