Ich habe ein Modul, das einen Knoten über Ajax aktualisiert, wenn auf einen Link geklickt wird.
Der Link ist ein Umschalter. Er sollte den Knoten beim ersten Klicken mit dem Wert 1 und beim nächsten Klicken mit dem Wert 0 aktualisieren. Zum Beispiel, wenn Sie etwas ein- oder ausschalten.
Der folgende Code funktioniert beim ersten Klicken nach dem Laden der Seite, jedoch nicht bei nachfolgenden Klicks. Ich glaube, Drupal.attachBehaviors muss nach jedem Klick aufgerufen / ausgelöst werden, aber ich kann nicht herausfinden, wie das geht.
Das Modul
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);
Was ich bisher versucht habe:
(a) Fügen ajax_command_invoke(NULL, 'mymodule');
Sie dem Array $ ajax_commands ein hinzu , das mit einer $.fn.mymodule
Funktion gekoppelt ist
(b) $('body').ajaxSuccess(Drupal.attachBehaviors);
Zu meinem Javascript hinzufügen. ajaxComplete hat es ebenfalls versucht. Versuchte es auch auf dem Dokument.
(c) Erstellen Sie einen benutzerdefinierten Befehl, wie hier beschrieben. http://www.jaypan.com/tutorial/calling-function-after-ajax-event-drupal-7
Hinweis: Ich weiß, dass es nur darum geht, attachBehaviors nach jedem Klick auszulösen, um das neue HTML, das eingefügt / geändert wird, zu "ajaxifizieren". Wenn ich auf den Link klicke und dann Drupal.attachBehaviors () in die Konsole eingebe, wird der Link von meinem Javascript erneut verarbeitet, was durch das Hinzufügen der Klasse 'middone' belegt wird, und kann erneut angeklickt werden.
Hinweis: Interessant ist auch, dass $ajax_commands
der Link beim ersten und den folgenden Klicks anklickbar bleibt , wenn ich das Feld leer lasse und es (leeres Array) am Ende der Rückruffunktion zurückgebe. Es wird die Funktionalität haben, die ich suche (ein Umschalter). Da jedoch nach jedem Klick keine Änderungen am HTML vorgenommen werden, kann der Benutzer nicht feststellen, ob der Schalter ein- oder ausgeschaltet ist.
Alle Hinweise wäre sehr dankbar.
================================================== =====
Eine teilweise Antwort:
Die Erfolgsfunktion von Drupal ajax.j fügt nur Verhaltensweisen für Formulare wieder hinzu (glaube ich?)
if (this.form) {
var settings = this.settings || Drupal.settings;
Drupal.attachBehaviors(this.form, settings);
}
Deshalb habe ich beschlossen, alle Erfolgsfunktionen meiner Ajax-Objekte zu hacken.
Das Javascript wird jetzt
(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);
Die Erfolgsfunktion ist ein Kopieren und Einfügen der Standardeinstellung aus ajax.js mit einer zusätzlichen Zeile für das erneute Anhängen von Verhalten. Aus irgendeinem Grund Drupal.attachBehaviors
muss innerhalb eines Timers sein. Ich kann es aus einem Grund, den ich ignoriere, nicht einfach alleine haben.
Ich werde diese Frage für einige offen lassen, falls jemand entweder eine elegantere Lösung finden und / oder die Seltsamkeit des Timers erklären kann.
Danke vielmals