У мене є модуль, який оновлює вузол через 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
функцією
(b) Додати $('body').ajaxSuccess(Drupal.attachBehaviors);
до мого javascript. ajaxComplete також спробував. Спробував це і в документі.
(c) Створіть власну команду, як детально описано тут http://www.jaypan.com/tutorial/calling-function-after-ajax-event-drupal-7
Примітка. Я знаю, що це лише питання активації attachBehaviors після кожного клацання, щоб "пришвидшити" новий 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
має бути в таймері. Я не можу просто мати його самостійно з тієї причини, яку я ігнорую.
Я залишаю це питання відкритим для мало кого, якщо хтось може знайти більш елегантне рішення та / або пояснити диваку часу.
Дуже дякую