AngularJS and Tab Order (Disabled Buttons)

时光毁灭记忆、已成空白 提交于 2019-12-11 03:16:22

问题


I have a form, and I'm navigating only with TAB. Tab order should be input > select > button, but because of the ng-disable on the SUBMIT, on certain browsers the TAB out of the select will kick you somewhere else.

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.

On Mac FF the final tab kicks you to the address bar before enabling the submit button. Mac Chrome works as you'd expect, focusing on the submit button after final tab. I know Windows is janky, but don't have exact specs to post.

Thoughts? How can I do this in a fool-proof fashion?

EDIT I've selected @David B.'s answer as it's the best Angular solution. I ended up using a somewhat hidden element right after the the submit button so the focus would stay in the same general area. Lame and hacky, I know, but for a tight deadline it worked.

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


This happens because Firefox doesn't send a change event on key-driven changes of the select. Angular doesn't see the change until the tab is hit, so the submit button isn't enabled until after the tab has been processed by the browser (and focus sent to some other element, e.g., the address bar). The W3C standard suggests not sending the event until the control loses focus, although Chrome sends one for any change and Firefox does if the change was mouse-driven.

See the angularjs issue tracker for more: https://github.com/angular/angular.js/issues/4216

As suggested in the issue tracker, solve it by manually issuing the change event via the following select directive (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");
            })
        }
    }
})

You'll need JQuery loaded before AngularJS to have the trigger function available on the element object.

Manually include an empty option (<option value=""></option>) in your select or the first option will be auto-selected when the control receives focus.

Unlike the default behavior, this empty option will not disappear after selecting a real option. I suppose you could remove the empty option by declaring all the options via ng-options or ng-repeat and then removing the empty one from the bound scope once a real option has been selected, but I've never tried it.



来源:https://stackoverflow.com/questions/23792570/angularjs-and-tab-order-disabled-buttons

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!