Zmień wybraną wartość listy rozwijanej za pomocą jQuery

840

Mam listę rozwijaną ze znanymi wartościami. To, co próbuję zrobić, to ustawić listę rozwijaną na określoną wartość, o której wiem, że istnieje przy użyciu jQuery . Używając zwykłego JavaScript , zrobiłbym coś takiego:

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

Jednak muszę to zrobić za pomocą jQuery , ponieważ używam klasy CSS dla mojego selektora (głupie identyfikatory klientów ASP.NET ...).

Oto kilka rzeczy, które próbowałem:

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

Jak mogę to zrobić za pomocą jQuery ?


Aktualizacja

Jak się okazuje, za pierwszym razem miałem rację:

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

Gdy umieszczam alert tuż powyżej, działa dobrze, ale kiedy go usuwam i pozwalam mu działać z pełną prędkością, pojawia się błąd

Nie można ustawić wybranej właściwości. Nieprawidłowy indeks

Nie jestem pewien, czy jest to błąd w jQuery lub Internet Explorer 6 (domyślam się Internet Explorera 6 ), ale to jest strasznie denerwujące.

phairoh
źródło
21
Problem tutaj zakończył się problemem z IE6. Tworzyłem nowe elementy opcji dla elementu select, a następnie próbowałem ustawić wartość na jeden z tych nowo utworzonych elementów opcji. IE6 niepoprawnie czeka, aż odzyska kontrolę nad skryptem, aby faktycznie utworzyć nowe elementy w DOM, więc tak naprawdę działo się tak, że próbowałem ustawić listy rozwijane na opcje, które jeszcze nie istniały, nawet jeśli powinny.
phairoh
możesz użyć czystego javascriptdd1 = document.getElementsByClassName('classname here'); dd1.value = 2;
user2144406

Odpowiedzi:

1008

Dokumentacja jQuery stwierdza:

[jQuery.val] sprawdza lub wybiera wszystkie przyciski opcji, pola wyboru i wybiera opcje pasujące do zestawu wartości.

To zachowanie występuje w jQuerywersjach 1.2i wyższych.

Najprawdopodobniej chcesz to:

$("._statusDDL").val('2');
strager
źródło
22
Czy to działa, jeśli selectjest ukryty ( display: none;)? Nie mogę tego zrobić poprawnie ...
Padel,
11
To właśnie uratowało mnie od pisania takich rzeczy, jak $('._statusDDL [value="2"]').attr('selected',true);Thanks!
Basil
6
@Nordes miałoby to miejsce w przypadku uzyskania wybranej wartości. W tym przypadku ustawia wybraną wartość, a dokładniej, ustawia wybraną opcję.
Jon P
107
@JL: Musisz dodać, .change()aby zobaczyć opcję w interfejsie rozwijanej listy, tj.$('#myID').val(3).change();
Kai Noack,
10
Do odpowiedzi należy dodać łańcuch .change (). Myślałem, że oszalałem na punkcie tego rozwiązania, które nie działało, dopóki nie przeczytałem komentarzy.
David Baucum
139

Z ukrytym polem musisz użyć następującego:

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

lub

$("._statusDDL").val(2).change();
Aivar Luist
źródło
Czy możesz wyjaśnić, dlaczego musisz uruchomić zdarzenie zmiany dla ukrytych pól?
Samuel
1
@ Samuel: ponieważ jeśli zmienisz wybraną opcję wyboru za pomocą jQuery, zmiana nie zostanie wyzwolona, ​​więc wymagane jest ręczne wyzwolenie.
machineaddict
2
Jeśli potrzebujesz zmienić zdarzenie wywołania zmiany po zmianie wartości Dropbox, musisz wywołać funkcję zmiany po ustawieniu wartości.
tver3305
Szczególnie potrzebowałem zdarzenia zmiany, aby wystrzelić, więc było to dla mnie najbardziej pomocne
Rohan
32

Po prostu FYI, nie musisz używać klas CSS, aby to osiągnąć.

Możesz napisać następujący wiersz kodu, aby uzyskać poprawną nazwę kontrolną na kliencie:

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

ASP.NET wyrenderuje poprawnie identyfikator kontroli w jQuery.

y0mbo
źródło
8
Działa to tylko wtedy, gdy skrypt javascript znajduje się w znacznikach .aspx lub .ascx, a nie wtedy, gdy znajduje się w pliku .js, jak miało to miejsce w tym przypadku. Ponadto, w zależności od tego, jak głęboko twoje kontrolki są zagnieżdżone w twojej aplikacji (w moim przypadku miały one około 10 poziomów głębokości), ClientID może stać się niesamowicie długi i może faktycznie dodać znaczny wzdęcie do rozmiaru twojego javascript, jeśli zostanie użyty zbyt swobodnie. Staram się, aby moje znaczniki były jak najmniejsze, jeśli to możliwe.
phairoh
2
@ y0mbo Ale nawet jeśli przejdziesz do MVC, powinieneś nadal używać zewnętrznych plików .JS dla swojego JavaScript, aby przeglądarki i serwery proxy mogły buforować go dla wydajności.
7wp
1
@Roberto - ale MVC nie stosuje głupich konwencji nazewnictwa, które robi formularze internetowe asp.net, więc możesz wygodnie odwoływać się w zewnętrznym pliku js do potrzebnych kontrolek.
lloydphillips
6
Jeśli utworzysz javascript w stylu OO, możesz przekazać identyfikatory klienta do konstruktora obiektu. Kod obiektowy jest zawarty w zewnętrznym pliku js, ale tworzysz go z kodu aspx.
mikesigs
1
Wcześniej ustawiłbym ClientIDMode = "Static" na kontrolkach asp, więc wiesz, że ID będzie identyfikatorem określonym przez ciebie. Musisz jednak uważać, jeśli następnie umieszczasz tę kontrolę w repeaterze. msdn.microsoft.com/en-us/library/…
Shawson
25

Po prostu spróbuj

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

i nie z

$("._statusDDL").val(2);
emas
źródło
23

Rozwiązania te wydają się zakładać, że każdy element na liście rozwijanej ma wartość val () odnoszącą się do ich pozycji na liście rozwijanej.

Sprawy są nieco bardziej skomplikowane, jeśli tak nie jest.

Aby odczytać wybrany indeks z listy rozwijanej, użyj tego:

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

Aby ustawić wybrany indeks listy rozwijanej, użyj tego:

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

Zauważ, że funkcja prop () wymaga JQuery w wersji 1.6 lub nowszej.

Zobaczmy, jak użyłbyś tych dwóch funkcji.

Załóżmy, że masz rozwijaną listę nazw miesięcy.

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

Możesz dodać przycisk „Poprzedni miesiąc” i „Następny miesiąc”, który przegląda aktualnie wybrany element listy rozwijanej i zmienia go na poprzedni / następny miesiąc:

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

A oto JavaScript, który uruchamiają te przyciski:

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

Przydatna jest również następująca witryna do pokazania, jak wypełnić listę rozwijaną danymi JSON:

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

Uff !!

Mam nadzieję że to pomoże.

Mike Gledhill
źródło
20

Po przeanalizowaniu niektórych rozwiązań zadziałało to dla mnie.

Mam jedną listę rozwijaną z niektórymi wartościami i chcę wybrać tę samą wartość z innej listy rozwijanej ... Więc najpierw wstawiam zmienną selectIndexz mojej pierwszej listy rozwijanej.

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

Następnie wybieram ten indeks z mojej drugiej listy rozwijanej.

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

Uwaga:

Myślę, że jest to najkrótsze, niezawodne, ogólne i eleganckie rozwiązanie.

Ponieważ w moim przypadku używam atrybutu danych wybranej opcji zamiast atrybutu wartości. Więc jeśli nie masz unikalnej wartości dla każdej opcji, powyższa metoda jest najkrótsza i słodka !!

ISIK
źródło
5
To poprawna odpowiedź i każdy, kto nie powiedział od razu „selectedIndex”, powinien wiedzieć lepiej. Hurray DOM API i ludzie, którzy napisali go w epoce kamienia łupanego.
vsync
16

Wiem, że to stare pytanie i powyższe rozwiązania działają dobrze, z wyjątkiem niektórych przypadków.

Lubić

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

Tak więc pozycja 4 pojawi się w przeglądarce jako „Wybrana”, a teraz chcesz zmienić wartość na 3 i pokazać „Pozycja 3” jako wybraną zamiast pozycji 4. Tak więc, zgodnie z powyższymi rozwiązaniami, jeśli używasz

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

Zobaczysz pozycję 3 wybraną w przeglądarce, ale kiedy przetwarzasz dane w php lub asp, znajdziesz wybraną wartość jako „4”. Powodem jest to, że Twój HTML będzie wyglądał tak.

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

i otrzymuje ostatnią wartość jako „4” w języku pobocznym serwera.

TAKIE MOJE KOŃCOWE ROZWIĄZANIE W TYM UWAGI

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

EDYCJA : Dodaj pojedynczy cudzysłów wokół „+ newselectedIndex +”, aby ta sama funkcjonalność mogła być używana dla wartości nienumerycznych.

Więc to, co robię, to usunięcie wybranego atrybutu, a następnie utworzenie nowego jako wybranego.

Byłbym wdzięczny za komentarze na ten temat od starszych programistów, takich jak @strager, @ y0mbo, @ISIK i inni

Rocker Maruf
źródło
10

Jeśli mamy listę rozwijaną z tytułem „Klasyfikacja danych”:

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

Możemy przekształcić go w zmienną:

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

Następnie umieść w innej zmiennej wartość, którą chcemy, aby lista rozwijana miała:

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

Następnie możemy użyć pola, w które się wpisujemy dataClsField, wyszukać myValuei ustawić je za pomocą .prop():

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

Lub możesz po prostu użyć .val(), ale możesz użyć selektora, .jeśli pasuje on do klasy w menu rozwijanym i powinieneś użyć cudzysłowu na wartości w nawiasie lub po prostu użyć zmiennej, którą ustawiliśmy wcześniej:

dataClsField.val(myValue);
vapcguy
źródło
4

Więc zmieniłem go tak, aby teraz działał po 300 milisekundach przy użyciu setTimeout. Wygląda na to, że teraz działa.

Natknąłem się na to wiele razy podczas ładowania danych z wywołania Ajax. Ja także używam .NET, a dostosowanie selektora jQuery zajmuje trochę czasu. Aby rozwiązać występujący problem i uniknąć konieczności dodawania setTimeoutwłaściwości, możesz po prostu wstawić „ async: false” w wywołaniu Ajax, a DOM zapewni wystarczająco dużo czasu na odzyskanie dodawanych obiektów. Mała próbka poniżej:

$.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)
            );
        });
    }
});
zgodnie z ruchem wskazówek zegara
źródło
3

Tylko uwaga - używałem selektorów symboli wieloznacznych w jQuery do przechwytywania elementów zaciemnionych przez identyfikatory klientów ASP.NET - to też może ci pomóc:

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

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

Zwróć uwagę na symbol wieloznaczny id * - znajdzie to Twój element, nawet jeśli nazwa to „ctl00 $ ctl00 $ ContentPlaceHolder1 $ ContentPlaceHolder1 $ MyDropDown”

AVH
źródło
3

Korzystam z funkcji rozszerzania, aby uzyskać identyfikatory klienta, na przykład:

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

Następnie możesz wywołać formanty ASP.NET w jQuery w następujący sposób:

$.clientID("_statusDDL")
jonofan
źródło
3

Inną opcją jest ustawienie parametru sterującego ClientID = "Static" w .net, a następnie można uzyskać dostęp do obiektu w JQuery przy ustawionym identyfikatorze.

Mych
źródło
3
<asp:DropDownList id="MyDropDown" runat="server" />

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

Monty
źródło
Jeśli pasujesz do nazwy, równie dobrze możesz ją usunąć, $aby była ona w pełni zgodna, a nie „kończąca się na”. Ale twoja sugestia jest prawdopodobnie szybsza niż dopasowanie tylko do nazwy klasy. Nawet szybciej byłoby element.classnamelub #idname.
Alec
2

Jak ładujesz wartości do rozwijanej listy lub decydujesz, którą wartość wybrać? Jeśli robisz to za pomocą Ajax, powodem, dla którego potrzebujesz opóźnienia przed dokonaniem wyboru, może być to, że wartości nie zostały załadowane w momencie wykonania danego wiersza. Wyjaśniłoby to również, dlaczego zadziałało, gdy umieściłeś komunikat ostrzegawczy w linii przed ustawieniem statusu, ponieważ akcja ostrzegania dałaby wystarczająco dużo czasu na załadowanie danych.

Jeśli używasz jednej z metod Ajax jQuery'ego, możesz określić funkcję zwrotną, a następnie umieścić ją $("._statusDDL").val(2);w funkcji zwrotnej.

Byłby to bardziej niezawodny sposób obsługi problemu, ponieważ można mieć pewność, że metoda została wykonana, gdy dane były gotowe, nawet jeśli zajęło to więcej niż 300 ms.

Pervez Choudhury
źródło
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 = „Statyczny”

$('#DropUserType').val('1');
hamze shoae
źródło
1

W moim przypadku udało mi się uruchomić go za pomocą metody .attr ().

$("._statusDDL").attr("selected", "");
Colin
źródło