Cambiar el valor seleccionado de una lista desplegable con jQuery

840

Tengo una lista desplegable con valores conocidos. Lo que intento hacer es establecer la lista desplegable en un valor particular que sé que existe usando jQuery . Usando JavaScript normal , haría algo como:

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

Sin embargo, necesito hacer esto con jQuery , porque estoy usando una clase CSS para mi selector (estúpidos identificadores de cliente ASP.NET ...).

Aquí hay algunas cosas que he probado:

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

¿Cómo puedo hacerlo con jQuery ?


Actualizar

Resulta que lo hice bien la primera vez con:

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

Cuando coloco una alerta justo encima, funciona bien, pero cuando elimino la alerta y la dejo correr a toda velocidad, aparece el error

No se pudo establecer la propiedad seleccionada. Índice inválido

No estoy seguro de si es un error con jQuery o Internet Explorer 6 (supongo que Internet Explorer 6 ), pero es terriblemente molesto.

Phairoh
fuente
21
El problema aquí terminó siendo un problema con IE6. Estaba creando nuevos elementos de opción para el elemento de selección y luego intentaba establecer el valor en uno de esos elementos de opción recién creados. IE6 espera incorrectamente hasta que ha recuperado el control de un script para crear realmente los nuevos elementos en el DOM, de manera tan efectiva que estaba sucediendo que estaba tratando de establecer las listas desplegables en opciones que aún no existían, aunque deberían haberlo hecho.
phairoh
podrías usar JavaScript purodd1 = document.getElementsByClassName('classname here'); dd1.value = 2;
user2144406

Respuestas:

1008

La documentación de jQuery establece:

[jQuery.val] marca o selecciona todos los botones de radio, casillas de verificación y selecciona opciones que coinciden con el conjunto de valores.

Este comportamiento está en jQueryversiones 1.2y superiores.

Lo más probable es que quieras esto:

$("._statusDDL").val('2');
extraño
fuente
22
¿Funciona esto si selectestá oculto ( display: none;)? No puedo hacer que funcione bien ...
Padel
11
Esto me salvó de escribir cosas como $('._statusDDL [value="2"]').attr('selected',true);¡Gracias!
Basil
66
@Nordes ese sería el caso si obtuviera el valor seleccionado. En este caso, está configurando el valor seleccionado, o más exactamente, configurando la opción seleccionada.
Jon P
107
@JL: Debe agregar .change()para ver la opción en la interfaz de la lista desplegable, es decir$('#myID').val(3).change();
Kai Noack
10
Encadenamiento .change () debe agregarse a la respuesta. Pensé que me estaba volviendo loco con esta solución que no funcionaba hasta que leí los comentarios.
David Baucum
139

Con el campo oculto debe usar así:

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

o

$("._statusDDL").val(2).change();
Aivar Luist
fuente
¿Podría explicar por qué necesita activar un evento de cambio para campos ocultos?
Samuel
1
@Samuel: porque si cambia la opción seleccionada de una selección con jQuery, el cambio no se activa, por lo que se requiere un activador manual.
machineaddict
2
Si necesita que se active un evento de cambio después de cambiar el valor del dropbox, debe llamar a la función de cambio después de establecer el valor.
tver3305
Necesitaba específicamente que se activara el evento de cambio, así que fue de gran ayuda para mí
Rohan
32

Solo para su información, no necesita usar clases CSS para lograr esto.

Puede escribir la siguiente línea de código para obtener el nombre de control correcto en el cliente:

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

ASP.NET representará la ID de control correctamente dentro de jQuery.

y0mbo
fuente
8
Eso solo funciona cuando su javascript está dentro del marcado .aspx o .ascx y no cuando está en el archivo .js como fue el caso aquí. Además, dependiendo de qué tan profundos estén sus controles anidados en su aplicación (en mi caso, tenían aproximadamente 10 niveles de profundidad), el ClientID puede ser increíblemente largo y, de hecho, puede agregar una hinchazón significativa al tamaño de su JavaScript si se usa demasiado. Intento mantener mi marcado lo más pequeño posible, si puedo.
phairoh
2
@ y0mbo Pero incluso si se muda a MVC, debería usar archivos .JS externos para su JavaScript para que los navegadores y los servidores proxy puedan almacenarlo en caché para su rendimiento.
7wp
1
@Roberto, pero MVC no utiliza las estúpidas convenciones de nomenclatura que usan los formularios web asp.net, por lo que puede hacer referencia cómodamente en un archivo js externo a los controles que necesita.
lloydphillips
66
Si crea javascript estilo OO, puede pasar sus ID de cliente al constructor de su objeto. El código objeto está contenido en un archivo js externo, pero lo instancia desde su código aspx.
mikesigs
1
Prefiero establecer ClientIDMode = "Static" en los controles asp para que sepa que la ID será la ID que especificó. Sin embargo, debe tener cuidado si coloca ese control en un repetidor. msdn.microsoft.com/en-us/library/…
Shawson
25

Solo intenta con

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

y no con

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

Estas soluciones parecen suponer que cada elemento en sus listas desplegables tiene un valor val () relacionado con su posición en la lista desplegable.

Las cosas son un poco más complicadas si este no es el caso.

Para leer el índice seleccionado de una lista desplegable, usaría esto:

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

Para establecer el índice seleccionado de una lista desplegable, usaría esto:

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

Tenga en cuenta que la función prop () requiere JQuery v1.6 o posterior.

Veamos cómo usaría estas dos funciones.

Supongamos que tiene una lista desplegable de nombres de mes.

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

Puede agregar un botón de "Mes anterior" y "Mes siguiente", que mira el elemento de la lista desplegable actualmente seleccionado y lo cambia al mes anterior / siguiente:

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

Y aquí está el JavaScript que ejecutarían estos botones:

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

El siguiente sitio también es útil para mostrar cómo llenar una lista desplegable con datos JSON:

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

¡Uf!

Espero que esto ayude.

Mike Gledhill
fuente
20

Después de buscar algunas soluciones, esto funcionó para mí.

Tengo una lista desplegable con algunos valores y quiero seleccionar el mismo valor de otra lista desplegable ... Así que primero pongo una variable selectIndexde mi primer menú desplegable.

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

Luego, selecciono ese índice en mi segunda lista desplegable.

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

Nota:

Supongo que esta es la solución más corta, confiable, general y elegante.

Porque en mi caso, estoy usando el atributo de datos de la opción seleccionada en lugar del atributo de valor. Entonces, si no tiene un valor único para cada opción, ¡el método anterior es el más corto y dulce!

ISIK
fuente
55
Esta es la respuesta correcta, y todos los que no digan 'selectedIndex' al instante, deberían saberlo mejor. Hurray DOM API y las personas que lo escribieron en la edad de piedra.
vsync
16

Sé que esta es una vieja pregunta y las soluciones anteriores funcionan bien, excepto en algunos casos.

Me gusta

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

Por lo tanto, el elemento 4 se mostrará como "Seleccionado" en el navegador y ahora desea cambiar el valor como 3 y mostrará "Elemento3" como seleccionado en lugar de Elemento4. De acuerdo con las soluciones anteriores, si usa

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

Verá ese elemento 3 como seleccionado en el navegador. Pero cuando procese los datos en php o asp, encontrará el valor seleccionado como "4". La razón es que su html se verá así.

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

y obtiene el último valor como "4" en el lenguaje secundario del servidor.

Entonces, mi solución final a este respecto

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

EDITAR : Agregue una comilla simple alrededor de "+ newselectedIndex +" para que la misma funcionalidad se pueda usar para valores no numéricos.

Entonces, lo que hago es eliminar el atributo seleccionado y luego hacer el nuevo como seleccionado.

Agradecería comentarios sobre esto de programadores senior como @strager, @ y0mbo, @ISIK y otros

Rocker Maruf
fuente
10

Si tenemos un menú desplegable con un título de "Clasificación de datos":

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

Podemos meterlo en una variable:

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

Luego ponga en otra variable el valor que queremos que tenga el menú desplegable:

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

Luego podemos usar el campo en el que ponemos dataClsField, hacer una búsqueda myValuey seleccionarlo usando .prop():

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

O bien, puede usar .val(), pero su selector de .solo se puede usar si coincide con una clase en el menú desplegable, y debe usar comillas en el valor dentro del paréntesis, o simplemente usar la variable que establecimos anteriormente:

dataClsField.val(myValue);
vapcguy
fuente
4

Así que lo cambié para que ahora se ejecute después de 300 milisegundos usando setTimeout. Parece estar trabajando ahora.

Me he encontrado con esto muchas veces al cargar datos de una llamada Ajax. Yo también uso .NET, y lleva tiempo ajustarme al clientId cuando uso el selector jQuery. Para corregir el problema que está teniendo y para evitar tener que agregar una setTimeoutpropiedad, simplemente puede poner " async: false" en la llamada Ajax y le dará al DOM suficiente tiempo para recuperar los objetos que está agregando a la selección. Una pequeña muestra a continuación:

$.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)
            );
        });
    }
});
a la derechaq
fuente
3

Solo una nota: he estado usando selectores comodín en jQuery para capturar elementos que están ofuscados por los ID de cliente de ASP.NET, esto también podría ayudarlo:

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

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

Tenga en cuenta el comodín id *: esto encontrará su elemento incluso si el nombre es "ctl00 $ ctl00 $ ContentPlaceHolder1 $ ContentPlaceHolder1 $ MyDropDown"

AVH
fuente
3

Utilizo una función de extensión para obtener identificadores de cliente, así:

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

Luego puede llamar a los controles ASP.NET en jQuery de esta manera:

$.clientID("_statusDDL")
jonofan
fuente
3

Otra opción es establecer el parámetro de control ClientID = "Static" en .net y luego puede acceder al objeto en JQuery por la ID que configuró.

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

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

Monty
fuente
Si coincide con el nombre, también podría eliminarlo $para que sea una coincidencia completa, no 'terminando con'. Pero su sugerencia es probablemente más rápida que solo coincidir con un nombre de clase. Aunque más rápido sería element.classnameo #idname.
Alec
2

¿Cómo carga los valores en la lista desplegable o determina qué valor seleccionar? Si está haciendo esto usando Ajax, entonces la razón por la que necesita el retraso antes de que ocurra la selección podría ser porque los valores no se cargaron en el momento en que se ejecutó la línea en cuestión. Esto también explicaría por qué funcionó cuando coloca una declaración de alerta en la línea antes de establecer el estado, ya que la acción de alerta daría suficiente retraso para que se carguen los datos.

Si está utilizando uno de los métodos Ajax de jQuery, puede especificar una función de devolución de llamada y luego ponerla $("._statusDDL").val(2);en su función de devolución de llamada.

Esta sería una forma más confiable de manejar el problema, ya que puede estar seguro de que el método se ejecutó cuando los datos estuvieron listos, incluso si tomó más de 300 ms.

Pervez Choudhury
fuente
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
fuente
1

En mi caso pude hacerlo funcionar usando el método .attr ().

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