Focus on the first field that is .ng-invalid at Submit - not working for radios-inline

百般思念 提交于 2019-12-24 00:33:49

问题


I am using the directive from accepted answer on Set focus on first invalid input in AngularJs form to accomplish this:

app.directive('accessibleForm', function () {
    return {
        restrict: 'A',
        link: function (scope, elem) {

            // set up event handler on the form element
            elem.on('submit', function () {

                console.log("inside focus directive");
                // find the first invalid element
                var firstInvalid = elem[0].querySelector('.ng-invalid');
                //if we find one, set focus
                if (firstInvalid) {
                    firstInvalid.focus();
                }
            });
        }
    };
});

As long as I do not use radios-inline the focus works. Please refer: http://jsfiddle.net/mutharasus/mu7y4k8f/

But if the first error happens to be on a radios-inline field the focus does not work. Please refer: http://jsfiddle.net/mutharasus/00jzbL6g/

I am not sure how to fix. Please help.


回答1:


The radio-inline is adding the ng-invalid class to the field label instead of to each individual radio input.

You could change that directive and implement your desired behaviour in your custom one (you would need to add ng-invalid to each radio input) or change the accessibleForm directive to check if the invalid element is a label and, in that case, find the the first radio input associated to it:

app.directive('accessibleForm', function () {
    return {
        restrict: 'A',
        link: function (scope, elem) {

            // set up event handler on the form element
            elem.on('submit', function () {

                console.log("inside focus directive");

                // find the first invalid element
                var firstInvalid = elem[0].querySelector('.ng-invalid');

                // If we got a label, then it is a radio-inline
                if(firstInvalid && firstInvalid.tagName === 'LABEL') {
                    firstInvalid =  elem[0].querySelector('.ng-invalid + div input[type=radio]')
                }

                firstInvalid && firstInvalid.focus();

            });
        }
    };
});

Although it may seem like the easiest solution, it does not look right for me to have that second query selector that depends so much on the structure of that specific directive, as if that changes then the accessibleForm directive will be broken again.




回答2:


I think the problem is that the label of each radio has the '.ng-invalid' class, but not the radio input element itself, which comes afterwards anyway. Your query selector is inadvertently returning the label's element and then uselessly calling focus()' on it.

This is the element that focus is called on if the radio is invalid:

<label ng-model="model['Field1']" ng-model-options="form.ngModelOptions" schema-validate="form" class="control-label  ng-valid-schema-form ng-dirty ng-invalid ng-invalid-tv4-302" ng-show="showTitle()">Field1</label>

The labels for the other types of controls do not have the .ng-invalid class so they are not bothered by this problem.

I'm not familiar with these libraries, so the answer depends. Either improve the selector or change how the labels of the radio inputs are styled.

Here's a version of the jsFiddle that I've hacked to demonstrate that it's the selector that's preventing the focus from occurring. Just click submit without changing the form.



来源:https://stackoverflow.com/questions/33904683/focus-on-the-first-field-that-is-ng-invalid-at-submit-not-working-for-radios

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