简体   繁体   中英

AngularJS directive blur event not setting validation

I am trying to make a custom AngularJS directive for the first time where a few currency validation checks are done and the form validity is set. I am trying to set up a blur event using link that validates the user input and then adds CSS and html elements if any of the validation checks fail. Here is what I have so far:

angular.module('sharedDirectives', []).directive('abccurrency', function () {
return {
    restrict: "A",
    require: 'ngModel',
    replace: true,
    link: function (scope, element, attr, ctrl) {
        var commaRegEx = /^(?:\d+(?:,\d{3})*(?:\.\d{2})?)$/;
        var min = 0;
        var max = 99999.99;

        element.bind('blur', function (value) {

            var valueNoComma = parseFloat(value.currentTarget.value.replace(/,/g, ''));
            ctrl.$setViewValue(String(value.currentTarget.value).replace(/,/g, ''));

            var validCommas = commaRegEx.test(value.currentTarget.value);
            ctrl.$setValidity('commaValidate', validCommas);

            if (validCommas === true) {
                var aboveMin = min < valueNoComma;
                ctrl.$setValidity('minValidate', aboveMin);
            }

            if (validCommas === true) {
                var belowMax = valueNoComma <= max;
                ctrl.$setValidity('maxValidate', belowMax);
            }
        });
    }
};
});

Here is an example of the html I am trying to apply this directive to:

<form name="testform">
<div class="row top-buffer15">
    <div class="col-md-3" ng-class="{'has-error' : testform.currencytest.$invalid && testform.currencytest.$touched}">
        <input type="text" ng-model="matchpay.test" id="currencytest" name="currencytest" class="form-control" abccurrency>
        <p style="color: red" ng-show="testform.currencytest.$error.commaValidate">Currency fields must the form XX,XXX.XX or XXXXX.XX.</p>
        <p style="color: red" ng-show="testform.currencytest.$error.minValidate">Currency fields must be more than zero.</p>
        <p style="color: red" ng-show="testform.currencytest.$error.maxValidate">Currency fields cannot be more than $99,999.99.</p>
    </div>
</div>
</form>

Now my problem is that in one area of the project, this works just as expected. The user enters their input and the CSS styling and error notification html is displayed. In another area, though, the blur event doesn't actually change anything, even though the code in the directive is ran. Only after you click in and out of the input, is the correct validation information displayed. Is there something immediately obvious that I am doing wrong? It is unclear to me why it would work in one place but not another. Please let me know if you need additional information, I'd be happy to post screenshots of the difference in functionality.

After doing some research and confirming this should work. I tried putting the $setViewValue call at the end to see if that would do anything. As it turns out, it indeed prevent the $setValidity calls for whatever reason. Any ideas as to why? This refactor allows the directive to correctly notify the user of incorrect input.

element.bind('blur', function (value) {

            var valueNoComma = parseFloat(value.currentTarget.value.replace(/,/g, ''));

            var validCommas = commaRegEx.test(value.currentTarget.value);
            var aboveMin = min < valueNoComma;
            var belowMax = valueNoComma <= max;

            ctrl.$setValidity('commaValidate', validCommas);
            ctrl.$setValidity('minValidate', aboveMin);
            ctrl.$setValidity('maxValidate', belowMax);
            ctrl.$setViewValue(String(value.currentTarget.value).replace(/,/g, ''));


        });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM