El selector jQuery no funciona correctamente

Estoy usando el selector jQuery para ocultar y mostrar algunas celdas HTML generadas dinámicamente. Sin embargo, parece que no elegí el selector correcto. Por lo tanto, agradezco si me puede dar algunas sugerencias.

La página web:

  1. primero pida a los usuarios que seleccionen el número de aplicaciones
  2. según la selección de los usuarios, genere dos campos de entrada "Tiempo de aplicación" y "Fecha de aplicación" para cada aplicación.
  3. Hay dos opciones en el "Tiempo de aplicación". Si el usuario elige "Predeterminado", la "Fecha de solicitud" desaparecerá.

Problema: Cuando hay más de tres solicitudes, solo desaparecerá la última "Fecha de solicitud", sin importar dónde se realice la selección. Creo que es porque no usé el selector derecho.

DEMO

CÓDIGO HTML

<table class="table">
    <tr>
        <th>
            <label for="id_NOA">Number of applications:</label>
        </th>
        <td>
            <select id="id_NOA" class="valid" name="NOA">
                <option selected="selected" value="">Choose</option>
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
                <option value="4">4</option>
            </select>
        </td>
    </tr>
</table>

JavaScript

$(document).ready(function() {
    $('#id_NOA').change(function() {

        var total = $(this).val();
        $('.app_timing').remove();
        $('.app_dates').remove();

        for (var i = 1; i <= total; i++) {

            $('<tr class="app_timing"><th><label for="id_Apt' + i + '">Application timing ' + i + ':</label></th><td><select name="Apt' + i + '" id="id_Apt' + i + '"><option value="" selected="selected">Select an application timing</option><option value="1">Default</option><option value="2">Enter your own</option></select></td></tr>').appendTo('.table')

            $('<tr class="app_dates"><th><label for="id_Date_apt">Application Date ' + i + ':</label></th><td><input readonly="readonly" type="text" name="Date_apt' + i + '" value="MM/DD" id="id_Date_apt' + i + '"/><td></tr>').appendTo('.table')

            $('.app_timing:last').find('select').bind('change', function() {
                if ($(this).val() == '1') {
                    $('.app_dates:last').hide()
                //$('#id_Date_apt' + i).hide() //I tried to use ID selector, but it does not work 
                }

            })
        }
    })


})​

preguntado el 10 de septiembre de 12 a las 22:09

Estás seleccionando específicamente la última app_date. Usar $('.app_dates') en lugar de $('.app_dates:last') para seleccionarlos todos. -

Como @NickG. dicho, aunque está vinculando múltiples eventos de la misma función en un ciclo for, creo que es mejor usarlo fuera de un ciclo. -

@Boltclock: la pregunta es basura - jQuery selector does not work properly, realmente no hay duda. Hay algo que pide sugerencias y algo que plantea un problema. Yes it does. es una respuesta perfectamente aceptable al título/pregunta -

@vol7ron: mi culpa por no seleccionar un título adecuado, ya que mi experiencia con la programación web es de solo varias semanas. Te agradezco si tienes un título mejor. -

@tao.hong: eso es comprensible, pero el problema es que no se supone que sea un título. Se supone que es una pregunta. Mi única preocupación es que en ningún momento a lo largo de su publicación hizo una pregunta. -

4 Respuestas

$('.app_dates:last').hide()

La línea anterior está dentro de la change controlador y no se ejecuta hasta que el controlador se dispara. En el momento en que se dispara, obtendrá el último elemento, lo que provoca el comportamiento que observaste. Puedes usar lo siguiente:

$(this).closest("tr").next().hide()

Tenga en cuenta que esto se basa en su html actual. Un cambio requeriría que esto cambie. Simplemente oculta la siguiente fila en la tabla.

EDIT:

Si bien lo anterior responde a la pregunta, un mejor enfoque general sería utilizar delegación de eventos. Esto le permitirá adjuntar un solo controlador en lugar de crear nuevos controladores cada vez que se cambie el menú desplegable. (Tenga en cuenta que agregué una clase a cada selección para simplificar el selector)

$(".table").on("change",".timeSel",function(){
    var $this = $(this);

    if ($this.val() == '1') {
        $(this).closest("tr").next().hide();
    }
});

http://jsfiddle.net/JDFcn/11/

Respondido el 10 de Septiembre de 12 a las 22:09

Gracias James Una pregunta, puedo agregar selectores entre paréntesis de siguiente, ¿verdad? (por ejemplo, siguiente (selector de jQuery)) - TTT

@tao.hong Puede, sin embargo, no irá más allá del siguiente elemento inmediato. - Kevin B

Reemplaza

$('.app_dates:last').hide()

con

$(this).closest('.app_timing').next().hide()

:last o utilizando i no funcionará debido al hecho de que el evento ocurrirá después de que se haya iterado todo el ciclo for.

Respondido el 10 de Septiembre de 12 a las 22:09

.app_dates no es un antepasado del selecto. - james montagne

@JamesMontagne Gracias, arreglado. - Kevin B

Tratar:

$('.app_timing:last').find('select').on('change', function() {
    if ($(this).val() == '1') {
        $(this).parents('tr').next('.app_dates').remove();
    }
})

ejemplo de jsFiddle

Esto eliminará la fila debajo de la fila que cambiaste a "predeterminada". Viaja hacia arriba en el DOM y luego vuelve a bajar para encontrar la fila que desea eliminar.

Respondido el 20 de junio de 20 a las 10:06

Cuando se llama a su función, intenta acceder a la variable i que se ha dejado incrementado a 1 más que el número que eligió en el menú desplegable superior, por lo que no puede usar eso. Su selector nunca devolverá nada.

Sugeriría tirar del valor para i fuera de la propiedad id de este que está disponible en la función anónima.

tal vez algo como esto:

var idx = this.id.substring(6);   // You may want something fancier here
$('#app_dates' + idx).hide();

Cuando hago ese cambio en tu jsFiddle, puedo hacer que desaparezca el primero.

Respondido el 10 de Septiembre de 12 a las 22:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.