#элементы 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 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),
);