Exécuter Javascript quand un widget est ajouté dans le backend

19

J'ai des widgets auxquels sont associés des contrôles javascript.

Si le widget est présent lors du chargement de la page d'administration du widget, les contrôles fonctionnent correctement.

Lorsque j'ajoute un nouveau widget, ils ne fonctionnent pas correctement, je reçois le balisage, mais aucun événement javascript ne prend effet.

Si j'enregistre le nouveau widget, lors du rechargement du formulaire, les contrôles sont créés correctement et fonctionnent maintenant.

L'actualisation de la page corrige également le problème, mais uniquement pour les widgets existants. Les nouveaux widgets ont toujours ce problème.

Plus précisément, je lance la sélection de certaines entrées à ces points:

  • document prêt
  • Ajaxcomplete

J'ai vérifié que mon code est exécuté sur chaque événement comme souhaité, mais les résultats ne sont pas ceux attendus.

Voici un plugin de test illustrant le problème:

enlace

Vous verrez que j'ai un compteur qui augmente à chaque élément sélectionné qu'il trouve qu'il peut convertir.

Notes:

  • Lorsque la page du widget est chargée, je peux voir le compteur augmenter dans la console JS comme prévu
  • Lorsque j'ajoute un nouveau widget, le code est exécuté. Cependant, il ne trouve aucun élément sélectionné sur lequel il peut s'exécuter, comme indiqué par found.length étant 0. Cela ne devrait pas être le cas, car chaque nouveau widget de ce type doit avoir un élément select
  • les éléments select ont une classe pour les identifier, cette classe est supprimée une fois que la bibliothèque selectize est appliquée pour empêcher la duplication et le traitement à nouveau sur les widgets existants.
  • Avant d’utiliser selectize, j’utilisais Select2, qui posait le même problème
  • En commentant le code AJAX, je m'attendrais à ce que les nouveaux widgets aient une entrée de sélection standard. Ils ne. Je ne sais pas pourquoi c'est le cas

Alors, comment faire fonctionner le contrôle de sélection sans demander à l'utilisateur d'actualiser / cliquer sur enregistrer avant d'apporter des modifications?

    
posée Tom J Nowell 17.01.2014 - 02:02

2 réponses

11

Bonnes nouvelles,

Je l'ai corrigé.

Je vous présente mes excuses pour avoir omis votre commentaire dans mon commentaire initial et vous donne une réponse que vous avez déjà mise en œuvre. Cela m'apprendra à répondre au téléphone pendant que je suis dans un train!

Votre utilisation de ajaxstop est correcte. La plupart du temps, JS fonctionne correctement, vous pouvez voir les styles CSS en cours d’initialisation et les modifications dans le DOM.

Le problème réside en fait avec votre sélecteur.

Cela est dû au fait que le contenu du widget n'est pas chargé via ajax. En fait, il le clone dans la colonne de gauche où il est masqué, puis déclenche un appel ajax pour enregistrer la position du widget dans la colonne de droite. Cela explique pourquoi ajaxstop fonctionne comme un régal, même si le contenu pensé est cloné. Cependant, comme il existe une version cachée du widget dans la colonne de gauche, votre système de surveillance est instancié sur ce point. En tant que tel, lorsque vous le faites glisser dans la colonne de droite, vous obtenez un clone mutilé du widget masqué.

Vous devez donc sélectionner celui du côté gauche. Ci-dessous le code corrigé:

<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>
    
réponse donnée MichaelJames 17.01.2014 - 13:22
14

Comme l'a commenté @ aaron-holbrook, une approche plus propre consistera à faire:

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

Il suffit de coller ici pour référence car les réponses sont beaucoup plus faciles à trouver que les commentaires

    
réponse donnée chifliiiii 24.11.2014 - 19:50

Lire d'autres questions sur les étiquettes