web-dev-qa-db-fra.com

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 la valeur "1" lorsque le formulaire est envoyé au serveur

J'ai essayé toutes sortes de combinaisons de méthodes jQuery et Select2 data et val, appelées en fonction de différentes entrées de la page, mais rien ne semble fonctionner.

-- 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 soit d’essayer de déclencher le changement.

J'utilisais:

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

Cependant, il en résulte un objet 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 la variable newObject disponible dans l'événement change de select2 et les valeurs définies correctement.

J'espère que cette information supplémentaire aide quelqu'un d'autre!

24
caponica

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 objectif, mais elle indique également «c’est essentiellement une fonction de mappage id-> objet», et ce n’est pas ainsi que vous l’avez implémentée.

Pour une raison quelconque, l'appel à .trigger('change') provoque l'appel de la fonction initSelection, ce qui ramène 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 documentation Select2 , vous verrez qu'il est utilisé lorsque l'élément a une valeur initiale et lorsque la fonction .val() de l'élément est appelée. En effet, ces valeurs consistent uniquement en un id et Select2 a besoin de l'intégralité de l'objet 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 la fournir). Dans ce cas, la fonction initSelection devra simplement rechercher le id dans la liste de données et renvoyer l'objet de données correspondant. (Je dis ici "return", mais il ne renvoie pas vraiment l'objet 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 code HTML) et vous n'allez pas appeler sa méthode .val(). Continuez simplement à utiliser la méthode .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'objet de données.

25
John S

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("trigger", "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.

35
Mark

Pour définir les valeurs initiales, vous devez ajouter 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('<option value=someID>optionText</option>');
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

10
nespapu

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'});

Utiliseztextau lieu delabel

7
lucbonnin

à 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").trigger("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"]).trigger("change"); });
$(".js-programmatic-multi-clear").on("click", function () { $exampleMulti.val(null).trigger("change"); });
3
Valentin Petkov

Ça y est:

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

Si vous supprimez la .trigger('change') de votre violon, il enregistre 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?

1
vesse

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).trigger('change'); // Standard event notifies select2

Il existe un exemple élémentaire dans la documentation de Select2: https://select2.org/programmatic-control/add-select-clear-items } _

1
Ryan

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

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

jqueryselect2multiplesetconcaténation

1
McAndrews

Pour ceux qui utilisent encore la version 3.5 ou même supérieure. Assurez-vous que vous faites référence à select2.js à votre page. Si vous utilisez asynchrone ou différez la charge. Ce plug-in peut se comporter différemment.

Pensé pour mentionner.

0
MonkeyDLuffy

POUR LA VERSION 3.5.3

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

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

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

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.

0
Del Eraser