AngularJS和Tab顺序(禁用按钮)

时间:2014-05-21 19:53:19

标签: forms angularjs user-experience

我有一个表单,我只使用TAB导航。应输入Tab键顺序>选择>按钮,但是由于SUBMIT上的ng-disable,在某些浏览器上,选择中的TAB会将你踢到其他地方。

HTML

<div ng-app="myApp">
    <div ng-controller="FirstCtrl">
        <form name="myForm" ng-submit="submit()" novalidate>    
            First Name: <input type="text" ng-model="Data.FirstName" required><br>
            Last Name: <select ng-model="Data.LastName" required>
                <option value="Bigglesworth">Bigglesworth</option>
                <option value="Burgermeister">Burgermeister</option>
            </select><br>
            <input type="submit" value="Submit" ng-disabled="myForm.$invalid" />
        </form>
    </div>
</div>

JS

var myApp = angular.module('myApp', []);

myApp.factory('Data', function(){
    return {
        FirstName: '',
        LastName: ''
    };
});

myApp.controller('FirstCtrl', function( $scope, Data ){
    $scope.Data = Data;
    $scope.submit = function() {
        console.log('you just submitted, foolio');
    }
});

JsFiddle here.

在Mac FF上,最终选项卡会在启用提交按钮之前将您踢到地址栏。 Mac Chrome按照您的预期工作,专注于最终标签后的提交按钮。我知道Windows很简陋,但没有确切的规格要发布。

思考?我怎么能以万无一失的方式做到这一点?

修改 我选择了@David B.的答案,因为它是最好的Angular解决方案。我最后在提交按钮后面使用了一个隐藏元素,因此焦点将保持在相同的一般区域。我知道Lame和hacky,但是在最后期限之前它起作用了。

<h3><button class="fakebtn_hack">Confirmation</button></h3>
<style>.fakebtn_hack {background:none; border:none; color: #FF6319; cursor: default; font-size: 1em; padding: 0;}</style>

1 个答案:

答案 0 :(得分:2)

这是因为Firefox不会对select的键驱动更改发送更改事件。在选项卡被点击之前,Angular看不到更改,因此在浏览器处理选项卡之后才会启用提交按钮(并将焦点发送到其他某个元素,例如地址栏) 。 W3C标准建议不要在控件失去焦点之前发送事件,尽管Chrome会发送一个用于任何更改,而Firefox会在鼠标驱动下进行更改。

请参阅angularjs问题跟踪器了解更多信息:https://github.com/angular/angular.js/issues/4216

正如问题跟踪器中所建议的那样,通过以下select指令(http://jsfiddle.net/j5ZzE/)手动发出更改事件来解决它:

myApp.directive("select", function () {
    return {
        restrict: "E",
        require: "?ngModel",
        scope: false,
        link: function (scope, element, attrs, ngModel) {
            if (!ngModel) {
                return;
            }
            element.bind("keyup", function () {
                element.trigger("change");
            })
        }
    }
})

你需要在 AngularJS之前加载,以便在trigger对象上提供element函数。

在您的选择中手动添加一个空选项(<option value=""></option>),或者当控件获得焦点时,将自动选择第一个选项。

与默认行为不同,选择实际选项后,此空选项不会消失。我想你可以通过ng-optionsng-repeat声明所有选项来删除空选项,然后在选择了真实选项后从绑定范围中删除空选项,但我从来没有试了一下。