如何将焦点设置到表单中第一个可编辑的输入元素?

13
动态创建的表单包含输入元素。首先的元素可能是被禁用或只读的。我尝试使用下面的代码将焦点设置到第一个可接受数据的元素,以便从键盘快速输入数据。但是如果表单第一个元素是禁用或只读的,焦点就无法设置。如何将焦点设置到第一个可接受数据的元素?
    <form style='margin: 30px' id="Form" class='form-fields' method='post' target='_blank'
    action='Report/Render'>
...
    <input id='_submit' type='submit' value='Show report' class='button blue bigrounded' />
    </form>
    <script type="text/javascript">
        $(function () {
            var elements = $('#Form').find(':text,:radio,:checkbox,select,textarea');
            elements[0].focus();
            elements[0].select();
});
</script>

更新

还有隐藏的输入字段,抱歉。提供的答案将焦点设置到隐藏元素上。包含函数未找到任何元素。

以下是更新的测试用例:

$(function () {
  $("#form :input:not([readonly='readonly']):not([disabled='disabled'])").first() 
                                                                        .focus(); 
});

如何将焦点设置到可见、启用且非只读元素?
更新3
我尝试了Row W代码,其中添加了输入元素。现在它将焦点设置到第二个元素。测试用例显示在Rob W的答案修订版5中。

1
请参考以下链接:https://dev59.com/R3I-5IYBdhLWcg3w99kH - DOK
2个回答

10

请使用以下代码:

var elements = $('#Form').find(':text,:radio,:checkbox,select,textarea').filter(function(){
    return !this.readOnly &&
           !this.disabled &&
           $(this).parentsUntil('form', 'div').css('display') != "none";
});
elements.focus().select();
如果你只想选择第一个元素,以下代码更有效率:
$('#Form').find(':text,:radio,:checkbox,select,textarea').each(function(){
    if(!this.readOnly && !this.disabled &&
                $(this).parentsUntil('form', 'div').css('display') != "none") {
        this.focus();  //Dom method
        this.select(); //Dom method
        return false;
    }
});

更新:如果你想要元素保持相同的顺序,请使用:

var elements = $("#form").find("*").filter(function(){
   if(/^select|textarea|input$/i.test(this.tagName)) { //not-null
       //Optionally, filter the same elements as above
       if(/^input$/i.test(this.tagName) && !/^checkbox|radio|text$/i.test(this.type)){
           // Not the right input element
           return false;
       }
       return !this.readOnly &&
              !this.disabled &&
              $(this).parentsUntil('form', 'div').css('display') != "none";
   }
   return false;
});

谢谢。还有隐藏的div包含输入元素。如何跳过隐藏的div?我更新了问题。 - Andrus
1
@Andrus 更新了具有最高效解决方案的答案。 - Rob W
1
IDs区分大小写。使用大写字母f$('#Form')。已更新的答案。 - Rob W
如果将最后的代码移动到单独的方法中,它就找不到任何元素了。我更新了问题并提供了测试用例。如何修复? - Andrus
1
@Andrus 这个函数展示了一种按正确顺序选择所有“有效”元素的方法。如果你只想获取第一个元素,使用 elements.eq(0).focus().select():http://jsfiddle.net/adQaN/ - Rob W
显示剩余4条评论

4
使用jQuery的:not()选择器:
$("#myForm :input:not([readonly='readonly']):not([disabled='disabled']):reallyvisible").first()
                                                                                      .focus();

这里是一个可工作的fiddle

编辑:

为了满足您在评论中发布的新要求,您需要扩展:visible选择器以检查父级的可见性(未经测试):

jQuery.extend(
  jQuery.expr[ ":" ], 
  { reallyvisible : function (a) { return !(jQuery(a).is(':hidden') || jQuery(a).parents(':hidden').length); }}
);

谢谢。页面可能包含#Form之外的输入元素,所以我认为它可能会聚焦到错误的元素。如何仅将其应用于表单#Form? - Andrus
1
@Andrus,将选择器添加#form。我已经更新了我的答案和fiddle。 - James Hill
谢谢。表单中还有<div style='display:none'>的div。如何忽略隐藏div中的输入元素?我更新了问题。 - Andrus
2
@Andrus,问题被回答后大幅度修改并不合适——这会使所有现有的答案失效。 - James Hill
非常抱歉。我另外添加了更新的内容到问题的末尾。非常感谢您的快速帮助。我已经为您的答案和评论点赞。 - Andrus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接