Wie kann ich eine Javascript-Funktion auslösen, wenn ein Drupal-Ajax-Aufruf abgeschlossen ist?


7

Ich muss einige zusätzliche Dinge tun, nachdem Drupal Ajax einige Dinge in das DOM eingefügt hat. Mit jQuery war das hirntot einfach, aber ich kann für mein ganzes Leben nicht herausfinden, wie es in Drupal 7: s geht

Füge ich meinem ajaxifizierten Link etwas hinzu? Ich habe etwas über das Anhängen eines Verhaltens gelesen ... Verwirrung setzt ein ...


3
1. Was löst den AJAX-Aufruf aus? 2. Verhalten ist der richtige Ansatz. 3. Sie sind nicht wirklich schwer;)
Amateur Barista

Antworten:


6

Am Ende habe ich der Seite, die vom Ajax-Handler zurückgegeben wird, einige Additionsbefehle hinzugefügt:

$commands = array();
$commands[] = ajax_command_invoke(NULL, 'grid_content_loading', array('argument1', 'argument2'));
$commands[] = ajax_command_append('#grid-content-target', $html);
$commands[] = ajax_command_invoke(NULL, 'grid_content_loaded', array('argument1', 'argument2'));
$page = array('#type' => 'ajax', '#commands' => $commands);
ajax_deliver($page);

Und auf der Client-Seite habe ich über jQuery 2 Javascript-Funktionen erstellt:

(function($) {
$.fn.grid_content_loading = function($argument1, $argument2) {
   ...
};

$.fn.grid_content_loaded = function($argument1, $argument2) {
   ...
};
})(jQuery);

1
Haben Sie sich Drupal.Behaviors angesehen, wie es Amateur-Barista vorgeschlagen hat?
Marcvangend

Wenn Sie beispielsweise ein verstecktes Feld mit der ID "block" aktualisieren möchten, können Sie Folgendes
Shasi Kanth

3

In meinem Projekt hatte ich bereits gut definierten JavaScript-Code geschrieben, der die Seitenstatistiken nach einem AJAX-Aufruf aktualisierte.

Da ich die Funktionen wiederverwenden wollte, ohne "jQuery zu erweitern", kam ich zu der folgenden Lösung, bei der eine vorhandene jQuery-Funktion verwendet wurde, anstatt eine neue zu definieren. Dies wurde durch die Funktionsweise des "Flags" -Moduls inspiriert - es löst einfach ein Ereignis aus und ermöglicht es vielen Javascript-Ereignis-Listenern, als Reaktion darauf zu reagieren, anstatt nur ein einziges fest codiertes, benutzerdefiniertes jQuery-Plugin / eine Erweiterung wie in der Lösung zu haben in den vorherigen Antworten untersucht.

In einem Drupal-Modul:

// in_some_ajax_function()

$commands[] = ajax_command_invoke('html', 'trigger', array('MY_EVENT'));

In Javascript:

// Added an event binding to my $(document).ready();

$(document).ready(function(){

  $(document).bind('MY_EVENT', function() {
    alert('MY_EVENT');
  });

});

Ich musste beachten, dass der erste Parameter für ajax_command_invoke NIEMALS native JavaScript-Objekte sind, daher funktioniert Folgendes nie, da es in einen Selektor 'document' (Element) übersetzt wird:

// This tries to select $('document')
// ... which is nothing, since there are no 'document' elements.

$commands[] = ajax_command_invoke('document', 'trigger', array('MY_EVENT'));

Seltsamerweise sind Binden $(document)und Auslösen $('html')kompatibel. Ich nehme an, Sie können sehr kreativ werden und spezifischere Elemente auf tieferer Ebene binden / auslösen. Wenn Sie sich ein Szenario vorstellen können, in dem dies sinnvoller ist als ein Ereignisauslöser der obersten Ebene, kommentieren Sie dies bitte!


Vielen Dank! Sie können in dieser Antwort auch ein zweites Argument neben "MY_EVENT" hinzufügen, um es an die von Ihrem Ereignis in Ihrem JS-Code ausgeführte Funktion zu übergeben. Zum Übergeben mehrerer Argumente oder Objekte können Sie json_encode verwenden. Ihr JS-Ereignis sollte 2 Argumente erhalten, Ihr erstes Argument ist das Ereignis selbst und das zweite Argument ist Ihr JSON_ENCODED-Ding. PHP: ajax_command_invoke ('html', 'trigger', ['acceptgar_qtip', json_encode (['# edit-linea-0-id-producto', 'No existe'])] JS: $ (document) .bind ( 'MY_EVENT', Funktion (Ereignis, Argumente) {}); Ich hoffe, das hilft!
Beto Aveiga

2

Ich denke, dass die beste Option die Verwendung der jQuery- ajaxCompleteFunktion ist:

(function($){ 
   $(document).ajaxComplete(function(e, xhr, settings)
   {
     alert(settings.url);
   });
}(jQuery));

Und wenn Sie die Funktion für eine bestimmte Ajax-Funktion verwenden möchten, können Sie die identifizierte settings.url für Ihr Feld verwenden und diese ändern in:

(function($) {
    $(document).ajaxComplete(function(e, xhr, settings){ 
    if (settings.url == "the path from step 1") {
        // Code to populate your fields here
    }
 });
}(jQuery));

Dies funktionierte bei mir für die Drupal 7 und 8.


1

Codebeispiel:

$commands = array();
$commands[] = array(
    'command' => 'your_js_callback', // the name of your javascript callback
    'value1'  => 'My first value',
    'value2'  => 'My second value',
);
ajax_render($commands);

JS-Code:

(function($, Drupal) {
    Drupal.ajax.prototype.commands.your_js_callback = function(ajax, response, status) {
        alert(response.value1);
        alert(response.value2);
    }
})(jQuery, Drupal);

0

Schnelle Hack-Lösung: Platzieren Sie ein Bild im geladenen Inhalt und geben Sie ihm das onload="[javascript function]()"Attribut. Sie sind sich nicht sicher, ob dies tatsächlich das ist, wonach Sie suchen ... Oder ob dies einfacher als der richtige Weg ist ... Aber vielleicht besser als nichts?


0

Ich habe eine Antwort auf diese Frage auf so gepostet

https://stackoverflow.com/a/19404566/894487

Ich bin mir nicht sicher über die wirklichen Unterschiede zwischen Erweiterung Drupal.ajax.prototype.commandsoder $.fn

Ich stelle mir vor, dass Ersteres effizienter wäre, da keine Dom-Durchquerung erforderlich ist, um Ihre Funktion zu erfüllen. Ich bin mir nicht sicher, ob das wichtig ist.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.