2010-12-09 11 views
5

tengo la siguiente página HTML:jQuery: seleccione la próxima entrada, aunque en diferentes fieldset

<form action="editProfile" id="userInformation"> 
<fieldset id="birthdate"> 
<label><input type="text" id="day" maxlength="2"/>/<input type="text" id="month" maxlength="2"/>/<input type="text" id="year" maxlength="2"/> 
</fieldset> 
<fieldset> 
<label>Name</label><input type="text" id="name"/> 
</fieldset> 
</div> 

Ahora me gustaría ir siempre a la siguiente InputField. He intentado:

$("#birthdate input[type=text]").keyup(function(e){ 
    if($(this).val().length == $(this).attr('maxlength')){ 
     $(this).next(":input").focus(); 
    } 
}); 

pero que parece mantenerse dentro del grupo de campos. Y nextall no parece funcionar o lo estoy usando mal.

edición: Mi solución hasta el momento:

 if($(this).val().length == $(this).attr('maxlength')){ 
      if($(this).parent().children().last().attr('id') == $(this).attr("id")){ 
       $(this).parent().next().find(':input').focus(); 
      }else{ 
       $(this).next("input").focus(); 
      } 
     } 
+0

No había encontrado este problema antes; una pregunta interesante (y ** + 1 **) =) –

+0

Fuera de interés, ¿por qué asigna un manejador de teclas, dentro de un manejador de teclas? – Jamiec

+0

Overlooked that one. – jack

Respuesta

1

Sé También he añadido en mi principal publicar pero es más fácil recibir comentarios. Parece que hay muchas soluciones.

Mi propia solución por ahora:

if($(this).val().length == $(this).attr('maxlength')){ 
      if($(this).parent().children().last().attr('id') == $(this).attr("id")){ 
       $(this).parent().next().find(':input').focus(); 
      }else{ 
       $(this).next("input").focus(); 
      } 
     } 

traté de mantenerlo bastante straightfoward pero flexible Creo que probabily podría simplificar el segundo si un poco.

1

Aquí es una solución utilizando un método personalizado (ejemplo de trabajo: http://jsfiddle.net/jamiec/uQdSS/)

(function($) { 
    $.fn.nextOrParentNext = function(sel){ 
     var $next = $(this).next(sel); 
     if($next.length) 
     { 
       return $next; 
     } 
     else 
     { 
      var $nextParent = $(this).parent().next().find(sel); 
      if($nextParent.length) 
      { 
       return ($nextParent); 
      } 
     }     
    }; 
})(jQuery); 

$("#birthdate input:text").keydown(function(e){ 
    if($(this).val().length == $(this).attr('maxlength')){ 
     $(this).nextOrParentNext(":input").focus(); 
    } 
}); 

básicamente, el plug-in de encargo envuelve el if/else lógica de que sea el último elemento en un fieldset.

+0

Esa es una solución, por supuesto, pero que aún requiere una estructura if else para comprobar si el campo de entrada actual es el último campo de entrada en la sección actual. ¿Hay alguna forma de evitar esto? – jack

+0

@jack - ver respuesta actualizada – Jamiec

0

Esta es una solución. Probablemente no sea la mejor solución, pero parece que funciona mediante el operador módulo vejez al ciclo de las entradas:

(function() { 
    var inputs = $("#userInformation input[type=text]"), 
     i = 0, 
     length = inputs.length; 

    inputs.keyup(function(e) { 
     if ($(this).val().length == $(this).attr('maxlength')) { 
      i = ++i % length; 
      inputs[i].focus(); 
     } 
    }); 

}()); 

Ejemplo: http://jsfiddle.net/jonathon/DysJe/

También he hecho un cambio en el selector para las entradas. En lugar de simplemente seleccionar el fieldset birthdate, recojo todas las entradas en el formulario. Pega estos en una matriz y cíñelos centrándote en ellos. He puesto todo en su propio cierre para mantener las variables que he creado escondidas de todo lo demás.

Cuando llega a la última entrada, simplemente se detendrá (si maxlength no está ajustado) o volverá a iniciar el enfoque al principio. Si no desea que se complete el ciclo, simplemente elimine el operador de módulo.

Se tiene un inconveniente, aunque: si el usuario no se centra en el primer elemento de entonces se ignorará esto y sólo tiene que ir a centrar el segundo, tercero, etc.


I hizo un poco más sobre esto y eliminó la necesidad de la otra variable. Este no funciona el siguiente sobre la marcha, está configurado desde el principio. Cada input tiene su evento configurado para enfocar el siguiente elemento en la lista inputs en lugar del siguiente elemento i. No va a recorrer similar a la anterior pero se moverá correctamente por lo que si las lengüetas de usuario a la segunda, que va a pasar a la tercera, etc.

(function() { 
    var inputs = $("#userInformation input"); 

    inputs.each(function(i, item) { 
     $(item).keyup(function() { 
      if ($(this).val().length == $(this).attr('maxlength') && inputs[i + 1]) { 
       inputs[i + 1].focus(); 
      } 
     }); 
    }); 
}()); 

http://jsfiddle.net/jonathon/TQzKS/

Es posible que desee configure el tabIndexes para sus elementos de entrada también. No estoy al 100% en el orden en que jQuery devuelve los artículos; creo que podría estar basado en la estructura DOM. Si hay algo inusual en su pedido, entonces puede usar el valor tabIndex del elemento para ordenar la lista inputs antes de ejecutar la parte .each.

Oh sí, y en ambos ejemplos establecí el evento keyup para que se mueva tan pronto como termine de escribir.

0

he usado algo como esto recientemente, que funciona bien:

function goToInput(distance) { 
    var $input = $(this), 
     $inputs = getInputs(), 
     currentIndex = $inputs.index($input), 
     newIndex = ($inputs.length + currentIndex + distance) % $inputs.length; 

    if (currentIndex > -1) { 
     $input.blur(); 
     $inputs.eq(newIndex).focusin().focus(); 
    } 
} 

function getInputs() { 
    return $('#userInformation :input:visible:enabled'); 
} 

function goToNextInput() { 
    goToInput.apply(this, [1]); 
} 

function goToPreviousInput() { 
    goToInput.apply(this, [-1]); 
} 

y luego

getInputs().keyup(goToNextInput); 
1

Prueba esto:

$("#birthdate input[type=text]").keyup(function(e){ 
    if($(this).val().length == $(this).attr('maxlength')){ 
     var $next = $(this).next(":input"); 
     if ($next.length == 0) // there are no next fields! try another fieldset 
     $next = $(this).closest("fieldset").next("fieldset").find(":input:first"); 
     $next.focus(); 
    } 
}); 
Cuestiones relacionadas