web-dev-qa-db-fra.com

Initialisation de select2 créé dynamiquement

J'ai un menu déroulant select2 pour lequel je fournis une fonction matcher. Il est initialisé comme ceci lors du chargement initial de la page:

jQuery(document).ready(function() {
    jQuery(".my_select2").select2({
        matcher: function(term, text) {...}
    });
});

Cela fonctionne trouver sur le chargement de la page initiale.

Maintenant, j’ai des listes déroulantes supplémentaires (des éléments select créés dynamiquement (tirées via AJAX, à savoir jQuery(match).load(url).). Ces listes déroulantes supplémentaires ne deviennent pas des widgets select2.

Alors, comment puis-je dire à jQuery de traiter ces éléments select créés dynamiquement comme des éléments select2 devant être initialisés? Puis-je définir une sorte de "surveillance" sur les éléments correspondants afin que l'initialisation de select2 démarre chaque fois qu'un élément correspondant est ajouté à la page?

Je me souviens que live() avait été introduit dans jQuery il y a quelque temps, prenant en charge les éléments correspondants avant leur création, si j'ai bien compris. Je n'ai jamais utilisé cette fonctionnalité, et elle semble maintenant obsolète. Mais je sens que c'est le genre de chose que je recherche.

Ceci est pour un plugin WordPress, qui utilise actuellement jQuery v1.11.2.

16
Jason

vous pouvez essayer avec DOMNodeInserted et chercher select ou la classe que vous leur attribuez

Démo

$('body').on('DOMNodeInserted', 'select', function () {
    $(this).select2();
});

Mettre à jour

DOMNodeInserted

Obsolète Cette fonctionnalité a été supprimée des standards Web. Bien que certains navigateurs puissent toujours le prendre en charge, il est en train d’être abandonné. Évitez de l'utiliser et mettez à jour le code existant si possible;

La méthode suggérée serait quelque chose comme ceci avec MutationObserver

$(function() {
  $("button").on("click", function() {
    $("#dynamic-container").append($("<select><option>test</option><select/>"));
  });

  // select the target node
  var target = document.getElementById('dynamic-container');

  if (target) {
    // create an observer instance
    var observer = new MutationObserver(function(mutations) {
      //loop through the detected mutations(added controls)
      mutations.forEach(function(mutation) {
      //addedNodes contains all detected new controls
        if (mutation && mutation.addedNodes) {
          mutation.addedNodes.forEach(function(Elm) {
          //only apply select2 to select elements
            if (Elm && Elm.nodeName === "SELECT") {
              $(Elm).select2();
            }
          });
        }
      });
    }); 
    
    // pass in the target node, as well as the observer options
    observer.observe(target, {
      childList: true
    });

    // later, you can stop observing
    //observer.disconnect();
  }
});
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>


<button>Add new select</button>
  <div id="dynamic-container">

  </div>

22
Juan Castillo

Je suis récemment tombé sur une situation similaire, mais de manière très habituelle:

$(document).ready(function() {

 //function to initialize select2
  function initializeSelect2(selectElementObj) {
    selectElementObj.select2({
      width: "80%",
      tags: true
    });
  }


 //onload: call the above function 
  $(".select-to-select2").each(function() {
    initializeSelect2($(this));
  });

 //dynamically added selects

  $(".add-new-select").on("click", function() {
    var newSelect = $("<select class='select-to-select2'  multiple><option>option 1</option><option>option 2</option></select>");
    $(".select-container").append(newSelect);
    initializeSelect2(newSelect);
  });


});
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/css/select2.css" rel="stylesheet" />

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/js/select2.min.js"></script>
<div class="select-container">
  <select class='select-to-select2' multiple>
    <option value='1'>option1</option>
    <option value='2'>option2</option>
  </select>

  <select class='select-to-select2' multiple>
    <option value='1'>option1</option>
    <option value='2'>option2</option>
  </select>

</div>
<div>
  <button class="add-new-select">Add New Select</button>
</div>

Dans le cas de la fonction .load, recherchez tous les éléments select à initialiser dans la fonction de rappel de chargement et appelez initializeSelect2 sur chacun de ces éléments select.

J'espère que cela aide quelqu'un qui recherche une solution simple.

14
roshan

Ça marche pour moi

<div id="somediv">
    <select class="component">
    ...
    </select>
</div>



<script>
    $(document).on('click', '#addComponent', function () {

        $('#somediv').append(data); //data is my new select
        $('.component:last').select2();
    });
</script>