Skip to content

Focus first text field using jQuery

When it comes to focus the first text field on a page using jQuery , the usual solution would be:

$(":text:visible:enabled:eq(0)").focus();

This query means to find the first of input text field(s), which is/are visible and enabled. However, this would also extract text field(s) which is/are under a display:none parent(s). So a more complete way would be:

$(":text:visible:enabled").filter(function(){
     return $(this).parents(":hidden").size()==0;
 }).slice(0,1).focus();

The filter here would try to determine if the text field is a descendant of a hidden ancestor. The usage of slice(0,1) instead of get(0) is to keep the chainability. A test page is put up here .

Finally, you may wrap it up with a plugin:

(function($){
    $.fn.focusFirstField = function(){
        $this = this;
        $this.find(":text:visible:enabled").filter(function(){
            return $(this).parents(":hidden").size() == 0;
        }).slice(0,1).focus();
        return this;
    }
})(jQuery)

So that you can do this:

$("#form1,#form2").focusFirstField(); //form1 or form2 may be 'hidden' dynamically

I just wonder if there is any ‘selector-only’ solution for this?

Update: It turns out that the child’s visiblity would override parent’s visibility. So the filter should only check display none:

$(":text:visible:enabled").filter(function(){
     return $(this).parents.filter(function(){ 
         return this.style.display == "none"; })
    .size()==0;
 }).slice(0,1).focus();

I’ve updated the demo page .

Jacky14 Apr 2008 12:03 am 寫關於電腦

Tags: , , 。 [ 永久連結 | 引用 | 回應 RSS ]

7 個留言

  1. 用 prototype 的話我會這樣:

    
     Event.observe(window, 'load', function() {
    	try{
    		($$('form')[0]).focusFirstElement();
    	} catch (e) {}
     });
    

    ( 在page load 完後才 focus )

  2. 呃... 上面 [ 0 ] 變了 [0]

  3. Can this function handle when
    1) style="display:none" on the input?
    2) the form itself is under a div with display:none?

  4. anonymous 寫於 14 Apr 2008 10:34 am

    Why slice() instead of eq()?

    http://docs.jquery.com/Core/eq#position

  5. 
      findFirstElement: function(form) {
        var elements = $(form).getElements().findAll(function(element) {
          return 'hidden' != element.type && !element.disabled;
        });
        var firstByIndex = elements.findAll(function(element) {
          return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
        }).sortBy(function(element) { return element.tabIndex }).first();
        return firstByIndex ? firstByIndex : elements.find(function(element) {
          return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
        });
      },
      focusFirstElement: function(form) {
        form = $(form);
        form.findFirstElement().activate();
        return form;
      }
    

    form 或 form 上層的 elements 是 hidden ... 是不行的

  6. anonymous: yes, can use eq() also.

    小影: that's my interest... multiple forms, which may be 'hidden'

  7. BTW, eq() also uses slice()

發表回應