Drupal AJAX回调只调用一次

时间:2011-12-28 02:37:37

标签: ajax drupal

我正在尝试在Drupal中创建一个表单,因此可以将多个元素添加到表单中。例如,页面可能包含事件的数据,那么事件可能有多个日期。所以我的表格看起来像:

/**
 * 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文件将输入字段的val替换为''

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

但是这个回调只被调用一次。我相信这是因为一旦调用它就必须再次附加行为。对不起我的无知 - 我不知道如何实现这一目标。谁能帮我吗?非常感谢。提前谢谢。

1 个答案:

答案 0 :(得分:4)

问题在于,基本上只调用render()的{​​{1}}不处理drupal_render()元素,它只是被忽略了。您可能希望在调用#ajax之前尝试通过ajax_pre_render_element()传递元素。

那就是说,我个人在尝试在正常调用序列之外重用Drupal函数方面没有很好的经验,特别是没有表单。我更喜欢坚持顶级功能,例如render()。我已经在我的调试器中多次跟踪这些函数,并且它们按照精确的顺序执行了大量操作,当您想要重用它时,很难掌握它们。

要使用AJAX回调更改表单,我总是更喜欢以下两种策略之一:

  • 在回调中,调整drupal_get_form参数的内容并执行$form。这要求您将return $form设置为原始元素(您的案例中的按钮)上的表单的id(标记中的#ajax['wrapper']属性的值,如用于CSS)。然后Drupal用整个表单来完成它的shpiel,浏览器取代了整个表单。 Drupal负责保留已经输入的值等。
  • 或者,您可以让回调返回一组对DOM执行非常具体修改的命令。在您的情况下,这将是创建和追加新行的命令。请记住,使用id,您可以使用整个jQuery库。

从这两种策略中,我通常更喜欢第二种策略,因为对于小调整看起来更优雅。但是,如果你想在Drupal的渲染上构建,或者你对表单进行了更大规模的更改,你应该使用第一个。

作为旁注,你知道有drupal.stackexchange.com吗? Drupal非常奇特,在那个网站上,你会找到更多关于细节的专家。