Modifica il valore selezionato di un elenco a discesa con jQuery


840

Ho un elenco a discesa con valori noti. Quello che sto cercando di fare è impostare l'elenco a discesa su un valore particolare che conosco esiste usando jQuery . Usando JavaScript normale , farei qualcosa del tipo:

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

Tuttavia, devo farlo con jQuery , perché sto usando una classe CSS per il mio selettore (stupidi ID client ASP.NET ...).

Ecco alcune cose che ho provato:

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

Come posso farlo con jQuery ?


Aggiornare

Quindi, a quanto pare, ho avuto ragione la prima volta con:

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

Quando inserisco un avviso appena sopra, funziona correttamente, ma quando rimuovo l'avviso e lo lascio funzionare alla massima velocità, viene visualizzato l'errore

Impossibile impostare la proprietà selezionata. Indice non valido

Non sono sicuro che si tratti di un bug con jQuery o Internet Explorer 6 (sto indovinando Internet Explorer 6 ), ma è terribilmente fastidioso.


21
Il problema qui ha finito per essere un problema con IE6. Stavo creando nuovi elementi opzione per l'elemento select e quindi provando a impostare il valore su uno di quegli elementi opzione appena creati. IE6 attende in modo errato fino a quando non ha ottenuto il controllo da uno script per creare effettivamente i nuovi elementi nel DOM in modo così efficace che cosa stesse accadendo, stavo cercando di impostare gli elenchi a discesa su opzioni che non esistevano ancora, anche se avrebbero dovuto.
phairoh,

potresti usare javascript purodd1 = document.getElementsByClassName('classname here'); dd1.value = 2;
user2144406

Risposte:


1008

La documentazione di jQuery afferma:

[jQuery.val] controlla o seleziona tutti i pulsanti di opzione, le caselle di controllo e seleziona le opzioni che corrispondono all'insieme di valori.

Questo comportamento è nelle jQueryversioni 1.2e successive.

Molto probabilmente lo desideri:

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

22
Funziona se selectè nascosto ( display: none;)? Non riesco a farlo funzionare bene ...
Padel,

11
Questo mi ha appena salvato da scrivere cose come $('._statusDDL [value="2"]').attr('selected',true);Grazie!
Basil,

6
@Nordes che sarebbe il caso se ottenesse il valore selezionato. In questo caso sta impostando il valore selezionato, o più precisamente, impostando l'opzione selezionata.
Jon P

107
@JL: Devi aggiungere .change()per vedere l'opzione nel frontend dell'elenco a discesa, ovvero$('#myID').val(3).change();
Kai Noack

10
Concatenare .change () dovrebbe essere aggiunto alla risposta. Pensavo di impazzire con questa soluzione che non funzionava fino a quando non ho letto i commenti.
David Baucum,

139

Con il campo nascosto è necessario utilizzare in questo modo:

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

o

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

Potresti spiegare perché devi attivare l'evento change per i campi nascosti?
Samuel,

1
@Samuel: perché se si modifica l'opzione selezionata di una selezione con jQuery, la modifica non viene attivata, quindi è necessario un trigger manuale.
machineaddict,

2
Se è necessario attivare un evento di modifica dopo aver modificato il valore del menu a discesa, è necessario chiamare la funzione di modifica dopo aver impostato il valore.
tver3305,

Avevo bisogno in particolare dell'evento di cambiamento per attivarmi, quindi questo mi è stato di grande aiuto
Rohan,

32

Solo una FYI, non è necessario utilizzare le classi CSS per raggiungere questo obiettivo.

È possibile scrivere la seguente riga di codice per ottenere il nome di controllo corretto sul client:

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

ASP.NET renderà l'ID di controllo correttamente all'interno di jQuery.


8
Funziona solo quando il tuo javascript si trova all'interno del markup .aspx o .ascx e non quando si trova nel file .js come è stato il caso qui. Inoltre, a seconda della profondità con cui i controlli sono nidificati nella tua applicazione (nel mio caso avevano una profondità di circa 10 livelli), ClientID può diventare incredibilmente lungo e in realtà può aggiungere un notevole gonfiore alle dimensioni del tuo javascript se usato in modo troppo libero. Cerco di mantenere il mio markup il più piccolo possibile, se posso.
phairoh,

2
@ y0mbo Ma anche se passi a MVC dovresti comunque utilizzare file .JS esterni per il tuo JavaScript in modo che browser e server proxy possano memorizzarli nella cache per prestazioni.
settimane

1
@Roberto - ma MVC non usa le stupide convenzioni di denominazione che asp.net webforms fa in modo da poter fare comodamente riferimento in un file js esterno ai controlli necessari.
lloydphillips,

6
Se si crea javascript in stile OO, è possibile passare gli ID client nel costruttore del proprio oggetto. Il codice oggetto è tutto contenuto in un file js esterno, ma viene istanziato dal codice aspx.
mikesigs,

1
Prima impostarei ClientIDMode = "Statico" sui controlli asp in modo da sapere che l'ID sarà l'ID specificato. Devi stare attento se stai mettendo quel controllo in un ripetitore. msdn.microsoft.com/en-us/library/...
Shawson

25

Prova con

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

e non con

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

23

Queste soluzioni sembrano presupporre che ogni elemento negli elenchi a discesa abbia un valore val () relativo alla loro posizione nell'elenco a discesa.

Le cose sono un po 'più complicate se non è così.

Per leggere l'indice selezionato di un elenco a discesa, utilizzare questo:

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

Per impostare l'indice selezionato di un elenco a discesa, utilizzare questo:

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

Nota che la funzione prop () richiede JQuery v1.6 o successive.

Vediamo come useresti queste due funzioni.

Supponiamo che tu abbia un elenco a discesa di nomi di mesi.

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

È possibile aggiungere un pulsante "Mese precedente" e "Mese successivo", che esamina l'elemento dell'elenco a discesa attualmente selezionato e lo cambia al mese precedente / successivo:

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

Ed ecco il JavaScript che questi pulsanti eseguiranno:

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

Il seguente sito è utile anche per mostrare come popolare un elenco a discesa con i dati JSON:

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

Accidenti !!

Spero che sia di aiuto.


20

Dopo aver esaminato alcune soluzioni, questo ha funzionato per me.

Ho un elenco a discesa con alcuni valori e voglio selezionare lo stesso valore da un altro elenco a discesa ... Quindi prima ho inserito in una variabile il selectIndexmio primo elenco a discesa.

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

Quindi, seleziono quell'indice nel mio secondo elenco a discesa.

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

Nota:

Immagino che questa sia la soluzione più breve, affidabile, generale ed elegante.

Perché nel mio caso, sto usando l'attributo data dell'opzione selezionata anziché l'attributo value. Quindi se non hai un valore univoco per ogni opzione, il metodo sopra è il più breve e dolce !!


5
Questa è la risposta corretta e tutti coloro che non hanno detto immediatamente "selectedIndex" dovrebbero conoscerlo meglio. Evviva l'API DOM e le persone che l'hanno scritta nell'età della pietra.
vsync,

16

So che questa è una vecchia domanda e le soluzioni di cui sopra funzionano bene, tranne in alcuni casi.

Piace

<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>

Quindi l'articolo 4 verrà visualizzato come "Selezionato" nel browser e ora si desidera modificare il valore come 3 e mostrare "Articolo3" come selezionato anziché Articolo4. Quindi, come per le soluzioni di cui sopra, se si utilizza

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

Vedrai quell'articolo 3 come selezionato nel browser, ma quando elabori i dati in php o asp, troverai il valore selezionato come "4". Il motivo è che il tuo html sarà simile a questo.

<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>

e ottiene l'ultimo valore come "4" nel linguaggio secondario severo.

Quindi la mia soluzione finale su questo punto

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

MODIFICA : aggiungi una virgoletta singola intorno a "+ newselectedIndex +" in modo che la stessa funzionalità possa essere utilizzata per valori non numerici.

Quindi quello che faccio è effettivamente, rimosso l'attributo selezionato e quindi crearne uno nuovo come selezionato.

Gradirei commenti su questo da programmatori senior come @strager, @ y0mbo, @ISIK e altri


10

Se abbiamo un menu a discesa con il titolo di "Classificazione dei dati":

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

Possiamo inserirlo in una variabile:

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

Quindi inserisci in un'altra variabile il valore che vogliamo che il menu a discesa abbia:

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

Quindi possiamo usare il campo in cui ci troviamo dataClsField, fare una ricerca myValuee renderlo selezionato usando .prop():

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

Oppure, puoi semplicemente usare .val(), ma il tuo selettore di .può essere usato solo se corrisponde a una classe nel menu a discesa e dovresti usare le virgolette sul valore tra parentesi o semplicemente usare la variabile che abbiamo impostato in precedenza:

dataClsField.val(myValue);

4

Quindi l'ho cambiato in modo che ora venga eseguito dopo 300 millisecondi usando setTimeout. Sembra funzionare ora.

Mi sono imbattuto in molte volte durante il caricamento dei dati da una chiamata Ajax. Anch'io utilizzo .NET e ci vuole tempo per adattarsi al clientId quando si usa il selettore jQuery. Per correggere il problema che stai riscontrando ed evitare di aggiungere una setTimeoutproprietà, puoi semplicemente inserire " async: false" nella chiamata Ajax e darà al DOM il tempo sufficiente per riavere gli oggetti che stai aggiungendo alla selezione. Un piccolo esempio di seguito:

$.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)
            );
        });
    }
});

3

Solo una nota: sto usando selettori di caratteri jolly in jQuery per afferrare elementi che sono offuscati dagli ID CLient ASP.NET, anche questo potrebbe aiutarti:

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

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

Nota l'id * jolly - questo troverà il tuo elemento anche se il nome è "ctl00 $ ctl00 $ ContentPlaceHolder1 $ ContentPlaceHolder1 $ MyDropDown"


3

Uso una funzione di estensione per ottenere gli ID client, in questo modo:

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

Quindi puoi chiamare i controlli ASP.NET in jQuery in questo modo:

$.clientID("_statusDDL")

3

Un'altra opzione è quella di impostare il parametro di controllo ClientID = "Statico" in .net e quindi è possibile accedere all'oggetto in JQuery tramite l'ID impostato.


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

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


Se stai abbinando il nome, puoi anche rimuoverlo, in $modo che sia una corrispondenza completa, senza "terminare con". Ma il tuo suggerimento è probabilmente più veloce della sola corrispondenza con un nome di classe. Anche più veloce sarebbe element.classnameo #idname.
Alec,

2

Come si caricano i valori nell'elenco a discesa o si determina quale valore selezionare? Se lo stai facendo usando Ajax, il motivo per cui hai bisogno del ritardo prima che si verifichi la selezione potrebbe essere perché i valori non sono stati caricati nel momento in cui la riga in questione è stata eseguita. Ciò spiegherebbe anche perché ha funzionato quando si inserisce un'istruzione di avviso sulla linea prima di impostare lo stato poiché l'azione di avviso darebbe un ritardo sufficiente per il caricamento dei dati.

Se si utilizza uno dei metodi Ajax di jQuery, è possibile specificare una funzione di richiamata e quindi inserirla $("._statusDDL").val(2);nella funzione di richiamata.

Questo sarebbe un modo più affidabile di gestire il problema poiché potresti essere sicuro che il metodo eseguito quando i dati erano pronti, anche se impiegava più di 300 ms.


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

1

Nel mio caso sono stato in grado di farlo funzionare usando il metodo .attr ().

$("._statusDDL").attr("selected", "");
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.