Обратный вызов Drupal AJAX вызывается только один раз - PullRequest
0 голосов
/ 28 декабря 2011

Я пытаюсь создать форму в 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 Ответ

4 голосов
/ 06 сентября 2012

Проблема в том, что render(), который в основном просто вызывает drupal_render(), не обрабатывает элемент #ajax, он просто игнорируется. Возможно, вы захотите попробовать передать элемент через ajax_pre_render_element() перед вызовом render().

Тем не менее, лично у меня нет хорошего опыта попыток повторного использования функций Drupal вне их обычной последовательности вызовов, особенно не с формами. Я предпочитаю придерживаться функций самого высокого уровня, таких как drupal_get_form. Я много раз следил за этими функциями в моем отладчике, и они делают кучу вещей в точном порядке, который трудно понять, когда вы хотите повторно использовать их.

Чтобы изменить форму с помощью обратных вызовов AJAX, я бы всегда предпочел одну из двух стратегий:

  • В обратном вызове измените содержимое аргумента $form и выполните return $form. Для этого необходимо установить #ajax['wrapper'] для идентификатора (значение атрибута id в разметке, как используется для CSS) формы исходного элемента (кнопка в вашем случае). Затем Drupal выполняет свой шпиль со всей формой, и браузер заменяет все это. Drupal заботится о сохранении уже введенных значений и т. Д.
  • Кроме того, вы можете сделать так, чтобы обратный вызов возвратил набор команд, которые делают очень специфические изменения в DOM. В вашем случае это будут команды, которые создают и добавляют новые строки. Имейте в виду, что с ajax_command_invoke() в вашем распоряжении весь арсенал jQuery.

Из этих двух стратегий я обычно предпочитаю вторую, потому что она кажется более элегантной для небольших настроек. Однако, если вы хотите использовать рендеринг Drupal или если у вас есть более масштабные изменения в форме, вы должны использовать первый.

В качестве примечания, знаете ли вы, что существует drupal.stackexchange.com ? Drupal может быть довольно своеобразным, и на этом сайте вы найдете больше экспертов по специфике.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...