2010-12-09 64 views
5

我有以下的HTML頁:的jQuery:選擇下一個輸入,即使在不同的字段集

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

現在,我想一直跳到下一inputfield。 我已經試過:

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

我以前沒有遇到過這個問題;一個有趣的問題(和** + 1 **)=) – 2010-12-09 09:36:27

+0

出於興趣,你爲什麼要在keydown處理程序中分配一個keydown處理程序? – Jamiec 2010-12-09 10:37:55

回答

1

我知道我還添加了它在我的主但是這很容易接受評論。 似乎有很多sollutions。

我現在自己的解決方案:

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

我試圖保持它非常straightfoward而靈活,我想我可以probabily簡化第二,如果一個位。

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它的邏輯是字段集中的最後一項。

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 fieldset,而是選取表單上的所有輸入。把它們放在一個陣列中,並通過聚焦它們來循環。我已經把所有東西放在它自己的閉包中,以使我創建的變量遠離其他所有東西。

當它到達最後一個輸入時,它會停止(如果沒有設置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。我不是jQuery返回項目的順序的100% - 我認爲它可能基於DOM結構。如果訂購中有任何異常,那麼在運行.each部件之前,可以使用元素的tabIndex值對inputs列表進行排序。

噢,是的,在這兩個例子中,我設置了keyup事件,以便它在我完成打字後立即移動。

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