Mam moduł, który aktualizuje węzeł za pośrednictwem ajax po kliknięciu łącza.
Link jest przełącznikiem, powinien zaktualizować węzeł o wartości 1 przy pierwszym kliknięciu, a następnie o wartości 0 przy kolejnym kliknięciu itp. Jak włączanie / wyłączanie czegoś.
Poniższy kod działa przy pierwszym kliknięciu po załadowaniu strony, ale nie przy kolejnych kliknięciach. Uważam, że Drupal.attachBehaviors należy wywoływać / uruchamiać po każdym kliknięciu, ale nie mogę wymyślić, jak to zrobić.
Moduł
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);
Co próbowałem do tej pory:
(a) Dodaj an ajax_command_invoke(NULL, 'mymodule');
do tablicy $ ajax_commands w połączeniu z $.fn.mymodule
funkcją
(b) Dodaj $('body').ajaxSuccess(Drupal.attachBehaviors);
do mojego javascript. ajaxComplete również próbował. Wypróbowałem to również w dokumencie.
(c) Utwórz niestandardowe polecenie, jak opisano tutaj http://www.jaypan.com/tutorial/calling-function-after-ajax-event-drupal-7
Uwaga: Wiem, że to tylko kwestia uruchomienia attachBehaviors po każdym kliknięciu, aby „ajaxify” nowy plik HTML został wstawiony / zmodyfikowany. Jeśli kliknę łącze, a następnie napiszę Drupal.attachBehaviors () w konsoli, łącze zostanie ponownie przetworzone przez mój skrypt javascript, o czym świadczy dodanie klasy „middone”, i można ponownie kliknąć.
Uwaga: Interesujące jest również to, że jeśli pozostawię $ajax_commands
puste i zwrócę je (pusta tablica) na końcu funkcji wywołania zwrotnego, link pozostanie klikalny przy pierwszym i kolejnych kliknięciach. Będzie miał funkcjonalność, której szukam (przełącznik). Ponieważ jednak po każdym kliknięciu html nie jest zmieniany, użytkownik nie może wiedzieć, czy przełącznik jest włączony, czy wyłączony.
Wszelkie wskazówki będą mile widziane.
================================================== =====
Częściowa odpowiedź:
Funkcja sukcesu Drupal ajax.js ponownie dołącza zachowania tylko dla formularzy (myślę?)
if (this.form) {
var settings = this.settings || Drupal.settings;
Drupal.attachBehaviors(this.form, settings);
}
więc postanowiłem zhakować wszystkie funkcje powodzenia moich obiektów ajax.
JavaScript staje się teraz
(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);
Funkcja sukcesu jest wklejaniem domyślnej kopii z ajax.js z dodaną linią do ponownego przyłączania zachowań. Z jakiegoś powodu Drupal.attachBehaviors
musi być w czasie. Nie mogę mieć tego samego z powodu, który ignoruję.
Pozostawię to pytanie otwarte dla nielicznych, na wypadek, gdyby ktoś mógł znaleźć bardziej eleganckie rozwiązanie i / lub wyjaśnić dziwność timera.
Wielkie dzięki
źródło
Odpowiedzi:
Dołączanie zachowań ajax do treści zwracanych z samego żądania ajax może być trudne. Jest to jednak możliwe.
Chociaż fragment kodu hook_menu wygląda na niekompletny, przy założeniu, że jest poprawny (zwraca $ items i funkcja jest zamknięta) - W twoim przypadku może być konieczne dostosowanie wywołania zwrotnego dostawy do „ajax_deliver”
to znaczy:
źródło
Po pewnym debugowaniu zdałem sobie sprawę, że problem nie dotyczy mojego kodu.
Problem dotyczył innego modułu, w moim przypadku modułu colorbox, który był źródłem błędu js w jego własnej funkcji zachowania. Uważam, że błąd spowodował zatrzymanie procesu dołączania zachowań i dlatego moja własna funkcja zachowań nie przywróciła się. Błąd można zobaczyć w konsoli.
Błąd colorbox: w 7.24
i w 7.25
Moim rozwiązaniem było wyłączenie modułu colorbox.
Dziękujemy wszystkim, którzy pomogli.
źródło
Nie mogę skomentować pierwszej odpowiedzi , ale możesz ustawić właściwość dla colorbox w ustawieniach. Na przykład:
źródło