Modifier la valeur sélectionnée d'une liste déroulante avec jQuery

840

J'ai une liste déroulante avec des valeurs connues. Ce que j'essaie de faire, c'est de définir la liste déroulante sur une valeur particulière que je sais exister à l'aide de jQuery . En utilisant du JavaScript normal , je ferais quelque chose comme:

ddl = document.getElementById("ID of element goes here");
ddl.value = 2; // 2 being the value I want to set it too.

Cependant, je dois le faire avec jQuery , car j'utilise une classe CSS pour mon sélecteur ( ids de client ASP.NET stupides ...).

Voici quelques choses que j'ai essayées:

$("._statusDDL").val(2); // Doesn't find 2 as a value.
$("._statusDDL").children("option").val(2) // Also failed.

Comment puis-je le faire avec jQuery ?


Mise à jour

Donc, en fin de compte, je l'ai bien fait la première fois avec:

$("._statusDDL").val(2);

Lorsque je mets une alerte juste au-dessus, cela fonctionne bien, mais lorsque je supprime l'alerte et la laisse s'exécuter à pleine vitesse, j'obtiens l'erreur

Impossible de définir la propriété sélectionnée. Index non valide

Je ne sais pas si c'est un bogue avec jQuery ou Internet Explorer 6 (je suppose Internet Explorer 6 ), mais c'est terriblement ennuyeux.

phairoh
la source
21
Le problème ici a fini par être un problème avec IE6. Je créais de nouveaux éléments d'option pour l'élément de sélection, puis j'essayais de définir la valeur sur l'un de ces éléments d'option nouvellement créés. IE6 n'attend pas correctement qu'il ait récupéré le contrôle d'un script pour créer réellement les nouveaux éléments dans le DOM si efficacement que j'essayais de définir les listes déroulantes sur des options qui n'existaient pas encore, même si elles auraient dû.
phairoh
vous pouvez utiliser du javascript purdd1 = document.getElementsByClassName('classname here'); dd1.value = 2;
user2144406

Réponses:

1008

La documentation de jQuery indique:

[jQuery.val] vérifie ou sélectionne tous les boutons radio, cases à cocher et sélectionne les options correspondant à l'ensemble de valeurs.

Ce comportement est dans les jQueryversions 1.2et au-dessus.

Vous le souhaitez très probablement:

$("._statusDDL").val('2');
strager
la source
22
Est-ce que cela fonctionne si le selectest caché ( display: none;)? Je n'arrive pas à faire fonctionner correctement ...
Padel
11
Cela m'a sauvé d'écrire des trucs comme $('._statusDDL [value="2"]').attr('selected',true);Merci!
Basil
6
@Nordes, ce serait le cas si vous obteniez la valeur sélectionnée. Dans ce cas, il définit la valeur sélectionnée ou, plus précisément, définit l'option sélectionnée.
Jon P
107
@JL: Vous devez ajouter .change()pour voir l'option dans la liste déroulante frontend, c'est$('#myID').val(3).change();
Kai Noack
10
Le chaînage du .change () doit être ajouté à la réponse. Je pensais que je devenais fou avec cette solution qui ne fonctionnait pas jusqu'à ce que je lise les commentaires.
David Baucum
139

Avec un champ caché, vous devez utiliser comme ceci:

$("._statusDDL").val(2);
$("._statusDDL").change();

ou

$("._statusDDL").val(2).change();
Aivar Luist
la source
Pourriez-vous expliquer pourquoi vous devez déclencher un événement de modification pour les champs masqués?
Samuel
1
@Samuel: parce que si vous modifiez l'option sélectionnée d'une sélection avec jQuery, la modification n'est pas déclenchée, donc un déclencheur manuel est requis.
machineaddict
2
Si vous avez besoin d'un incendie d'événement de modification après avoir modifié la valeur de la zone de dépôt, vous devez appeler la fonction de modification après avoir défini la valeur.
tver3305
J'avais spécifiquement besoin que l'événement de changement se déclenche, cela m'a donc été très utile
Rohan
32

Juste un FYI, vous n'avez pas besoin d'utiliser des classes CSS pour accomplir cela.

Vous pouvez écrire la ligne de code suivante pour obtenir le nom de contrôle correct sur le client:

$("#<%= statusDDL.ClientID %>").val("2");

ASP.NET restituera correctement l'ID de contrôle dans jQuery.

y0mbo
la source
8
Cela ne fonctionne que lorsque votre javascript est à l'intérieur du balisage .aspx ou .ascx et non lorsqu'il se trouve dans le fichier .js comme c'était le cas ici. En outre, en fonction de la profondeur de vos contrôles imbriqués dans votre application (dans mon cas, ils étaient d'environ 10 niveaux), le ClientID peut devenir incroyablement long et peut en fait ajouter un gonflement significatif à la taille de votre javascript s'il est utilisé trop généreusement. J'essaie de garder mon balisage aussi petit que possible, si je le peux.
phairoh
2
@ y0mbo Mais même si vous passez à MVC, vous devez toujours utiliser des fichiers .JS externes pour votre JavaScript afin que les navigateurs et les serveurs proxy puissent le mettre en cache pour les performances.
7wp
1
@Roberto - mais MVC n'utilise pas les conventions de dénomination stupides que les formulaires Web asp.net vous permettent de référencer confortablement dans un fichier js externe aux contrôles dont vous avez besoin.
lloydphillips
6
Si vous créez du javascript de style OO, vous pouvez transmettre vos identifiants client au constructeur de votre objet. Le code objet est tout contenu dans un fichier js externe, mais vous l'instanciez à partir de votre code aspx.
mikesigs
1
Je préfère définir ClientIDMode = "Static" sur les contrôles asp afin que vous sachiez que l'ID sera l'ID que vous avez spécifié. Vous devez être prudent si vous mettez ensuite ce contrôle dans un répéteur. msdn.microsoft.com/en-us/library/…
Shawson
25

Essayez avec

$("._statusDDL").val("2");

et pas avec

$("._statusDDL").val(2);
emas
la source
23

Ces solutions semblent supposer que chaque élément de vos listes déroulantes a une valeur val () relative à leur position dans la liste déroulante.

Les choses sont un peu plus compliquées si ce n'est pas le cas.

Pour lire l'index sélectionné d'une liste déroulante, vous utiliseriez ceci:

$("#dropDownList").prop("selectedIndex");

Pour définir l'index sélectionné d'une liste déroulante, vous utiliseriez ceci:

$("#dropDownList").prop("selectedIndex", 1);

Notez que la fonctionnalité prop () nécessite JQuery v1.6 ou ultérieure.

Voyons comment vous utiliseriez ces deux fonctions.

Supposons que vous disposiez d'une liste déroulante de noms de mois.

<select id="listOfMonths">
  <option id="JAN">January</option>
  <option id="FEB">February</option>
  <option id="MAR">March</option>
</select>

Vous pouvez ajouter un bouton "Mois précédent" et "Mois suivant", qui examine l'élément de liste déroulante actuellement sélectionné et le remplace par le mois précédent / suivant:

<button id="btnPrevMonth" title="Prev" onclick="btnPrevMonth_Click();return false;" />
<button id="btnNextMonth" title="Next" onclick="btnNextMonth_Click();return false;" />

Et voici le JavaScript que ces boutons exécuteraient:

function btnPrevMonth_Click() {
    var selectedIndex = $("#listOfMonths").prop("selectedIndex");
    if (selectedIndex > 0) {
        $("#listOfMonths").prop("selectedIndex", selectedIndex - 1);
    }
}
function btnNextMonth_Click() {
    //  Note:  the JQuery "prop" function requires JQuery v1.6 or later
    var selectedIndex = $("#listOfMonths").prop("selectedIndex");
    var itemsInDropDownList = $("#listOfMonths option").length;

    //  If we're not already selecting the last item in the drop down list, then increment the SelectedIndex
    if (selectedIndex < (itemsInDropDownList - 1)) {
        $("#listOfMonths").prop("selectedIndex", selectedIndex + 1);
    }
}

Le site suivant est également utile pour montrer comment remplir une liste déroulante avec des données JSON:

http://mikesknowledgebase.com/pages/Services/WebServices-Page8.htm

Phew !!

J'espère que cela t'aides.

Mike Gledhill
la source
20

Après avoir examiné certaines solutions, cela a fonctionné pour moi.

J'ai une liste déroulante avec quelques valeurs et je veux sélectionner la même valeur dans une autre liste déroulante ... Alors d'abord, je mets dans une variable la selectIndexde ma première liste déroulante.

var indiceDatos = $('#myidddl')[0].selectedIndex;

Ensuite, je sélectionne cet index dans ma deuxième liste déroulante.

$('#myidddl2')[0].selectedIndex = indiceDatos;

Remarque:

Je suppose que c'est la solution la plus courte, fiable, générale et élégante.

Parce que dans mon cas, j'utilise l'attribut de données de l'option sélectionnée au lieu de l'attribut de valeur. Donc, si vous n'avez pas de valeur unique pour chaque option, la méthode ci-dessus est la plus courte et la plus douce !!

ISIK
la source
5
C'est la bonne réponse, et tous ceux qui n'ont pas dit «selectedIndex» instantanément, devraient le savoir. Vive l'API DOM et les personnes qui l'ont écrite à l'âge de pierre.
vsync
16

Je sais que c'est une vieille question et les solutions ci-dessus fonctionnent bien, sauf dans certains cas.

Comme

<select id="select_selector">
<option value="1">Item1</option>
<option value="2">Item2</option>
<option value="3">Item3</option>
<option value="4" selected="selected">Item4</option>
<option value="5">Item5</option>
</select>

Donc, l'élément 4 apparaîtra comme "Sélectionné" dans le navigateur et maintenant vous voulez changer la valeur comme 3 et afficher "Article3" comme sélectionné au lieu de Item4. Donc, selon les solutions ci-dessus, si vous utilisez

jQuery("#select_selector").val(3);

Vous verrez cet élément 3 comme sélectionné dans le navigateur. Mais lorsque vous traitez les données soit en php soit en asp, vous trouverez la valeur sélectionnée comme "4". La raison en est que votre html ressemblera à ceci.

<select id="select_selector">
<option value="1">Item1</option>
<option value="2">Item2</option>
<option value="3" selected="selected">Item3</option>
<option value="4" selected="selected">Item4</option>
<option value="5">Item5</option>
</select>

et il obtient la dernière valeur comme "4" dans la langue côté serveur.

DONC MA SOLUTION FINALE SUR CE REGARD

newselectedIndex = 3;
jQuery("#select_selector option:selected").removeAttr("selected");
jQuery("#select_selector option[value='"+newselectedIndex +"']").attr('selected', 'selected');  

EDIT : Ajoutez un guillemet simple autour de "+ newselectedIndex +" afin que la même fonctionnalité puisse être utilisée pour les valeurs non numériques.

Donc, ce que je fais est en fait, supprimé l'attribut sélectionné, puis faites le nouveau comme sélectionné.

J'apprécierais les commentaires à ce sujet de programmeurs seniors comme @strager, @ y0mbo, @ISIK et d'autres

Rocker Maruf
la source
10

Si nous avons une liste déroulante avec un titre de "Classification des données":

<select title="Data Classification">
    <option value="Top Secret">Top Secret</option>
    <option value="Secret">Secret</option>
    <option value="Confidential">Confidential</option>
</select>

Nous pouvons le mettre dans une variable:

var dataClsField = $('select[title="Data Classification"]');

Ensuite, mettez dans une autre variable la valeur que nous voulons que la liste déroulante ait:

var myValue = "Top Secret";  // this would have been "2" in your example

Ensuite, nous pouvons utiliser le champ que nous avons mis dataClsField, faire une recherche myValueet le sélectionner en utilisant .prop():

dataClsField.find('option[value="'+ myValue +'"]').prop('selected', 'selected');

Ou, vous pouvez simplement utiliser .val(), mais votre sélecteur de .ne peut être utilisé que s'il correspond à une classe dans la liste déroulante, et vous devez utiliser des guillemets sur la valeur entre parenthèses, ou simplement utiliser la variable que nous avons définie précédemment:

dataClsField.val(myValue);
vapcguy
la source
4

Je l'ai donc changé pour que maintenant il s'exécute après 300 millisecondes en utilisant setTimeout. Semble fonctionner maintenant.

J'ai rencontré cela plusieurs fois lors du chargement de données à partir d'un appel Ajax. Moi aussi, j'utilise .NET, et il faut du temps pour s'adapter au clientId lors de l'utilisation du sélecteur jQuery. Pour corriger le problème que vous rencontrez et éviter d'avoir à ajouter une setTimeoutpropriété, vous pouvez simplement mettre " async: false" dans l'appel Ajax, et cela donnera au DOM suffisamment de temps pour récupérer les objets que vous ajoutez à la sélection. Un petit échantillon ci-dessous:

$.ajax({
    type: "POST",
    url: document.URL + '/PageList',
    data: "{}",
    async: false,
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function (response) {
        var pages = (typeof response.d) == 'string' ? eval('(' + response.d + ')') : response.d;

        $('#locPage' + locId).find('option').remove();

        $.each(pages, function () {
            $('#locPage' + locId).append(
                $('<option></option>').val(this.PageId).html(this.Name)
            );
        });
    }
});
dans le sens horaireq
la source
3

Juste une note - j'ai utilisé des sélecteurs génériques dans jQuery pour récupérer des éléments obscurcis par les ID clients ASP.NET - cela pourrait vous aider aussi:

<asp:DropDownList id="MyDropDown" runat="server" />

$("[id* = 'MyDropDown']").append("<option value='-1'>&nbsp;</option>"); //etc

Notez le caractère générique id * - cela trouvera votre élément même si le nom est "ctl00 $ ctl00 $ ContentPlaceHolder1 $ ContentPlaceHolder1 $ MyDropDown"

AVH
la source
3

J'utilise une fonction d'extension pour obtenir les identifiants des clients, comme ceci:

$.extend({
    clientID: function(id) {
        return $("[id$='" + id + "']");
    }
});

Ensuite, vous pouvez appeler des contrôles ASP.NET dans jQuery comme ceci:

$.clientID("_statusDDL")
jonofan
la source
3

Une autre option consiste à définir le paramètre de contrôle ClientID = "Static" dans .net, puis vous pouvez accéder à l'objet dans JQuery par l'ID que vous définissez.

Mych
la source
3
<asp:DropDownList id="MyDropDown" runat="server" />

Utilisez $("select[name$='MyDropDown']").val().

Monty
la source
Si vous correspondez au nom, vous pouvez aussi bien supprimer le $afin qu'il s'agisse d'une correspondance complète, et non pas de «se terminant par». Mais votre suggestion est probablement plus rapide que de faire correspondre uniquement un nom de classe. Encore plus rapide serait element.classnameou #idname.
Alec
2

Comment chargez-vous les valeurs dans la liste déroulante ou déterminez-vous la valeur à sélectionner? Si vous faites cela en utilisant Ajax, la raison pour laquelle vous avez besoin du délai avant que la sélection ne se produise pourrait être parce que les valeurs n'ont pas été chargées au moment de l'exécution de la ligne en question. Cela expliquerait également pourquoi cela a fonctionné lorsque vous avez mis une instruction d'alerte sur la ligne avant de définir l'état, car l'action d'alerte donnerait suffisamment de retard pour le chargement des données.

Si vous utilisez l'une des méthodes Ajax de jQuery, vous pouvez spécifier une fonction de rappel, puis la mettre $("._statusDDL").val(2);dans votre fonction de rappel.

Ce serait un moyen plus fiable de gérer le problème, car vous pouvez être sûr que la méthode s'exécute lorsque les données sont prêtes, même si cela prend plus de 300 ms.

Pervez Choudhury
la source
2
<asp:DropDownList ID="DropUserType" ClientIDMode="Static" runat="server">
     <asp:ListItem Value="1" Text="aaa"></asp:ListItem>
     <asp:ListItem Value="2" Text="bbb"></asp:ListItem>
</asp:DropDownList>

ClientIDMode = "Static"

$('#DropUserType').val('1');
hamze shoae
la source
1

Dans mon cas, j'ai pu le faire fonctionner en utilisant la méthode .attr ().

$("._statusDDL").attr("selected", "");
Colin
la source