#элементы ajax, добавленные в форму крючка, изменяют пропуск после первого вызова ajax


Я изменяю элементы из модуля множественного выбора, чтобы добавить функциональность ajax. Я хотел использовать функцию hook_field_widget_WIDGET_TYPE_form_alter(), но я застрял в 7.14, и для этого требуется 7.8.

Итак, я просматриваю форму $ в hook_form_alter(), чтобы найти изменение элементов "множественного выбора":

/*
 * Implements hook_form_alter()
 */
function ajax_multiselect_form_alter(&$form, &$form_state, $form_id) {
  _ajax_multiselect_search_children($form, $form);
}

/*
 * Look for multiselect elements
 */
function _ajax_multiselect_search_children(&$form, &$element) {

  if (isset($element['#type']) && $element['#type'] == 'multiselect') {
    _ajax_multiselect_modify_multiselect($form, $element);
  }

  $children = element_children($element);

  if (is_array($children)) {
    foreach ($children as $child) {
      _ajax_multiselect_search_children($form, $element[$child]);
    }
  }
}

Когда я нахожу элемент "множественный выбор", я добавляю новый элемент "выбор" в форму со свойством #ajax, скопированным с исходного "множественного выбора".

/*
 * Modify the multiselect for ajax processing
 */
function _ajax_multiselect_modify_multiselect(&$form, &$element) {

  $element['#attached']['js'] = array(
    array(
      'data' => drupal_get_path('module', 'ajax_multiselect') . '/js/ajax_multiselect.js',
    ),
  );


  if (isset($element['#ajax'])) {

    $ajax_element_id = drupal_html_id('ajax_multiselect_element');

    // tell jquery where to find the id of the dummy select
    $element['#attributes']['class'][] = 'multiselect-element-id-holder';
    // transmit the id of the dummy select to jquery
    $element['#attributes']['data-ajax-multiselect-element-id'] = $ajax_element_id;

    $form[$ajax_element_id] = array(

      '#id' => $ajax_element_id,
      '#type' => 'select',
      '#ajax' => $element['#ajax'],
      '#options' => array(0,1),

//      '#prefix' => '<div style="display:none">',
//      '#suffix' => '</div>',
    );

  }

}

Затем в Javascript я запускаю событие "изменение" для нового (фиктивного) "выбора" всякий раз, когда изменяются элементы в "множественном выборе".

  // create a new function that incorporates the old function to add/remove options in multiselect
  $.fn.oldAddOption = $.fn.addOption;
  $.fn.addOption = function(arguments) {
    this.oldAddOption(arguments);

    // find the tag that holds the id of the ajax multiselect element
    var tag_with_id = $(this).parent().parent().find('.multiselect-element-id-holder');
    // find the id of the ajax multiselect element
    var ajax_element_id = tag_with_id.data('ajax-multiselect-element-id');

    $('#'+ajax_element_id).trigger('change');
  }

Это работает для первого #ajax туда и обратно, но после первого вызова #ajax в любом месте страницы мои новые (фиктивные) элементы "выбрать" не запускают правильный #ajax. В моих последних журналах Drupal я получаю

Undefined index: #ajax in ajax_form_callback() 

Когда я использую фиктивные элементы выбора.

В сетевой активности я вижу, что первый ответ #ajax включает в себя правильный набор команд для действия замены. Но после первого #ajax в любом месте формы мои новые элементы "выбрать" получают только ответ по умолчанию #настройки ajax без команд замены.

Я думаю, что есть что-то в том, как я строю в hook_form_alter, что неправильно добавляет свойство #ajax после первого вызова ajax, но я не могу понять, что это такое.

 1
Author: Joe Beuckman, 2012-07-23

1 answers

Проблема заключалась в том, что идентификаторы, созданные drupal_html_id(), совпадали после перестройки формы ajax. Я исправил это, попросив jQuery найти фиктивные элементы выбора по атрибуту "имя".

  $.fn.oldAddOption = $.fn.addOption;
  $.fn.addOption = function(arguments) {
    this.oldAddOption(arguments);

    // find the tag that holds the id of the ajax multiselect element
    var tag_with_name = $(this).parent().parent().find('.multiselect-element-name-holder');
    // find the id of the ajax multiselect element
    var ajax_element_name = tag_with_name.data('ajax-multiselect-element-name');

    $('select[name="'+ajax_element_name+'"]').trigger('change');
  }

Этот код теперь устанавливает уникальные имена элементов вместо того, чтобы пытаться установить уникальные идентификаторы:

$ajax_element_name = drupal_html_id('ajax-multiselect-element');

// tell jquery where to find the id of the dummy select
$element['#attributes']['class'][] = 'multiselect-element-name-holder';
// transmit the id of the dummy select to jquery
$element['#attributes']['data-ajax-multiselect-element-name'] = $ajax_element_name;

$form[$ajax_element_name] = array(
  '#type' => 'select',
  '#ajax' => $element['#ajax'],
  '#options' => array(0,1),
);
 1
Author: Joe Beuckman, 2012-07-24 16:55:53