jquery:即使在不同的fieldset中选择下一个输入

时间:2010-12-09 09:05:35

标签: jquery

我有以下html页面:

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

现在我想总是跳到下一个输入字段。 我试过了:

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

但这似乎仍然属于该字段集。并且nextall似乎不起作用或我使用它错了。

编辑: 到目前为止我的解决方案:

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

5 个答案:

答案 0 :(得分:1)

以下是使用自定义方法的解决方案(工作示例: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();
    }
});

基本上,自定义插件将if / else逻辑包装为字段集中的最后一项。

答案 1 :(得分:1)

试试这个:

$("#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();
    }
});

答案 2 :(得分:1)

我知道我也在主帖中添加了它,但这更容易收到评论。 似乎有很多解决方案。

我现在的解决方案:

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

我试图保持它非常直接而且灵活,我想我可能会简单地简化第二个。

答案 3 :(得分:0)

这是一个解决方案。可能不是最好的解决方案,但似乎使用老化模数运算符来循环输入:

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

}());

示例:http://jsfiddle.net/jonathon/DysJe/

我还对输入的选择器进行了更改。我只选择表单上的所有输入,而不仅仅是选择birthdate字段集。将它们粘在一个数组中并循环聚焦它们。我把所有内容放在它自己的闭包中,以保持我创建的变量远离其他任何东西。

当它到达最后一个输入时,它将停止(如果未设置maxlength)或它将再次循环焦点。如果您不希望它循环,只需删除模数运算符。

它确实有一个缺点:如果用户没有专注于第一个元素,那么它将忽略它,然后继续聚焦第二个,第三个等。


我对此做了一点点,并删除了对其他变量的需求。这个在飞行中不能解决下一个问题,它在一开始就设定了。每个input都将其事件设置为将下一个项目集中在inputs列表中,而不是下一个元素i。它不会像上面那样循环,但它会正确移动,所以如果用户选中第二个,它将进入第三个,等等。

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

您可能还想为输入元素设置tabIndexes。我不是100%依赖于jQuery返回项目的顺序 - 我认为它可能基于DOM结构。如果您的订购中有任何异常,那么您可以使用元素的tabIndex值对inputs列表进行排序,然后再运行.each部分。

哦,是的,在这两个示例中,我设置了keyup事件,以便在我完成输入后立即移动。

答案 4 :(得分:0)

我最近使用过这样的东西,效果很好:

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

然后

getInputs().keyup(goToNextInput);