Altere o valor selecionado de uma lista suspensa com jQuery

840

Eu tenho uma lista suspensa com valores conhecidos. O que estou tentando fazer é definir a lista suspensa para um valor específico que eu sei que existe usando o jQuery . Usando JavaScript regular , eu faria algo como:

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

No entanto, preciso fazer isso com o jQuery , porque estou usando uma classe CSS para o meu seletor (idiotas idiotas do cliente ASP.NET ...).

Aqui estão algumas coisas que eu tentei:

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

Como posso fazer isso com o jQuery ?


Atualizar

Então, na verdade, eu entendi direito da primeira vez com:

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

Quando coloco um alerta logo acima, ele funciona bem, mas quando removo o alerta e o deixo rodar a toda velocidade, recebo o erro

Não foi possível definir a propriedade selecionada. Índice inválido

Não tenho certeza se é um bug do jQuery ou do Internet Explorer 6 (acho que o Internet Explorer 6 ), mas é terrivelmente irritante.

phairoh
fonte
21
O problema aqui acabou sendo um problema no IE6. Eu estava criando novos elementos de opção para o elemento select e, em seguida, tentando definir o valor para um desses elementos de opção recém-criados. O IE6 aguarda incorretamente até recuperar o controle de um script para realmente criar os novos elementos no DOM de maneira tão eficaz. O que estava acontecendo é que eu estava tentando definir as listas suspensas para opções que ainda não existiam, mesmo que devessem existir.
Phairoh 22/04/09
você pode usar javascript purodd1 = document.getElementsByClassName('classname here'); dd1.value = 2;
user2144406

Respostas:

1008

A documentação do jQuery declara:

[jQuery.val] verifica ou seleciona todos os botões de opção, caixas de seleção e opções que correspondem ao conjunto de valores.

Esse comportamento está nas jQueryversões 1.2e acima.

Você provavelmente quer isso:

$("._statusDDL").val('2');
strager
fonte
22
Isso funciona se o selectestiver oculto ( display: none;)? Eu não posso obtê-lo para a direita trabalho ...
Padel
11
Isso me salvou de escrever coisas como $('._statusDDL [value="2"]').attr('selected',true);Obrigado!
Basil Basil
6
@Nordes que seria o caso se obtivesse o valor selecionado. Nesse caso, está configurando o valor selecionado, ou mais precisamente, configurando a opção selecionada.
Jon P
107
@JL: Você precisa adicionar .change()para ver a opção na lista frontend suspensa, ou seja$('#myID').val(3).change();
Kai Noack
10
Encadear o .change () deve ser adicionado à resposta. Eu pensei que estava ficando louco por essa solução não funcionar até ler os comentários.
David Baucum
139

Com o campo oculto, você precisa usar assim:

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

ou

$("._statusDDL").val(2).change();
Aivar Luist
fonte
Você poderia explicar por que você precisa acionar um evento de alteração para campos ocultos?
Samuel
1
@ Samuel: porque se você alterar a opção selecionada de um select com jQuery, a alteração não é acionada, portanto é necessário um acionador manual.
Machineaddict
2
Se você precisar acionar um evento de alteração após alterar o valor da caixa de depósito, chame a função de alteração após definir o valor.
precisa saber é o seguinte
Eu especificamente precisava que o evento de mudança fosse acionado, então isso foi muito útil para mim
Rohan
32

Apenas um FYI, você não precisa usar classes CSS para fazer isso.

Você pode escrever a seguinte linha de código para obter o nome de controle correto no cliente:

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

O ASP.NET renderizará a identificação de controle corretamente dentro do jQuery.

y0mbo
fonte
8
Isso só funciona quando seu javascript está dentro da marcação .aspx ou .ascx e não quando está no arquivo .js, como foi o caso aqui. Além disso, dependendo da profundidade em que seus controles estão aninhados no seu aplicativo (no meu caso, eles tinham cerca de 10 níveis), o ClientID pode ficar incrivelmente longo e pode realmente adicionar inchaço significativo ao tamanho do seu javascript, se usado de maneira muito liberal. Tento manter minha marcação o menor possível, se puder.
Phairoh
2
@ y0mbo Mas, mesmo que você mude para o MVC, ainda deve usar arquivos .JS externos para o seu JavaScript, para que navegadores e servidores proxy possam armazená-lo em cache para desempenho.
7wp 15/12/09
1
@ Roberto - mas o MVC não usa as convenções de nomes estúpidas que o asp.net webforms faz para que você possa confortavelmente fazer referência em um arquivo js externo aos controles de que precisa.
lloydphillips
6
Se você criar javascript no estilo OO, poderá passar seus IDs de cliente para o construtor do seu objeto. O código do objeto está todo contido em um arquivo js externo, mas você o instancia a partir do seu código aspx.
Mikeigs #
1
Mais cedo, definir ClientIDMode = "Static" nos controles asp para que você saiba que o ID será o ID especificado. Você precisa ter cuidado se estiver colocando esse controle em um repetidor. msdn.microsoft.com/pt-BR/library/…
Shawson 24/09
25

Apenas tente com

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

e não com

$("._statusDDL").val(2);
emas
fonte
23

Essas soluções parecem assumir que cada item nas suas listas suspensas tem um valor val () relacionado à sua posição na lista suspensa.

As coisas são um pouco mais complicadas se esse não for o caso.

Para ler o índice selecionado de uma lista suspensa, você usaria o seguinte:

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

Para definir o índice selecionado de uma lista suspensa, você usaria o seguinte:

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

Observe que o recurso prop () requer JQuery v1.6 ou posterior.

Vamos ver como você usaria essas duas funções.

Supondo que você tenha uma lista suspensa de nomes de meses.

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

Você pode adicionar um botão "Mês anterior" e "Próximo mês", que examina o item da lista suspensa atualmente selecionado e o altera para o mês anterior / seguinte:

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

E aqui está o JavaScript que esses botões executariam:

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

O site a seguir também é útil para mostrar como preencher uma lista suspensa com dados JSON:

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

Ufa !!

Espero que isto ajude.

Mike Gledhill
fonte
20

Depois de analisar algumas soluções, isso funcionou para mim.

Eu tenho uma lista suspensa com alguns valores e quero selecionar o mesmo valor em outra lista suspensa ... Então, primeiro eu coloquei em uma variável o selectIndexmeu primeiro menu suspenso.

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

Em seguida, seleciono esse índice na minha segunda lista suspensa.

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

Nota:

Acho que essa é a solução mais curta, confiável, geral e elegante.

Porque no meu caso, estou usando o atributo de dados da opção selecionada em vez do atributo de valor. Portanto, se você não tiver um valor exclusivo para cada opção, o método acima é o mais curto e agradável !!

ISIK
fonte
5
Esta é a resposta correta e todos que não disserem 'selectedIndex' instantaneamente devem saber melhor. API DOM do Hurrah e as pessoas que a escreveram na era da pedra.
vsync
16

Sei que essa é uma pergunta antiga e as soluções acima funcionam bem, exceto em alguns casos.

Gostar

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

Portanto, o Item 4 será exibido como "Selecionado" no navegador e agora você deseja alterar o valor como 3 e mostrará "Item3" como selecionado em vez de Item4.Então, conforme as soluções acima, se você usar

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

Você verá o item 3 como selecionado no navegador. Mas, ao processar os dados em php ou asp, o valor selecionado será "4". O motivo é que o seu html ficará assim.

<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 obtém o último valor como "4" no idioma secundário do servidor.

ASSIM MINHA SOLUÇÃO FINAL NESTE RELATÓRIO

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

EDIT : adicione aspas simples ao redor de "+ newselectedIndex +" para que a mesma funcionalidade possa ser usada para valores não numéricos.

Então, o que eu faço é remover o atributo selecionado e criar o novo como selecionado.

Eu gostaria de receber comentários de programadores seniores como @strager, @ y0mbo, @ISIK e outros

Rocker Maruf
fonte
10

Se tivermos um menu suspenso com o título "Classificação de dados":

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

Podemos colocá-lo em uma variável:

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

Em seguida, coloque em outra variável o valor que queremos que o menu suspenso tenha:

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

Em seguida, podemos usar o campo em que inserimos dataClsField, encontrar myValuee fazer a seleção usando .prop():

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

Ou você pode apenas usar .val(), mas seu seletor de .apenas pode ser usado se corresponder a uma classe no menu suspenso, e você deve usar aspas no valor entre parênteses, ou apenas usar a variável que definimos anteriormente:

dataClsField.val(myValue);
vapcguy
fonte
4

Então eu mudei para que agora seja executado após 300 milissegundos usando setTimeout. Parece estar funcionando agora.

Eu já me deparei com isso muitas vezes ao carregar dados de uma chamada do Ajax. Eu também uso o .NET e leva tempo para ser ajustado ao clientId ao usar o seletor jQuery. Para corrigir o problema que você está tendo e para evitar ter que adicionar uma setTimeoutpropriedade, basta " async: false" colocar a chamada Ajax, e isso dará ao DOM tempo suficiente para recuperar os objetos que você está adicionando à seleção. Uma pequena amostra abaixo:

$.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)
            );
        });
    }
});
sentido horárioq
fonte
3

Apenas uma observação - eu tenho usado seletores curinga no jQuery para obter itens ofuscados pelas IDs de cliente do ASP.NET - isso também pode ajudá-lo:

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

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

Observe o caractere curinga id * - ele encontrará seu elemento mesmo se o nome for "ctl00 $ ctl00 $ ContentPlaceHolder1 $ ContentPlaceHolder1 $ MyDropDown"

AVH
fonte
3

Eu uso uma função de extensão para obter IDs de clientes, assim:

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

Em seguida, você pode chamar os controles ASP.NET no jQuery da seguinte maneira:

$.clientID("_statusDDL")
jonofan
fonte
3

Outra opção é definir o parâmetro de controle ClientID = "Static" no .net e, em seguida, você pode acessar o objeto no JQuery pelo ID definido.

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

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

Monty
fonte
Se você estiver combinando com o nome, é possível remover o, $para que seja uma correspondência completa, não "terminando com". Mas sua sugestão provavelmente é mais rápida do que apenas corresponder a um nome de classe. Ainda mais rápido seria element.classnameou #idname.
Alec
2

Como você está carregando os valores na lista suspensa ou determinando qual valor selecionar? Se você estiver fazendo isso usando o Ajax, o motivo pelo qual você precisa do atraso antes da seleção ocorrer pode ser porque os valores não foram carregados no momento em que a linha em questão foi executada. Isso também explicaria por que funcionou quando você colocou uma instrução de alerta na linha antes de definir o status, pois a ação de alerta daria um atraso suficiente para o carregamento dos dados.

Se você estiver usando um dos métodos Ajax do jQuery, poderá especificar uma função de retorno de chamada e depois inseri-la $("._statusDDL").val(2);na função de retorno de chamada.

Essa seria uma maneira mais confiável de lidar com o problema, pois você pode ter certeza de que o método foi executado quando os dados estavam prontos, mesmo que demorassem mais de 300 ms.

Pervez Choudhury
fonte
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 = "Estático"

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

No meu caso, consegui fazê-lo funcionar usando o método .attr ().

$("._statusDDL").attr("selected", "");
Colin
fonte