Drupal AJAX回调只调用一次

Drupal AJAX回调只调用一次

问题描述:

我想在Drupal中创建一个表单,因此可以将多个元素添加到表单中。例如,一个页面可能包含一个事件的数据,那么该事件可能有多个日期。所以,我有,看起来像一个形式:Drupal AJAX回调只调用一次

/** 
* Implements hook_form_alter(). 
*/ 
function addextra_form_alter(&$form, &$form_state) { 
    if ($form['#form_id'] == 'test_content_node_form') { 
    $form['elements_table'] = array(
     '#theme' => 'table', 
     '#title' => 'Elements already added', 
     '#header' => array('Item', 'Remove'), 
     '#empty' => 'No elements', 
     '#prefix' => '<div id="elements-table">', 
     '#suffix' => '</div>', 
    ); 
    $form['add_elements'] = array(
     '#title' => 'Add another element', 
     '#type' => 'fieldset', 
     '#collapsible' => TRUE, 
     '#collapsed' => FALSE, 
    ); 
    $form['add_elements']['add_content'] = array(
     '#type' => 'textfield', 
     '#description' => t('Add an element to the table'), 
     '#title' => t('Add another item'), 
     '#size' => '12', 
     '#maxlength' => '60', 
     '#prefix' => '<div id="addextra_content">', 
     '#suffix' => '</div>', 
    ); 
    $form['add_elements']['add_another_btn'] = array(
     '#type' => 'button', 
     '#name' => 'add_another', 
     '#button_type' => 'submit', 
     '#executes_submit_callback' => FALSE, 
     '#value' => 'Add another', 
     '#ajax' => array(
      'callback' => 'addextra_element_to_table', 
     ), 
    ); 
    } 
} 

当“add_another_btn”被点击,它会运行Ajax回调“addextra_element_to_table。

该回调是:

function addextra_element_to_table(&$form, &$form_state) { 
    $form['elements_table']['#rows'][] = array($form_state['values']['add_content'], l('Remove Item', '#')); 
    drupal_add_js(drupal_get_path('module', 'addextra') . '/addextra.js'); 
    return array(
     '#type' => 'ajax', 
     '#commands' => array(
      ajax_command_replace('#elements-table', render($form['elements_table'])), 

    ), 
); 
} 

叫JS文件替换输入字段为 ''

(function ($) { 
    $('#edit-add-content').val(''); 
})(jQuery); 

的VAL但只有这个回调函数被调用一次。我相信这是因为一旦被调用,行为必须重新被附加。对不起,我的无知 - 我不知道如何实现这一点。谁能帮我吗?这将非常感激。提前致谢。

+0

我不是Drupal的专家,但是你所做的是在已经加载的html页面中一次又一次添加相同的js文件,并期望每次调用'$(document).onload()'事件?看起来很奇怪。为什么使用Ajax来实现?难道你不能'克隆'一个(最终)隐藏的节点吗? – Stan 2011-12-28 02:50:05

+0

我可以删除js,但替换为新元素的表单也不起作用。它不会在回调中添加'#row'数据的操作。 – Deshiknaves 2011-12-28 03:00:04

+0

我已经移动了drupal_add_js,它按预期工作。每当我为add_content添加一个新值时,它都会运行并替换表。但它不添加到“#rows”,它只是用新值替换行,而不是加入一个新元素,则表更换表。任何想法将不胜感激。我知道还有其他的方法可以实现这一点,但我现在只想弄清楚如何以这种方式实现它,所以我可以在将来使用这种方法。 – Deshiknaves 2011-12-28 08:49:12

问题是render(),基本上只是调用drupal_render(),不处理#ajax元素,它只是被忽略。在致电render()之前,您可能想尝试通过ajax_pre_render_element()传递元素。

这就是说,我个人没有很好的经验,试图在正常的调用顺序之外重用Drupal函数,特别是不使用窗体。我更喜欢坚持*功能,如drupal_get_form。我在调试器中多次跟踪这些函数,并且他们按照精确的顺序执行一系列的操作,当你想重用这些函数的时候很难保留下来。

要改变与AJAX回调一种形式,我总是喜欢两种策略之一:

  • 在回调,调整$form争论的内容和做return $form。这要求您将#ajax['wrapper']设置为原始元素(您的案例中的按钮)上的表单的id(标记中的id属性的值,用于CSS)。然后Drupal可以完成整个表单的浏览器,而浏览器取代了整个表单。 Drupal负责保存已经输入的值等。
  • 或者,您可以让回调返回一组命令,这些命令在DOM上做了非常特定的修改。在你的情况下,这将是创建和追加新行的命令。请记住,与ajax_command_invoke(),你有你的处置整个jQuery武库。

从这两种策略中,我通常更喜欢第二种策略,因为它对于小小的调整似乎更加优雅。然而,如果你想建立在Drupal的渲染上,或者如果你对窗体有更大的改变,你应该使用第一个。

作为一个附注,你知道有drupal.stackexchange.com? Drupal可能很特别,在这个网站上,你会发现更多的细节专家。

+0

我有同样的问题,并做“返回$表格;”在*id的回调中立即修复它(vs“return $ form ['some_element'];”到一个有针对性的id)。这是迄今为止我能够做出的唯一解决方案。谢谢! – 2013-06-10 23:00:26

+0

+1指向drupal.stackexchange.com – 2014-06-19 09:38:17