Définir par programme la valeur d’un Select2 ajax

Je possède une entrée de saisie semi-automatique Select2 (construite via SonataAdmin), mais je ne peux pas comprendre comment la définir par programme pour une paire clé / valeur connue.

Il y a un JS Fiddle ici qui montre à peu près ce que j’ai. Ce que je veux savoir, c’est quelle fonction je peux attacher au bouton pour que

  • le champ Select2 indique le texte “NOUVELLE VALEUR” à l’utilisateur, et
  • le champ Select2 soumettra une valeur de “1” lorsque le formulaire est envoyé au serveur

J’ai essayé toutes sortes de combinaisons de méthodes de data et de méthodes jQuery et Select2, appelées en fonction de différentes entrées de la page, mais rien ne semble fonctionner … il y a sûrement un moyen de le faire?

— Modifier —

La réponse acceptée ci-dessous est très utile, elle permet de mieux comprendre la bonne façon d’initialiser la sélection et d’expliquer l’initiative initSelection.

Cela dit, il semble que ma plus grande erreur ici ait été d’essayer de déclencher le changement.

J’utilisais:

 $(element).select2('data', newObject).sortinggger('change'); 

Mais cela se traduit par un object add vide dans l’événement change de select2.

Si vous utilisez plutôt:

 $(element).select2('data', newObject, true); 

alors le code fonctionne comme il se doit, avec newObject disponible dans l’événement change de select2 et les valeurs étant correctement définies.

J’espère que cette information supplémentaire aidera quelqu’un d’autre!

Remarque: la question et cette réponse concernent Select2 v3. Select2 v4 a une API très différente de la v3.

Je pense que le problème est la fonction initSelection . Utilisez-vous cette fonction pour définir la valeur initiale? Je sais que la documentation de Select2 donne l’impression que c’est son objective, mais elle indique également «c’est essentiellement une fonction de mappage id-> object», et ce n’est pas ainsi que vous l’avez implémentée.

Pour une raison quelconque, l’appel à .sortinggger('change') provoque l’ initSelection fonction initSelection , qui remet la valeur sélectionnée à “ENABLED_FROM_JS”.

Essayez de vous débarrasser de la fonction initSelection et définissez plutôt la valeur initiale à l’aide de:

 autocompleteInput.select2('data', {id:103, label:'ENABLED_FROM_JS'}); 

jsfiddle

Remarque: L’OP a fourni les options formatResult et formatSelection . A la livraison, ces fonctions de rappel supposent que les éléments possèdent une propriété “label” plutôt qu’une propriété “text”. Pour la plupart des utilisateurs, cela devrait être:

 autocompleteInput.select2('data', {id:103, text:'ENABLED_FROM_JS'}); 

Plus d’informations sur la fonction initSelection :

Si vous recherchez “initSelection” dans la documentation de Select2, vous verrez qu’il est utilisé lorsque l’élément a une valeur initiale et lorsque la fonction .val() l’élément est appelée. Cela est dû au fait que ces valeurs consistent uniquement en un id et que Select2 requirejs l’intégralité de l’object de données (en partie pour pouvoir afficher l’étiquette correcte).

Si le contrôle Select2 affichait une liste statique, la fonction initSelection serait facile à écrire (et il semble que Select2 pourrait vous le fournir). Dans ce cas, la fonction initSelection devra simplement rechercher l’ id dans la liste de données et renvoyer l’object de données correspondant. (Je dis “return” ici, mais il ne renvoie pas vraiment l’object de données; il le transmet à une fonction de rappel.)

Dans votre cas, vous n’avez probablement pas besoin de fournir la fonction initSelection car votre élément n’a pas de valeur initiale (dans le .val() HTML) et vous n’allez pas appeler sa méthode .val() . Continuez simplement à utiliser la .select2('data', ...) pour définir les valeurs par programmation.

Si vous deviez fournir une fonction initSelection pour une saisie semi-automatique (qui utilise ajax), vous devrez probablement effectuer un appel ajax pour générer l’object de données.

Notez que ceci a été testé avec la version 4+

J’ai finalement pu progresser après avoir trouvé cette discussion: https://groups.google.com/forum/#!topic/select2/TOh3T0yqYr4

Le dernier commentaire note une méthode que j’ai pu utiliser avec succès.

Exemple:

 $("#selectelement").select2("sortinggger", "select", { data: { id: "5" } }); 

Cela semble être suffisamment d’informations pour qu’il corresponde aux données ajax et définisse la valeur correctement. Cela a énormément aidé avec les adaptateurs de données personnalisés.

Pour définir les valeurs initiales, vous devez append la balise d’options nécessaire à l’élément select avec jQuery, puis définir ces options comme sélectionnées avec la méthode val de select2 et enfin déclencher l’événement ‘change’ de select2.

 1.-$('#selectElement').append(''); 2.-$('#selectElement').select2('val', someID, true); 

Le troisième argument booléen indique à select2 de déclencher l’événement change.

Pour plus d’informations, voir https://github.com/select2/select2/issues/3057

Attention, il y a une erreur dans le commentaire “validé”.

 autocompleteInput.select2('data', {id:103, label:'ENABLED_FROM_JS'}); 

La bonne façon est

 autocompleteInput.select2('data', {id:103, text:'ENABLED_FROM_JS'}); 

Utiliser du text place de l’ label

à partir de leurs exemples https://select2.github.io/examples.html

Accès programmatique:

 var $example = $(".js-example-programmatic").select2(); var $exampleMulti = $(".js-example-programmatic-multi").select2(); $(".js-programmatic-set-val").on("click", function () { $example.val("CA").sortinggger("change"); }); $(".js-programmatic-open").on("click", function () { $example.select2("open"); }); $(".js-programmatic-close").on("click", function () { $example.select2("close"); }); $(".js-programmatic-init").on("click", function () { $example.select2(); }); $(".js-programmatic-destroy").on("click", function () { $example.select2("destroy"); }); $(".js-programmatic-multi-set-val").on("click", function () { $exampleMulti.val(["CA", "AL"]).sortinggger("change"); }); $(".js-programmatic-multi-clear").on("click", function () { $exampleMulti.val(null).sortinggger("change"); }); 

Si vous supprimez le .sortinggger('change') de votre violon, il enregistre l’ Object {id: 1, label: "NEW VALUE"} (vous devez cliquer deux fois car la journalisation est antérieure à la modification de valeur). Est-ce ce que vous cherchez?

Lorsque vous utilisez select2 avec plusieurs options, utilisez cette construction:

 $(element).select2("data", $(element).select2("data").concat(newObject), true); 

jquery select2 concaténation en plusieurs jeux

Ça y est:

 $("#tag").select2('data', { id:8, title: "Hello!"}); 

Avec Select2 version 4+, vous n’avez rien de spécial à faire. JQuery standard avec un déclencheur d’événement ‘change’ à la fin fonctionnera.

 var $select = $("#field"); var items = {id: 1, text: "Name"}; // From AJAX etc var data = $select.val() || []; // If you want to merge with existing $(items).each(function () { if(!$select.find("option[value='" + this.id + "']").length) { $select.append(new Option(this.text, this.id, true, true)); } data.push(this.id); }); $select.val(data).sortinggger('change'); // Standard event notifies select2 

Il existe un exemple de base dans la documentation de Select2: https://select2.org/programmatic-control/add-select-clear-items

POUR LA VERSION 3.5.3

  $(".select2").select2('data',{id:taskid,text:taskname}).sortinggger('change'); 

Basé sur la réponse de John S. Ce qui précède ne fonctionnera cependant que si, lors de l’initialisation de select2, l’option initSelection n’est pas initialisée.

 $(".select2").select2({ //some setup }) 

Tout ce que vous avez à faire est de définir la valeur, puis d’exécuter: $ ('#myselect').select2 (); ou $ ('select').select2 (); . Et tout est très bien mis à jour.