У меня есть модуль, который обновляет узел через ajax при нажатии на ссылку.
Ссылка является переключателем, она должна обновлять узел со значением 1 при первом щелчке, затем со значением 0 при последующем щелчке и т. Д. Подобно включению / выключению чего-либо.
Приведенный ниже код работает при первом нажатии после загрузки страницы, но не при последующих щелчках. Я считаю, что Drupal.attachBehaviors должен вызываться / запускаться после каждого клика, но я не могу понять, как это сделать.
Модуль
function mymodule_menu() { $items['mypath/%/%/ajax'] = array( 'title' => 'My title', 'page callback' => 'mymodule_ajax_callback', 'page arguments' => array(1,2), 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); ... } function mymodule_ajax_callback($id, $status) { //Validation[...] //Node Update using $id as the nid and $status as the field value[...] // Define a new array to hold our AJAX commands. $ajax_commands = array(); // Create a new AJAX command that replaces the #div. $replacedivid = '#status'.$id; $replacestring = '<div id="status'.$id.'"><a data-url="'.base_path().'mypath/'.$id.'/'.$new_status.'/ajax" title="This item is marked as '.$status_text.'" id="statuslink'.$id.'" class="midui">'.$status_text.'</a></div>'; $ajax_commands[] = ajax_command_replace($replacedivid, $replacestring); return drupal_json_output($ajax_commands); }
Javascript
(function ($) { Drupal.behaviors.mymodule = { attach: function(context, settings) { var $uilink = $('.midui'); //find all links for (var i=0;i<$uilink.length;i++) { //Loop var $link = $('#' + $uilink[i].id); if (!$link.hasClass("middone")) { new Drupal.ajax('#' + $uilink[i].id, $link, { url: $link.attr('data-url'), effect: 'fade', settings: {}, progress: { type: 'throbber' }, event: 'click tap' }); $link.addClass("middone"); //add class when we're done } } } } })(jQuery);
Что я уже пробовал:
(a) Добавьте ajax_command_invoke(NULL, 'mymodule');
к массиву $ ajax_commands вместе с $.fn.mymodule
функцией
(б) Добавить $('body').ajaxSuccess(Drupal.attachBehaviors);
в мой JavaScript. ajaxComplete пробовал также. Пробовал это и на документе.
(c) Создайте пользовательскую команду, как описано здесь http://www.jaypan.com/tutorial/calling-function-after-ajax-event-drupal-7
Примечание: я знаю, что это просто вопрос запуска attachBehaviors после каждого щелчка, чтобы «ajaxify» новый HTML-код был вставлен / изменен. Если я щёлкну по ссылке и наберу в консоли Drupal.attachBehaviors (), ссылка будет снова обработана моим javascript, о чем свидетельствует добавление класса 'middone', и ее можно будет щелкнуть снова.
Примечание. Также интересно, если я оставлю $ajax_commands
пустое значение и верну его (пустой массив) в конце функции обратного вызова, ссылка останется активной при первом и последующих щелчках. Он будет иметь ту функциональность, которую я ищу (переключатель). Однако, поскольку после каждого щелчка в html не вносятся никакие изменения, пользователь не может узнать, включен или выключен тумблер.
Любые указатели будут с благодарностью.
================================================== =====
Частичный ответ:
Функция успеха Drupal ajax.js только повторно присоединяет поведение к формам (я думаю?)
if (this.form) {
var settings = this.settings || Drupal.settings;
Drupal.attachBehaviors(this.form, settings);
}
поэтому я решил взломать функцию успеха всех моих объектов ajax.
Javascript теперь становится
(function ($) {
Drupal.behaviors.mymodule = {
attach: function(context, settings) {
var $uilink = $('.midui'); //find all links
for (var i=0;i<$uilink.length;i++) { //Loop
var $link = $('#' + $uilink[i].id);
if (!$link.hasClass("middone")) {
myAjax = new Drupal.ajax('#' + $uilink[i].id, $link, {
url: $link.attr('data-url'),
effect: 'fade',
settings: {},
progress: {
type: 'throbber'
},
event: 'click tap'
});
myAjax.options.success = function (response, status) {
//Trigger Attach Behaviors
setTimeout(function(){Drupal.attachBehaviors($(myAjax.selector))}, 0);
// Sanity check for browser support (object expected).
// When using iFrame uploads, responses must be returned as a string.
if (typeof response == 'string') {
response = $.parseJSON(response);
}
return myAjax.success(response, status);
}
$link.addClass("middone"); //add class when we're done
}
}
}
}
})(jQuery);
Функция успеха является копией вставки по умолчанию из ajax.js с добавленной строкой для повторного присоединения поведения. По какой-то причине Drupal.attachBehaviors
должно быть в пределах таймера. Я не могу просто получить его сам по причине, которую игнорирую.
Я оставлю этот вопрос открытым для немногих на тот случай, если кто-то сможет найти более элегантное решение и / или объяснить странность таймера.
Большое спасибо
источник
Ответы:
Может быть сложно прикрепить поведение ajax к контенту, который возвращается из самого запроса ajax. Однако это возможно.
Хотя ваш фрагмент кода hook_menu выглядит неполным, при условии, что он правильный (возвращает $ items, а функция закрыта) - В вашем случае вам может просто понадобиться настроить обратный вызов доставки на «ajax_deliver»
то есть:
источник
После некоторой отладки я понял, что проблема не в моем коде.
Проблема заключалась в другом модуле, в моем случае в модуле colorbox, который был источником ошибки js в его собственной функции поведения. Я полагаю, что ошибка привела к остановке процесса прикрепленного поведения, и поэтому моя собственная функция поведения не была повторно присоединена. Ошибка видна в консоли.
Ошибка colorbox: в 7.24
и в 7.25
Моим решением было отключить модуль colorbox.
Большое спасибо всем, кто помог.
источник
Я не могу прокомментировать первый ответ , но вы можете установить свойство для colorbox в настройках. Например:
источник