it-swarm.com.de

Ausführen von Javascript, wenn ein Widget im Backend hinzugefügt wird

Ich habe Widgets, an die Javascript-Steuerelemente angehängt sind.

Wenn das Widget beim Laden der Widget-Verwaltungsseite vorhanden ist, funktionieren die Steuerelemente ordnungsgemäß.

Wenn ich ein neues Widget hinzufüge, funktionieren diese nicht richtig. Ich erhalte das Markup, aber es werden keine JavaScript-Ereignisse wirksam.

Wenn ich das neue Widget speichere, werden die Steuerelemente beim erneuten Laden des Formulars korrekt erstellt und funktionieren jetzt.

Das Aktualisieren der Seite behebt das Problem ebenfalls, jedoch nur für vorhandene Widgets. Neue Widgets haben dieses Problem immer noch.

Insbesondere führe ich an folgenden Punkten selectize auf ausgewählten Eingängen aus:

  • dokument bereit
  • Ajaxcomplete

Ich habe überprüft, ob mein Code bei jedem Ereignis wie gewünscht ausgeführt wird, aber die Ergebnisse sind nicht wie erwartet.

Hier ist ein Test-Plugin, das das Problem demonstriert:

https://Gist.github.com/Tarendai/8466299

Sie werden sehen, dass ich einen Zähler habe, der sich mit jedem ausgewählten Element erhöht, das konvertiert werden kann.

Anmerkungen:

  • Wenn die Widget-Seite geladen wird, wird der Zähler in der JS-Konsole wie erwartet erhöht
  • Wenn ich ein neues Widget hinzufüge, wird der Code ausgeführt, es werden jedoch keine ausgewählten Elemente gefunden, auf denen er ausgeführt werden kann. Dies wird dadurch demonstriert, dass found.length 0 ist. Dies sollte nicht der Fall sein, wie dies bei jedem neuen Widget dieses Typs der Fall sein sollte habe ein ausgewähltes Element
  • select-Elemente haben eine Klasse, um sie zu identifizieren. Diese Klasse wird entfernt, sobald die Selectize-Bibliothek angewendet wird, um das Duplizieren und die erneute Verarbeitung auf vorhandenen Widgets zu verhindern.
  • Vor der Verwendung von selectize habe ich Select2 verwendet, das das gleiche Problem hatte
  • Wenn ich den AJAX -Code auskommentiere, würde ich erwarten, dass neue Widgets eine Standardauswahleingabe haben. Sie nicht. Ich weiß nicht, warum das so ist

Wie kann ich das Steuerelement selectize aktivieren, ohne den Benutzer aufzufordern, vor dem Vornehmen von Änderungen zu aktualisieren/auf Speichern zu klicken?

20
Tom J Nowell

Großartige Neuigkeiten,

Ich habe es behoben.

Entschuldigen Sie, dass Sie in meinem ersten Kommentar Ihr Gist verpasst haben und Ihnen eine Antwort gegeben haben, die Sie bereits implementiert haben. Das bringt mir bei, in einem Zug auf meinem Handy zu antworten!

Ihre Verwendung von Ajaxstop ist korrekt. Zur Hölle, der JS funktioniert größtenteils richtig. Sie konnten sehen, wie die CSS-Stile initialisiert wurden und welche Änderungen im DOM vorgenommen wurden.

Das Problem liegt in der Tat bei Ihrer Auswahl.

Dies liegt daran, dass der Widget-Inhalt nicht über Ajax geladen wird. Tatsächlich wird er aus der linken Spalte geklont, wo er ausgeblendet ist, und anschließend wird ein Ajax-Aufruf ausgelöst, um die Position des Widgets in der rechten Spalte zu speichern. Dies erklärt, warum Ajaxstop eine Wohltat ist, auch wenn Gedankeninhalte geklont werden. Da sich jedoch in der linken Spalte eine versteckte Version des Widgets befindet, wird dies von Ihrem JS instanziiert. Wenn Sie es in die rechte Spalte ziehen, erhalten Sie einen entstellten Klon des versteckten Widgets.

Daher müssen Sie die auf der linken Seite auswählen. Unten ist der korrigierte Code:

<script>
jQuery( document ).ready( function( $ ) {
    function runSelect() {
        var found = $( '#widgets-right select.testselectize' );
        found.each( function( index, value ) {

            $( value ).selectize();
                .removeClass( 'testselectize' )
                .addClass( 'run-' + window.counter );

            console.log( $val );
            window.counter++;
        } );
    }

    window.counter = 1;

    runSelect();

    $( document ).ajaxStop( function() {
        runSelect();
    } );
} );
</script>
12
MichaelJames

Wie @ aaron-holbrook kommentierte, wird ein sauberer Ansatz zu tun sein:

jQuery(document).on('widget-updated widget-added', function(){
    // your code to run
});

In vielen Fällen möchten Sie den JS auch ausführen, wenn die Seite geladen wird und wenn die Widgets aktualisiert werden. Sie können dies so tun.

function handle_widget_loading(){
   // your code to run
}
jQuery(document).ready( handle_widget_loading );
jQuery(document).on('widget-updated widget-added', handle_widget_loading );

Das Einfügen hier als Referenz, da Antworten viel einfacher sind, diese Kommentare zu finden

16
chifliiiii