【问题标题】:AngularJS Custom date of birth input does not show required errorAngularJS自定义出生日期输入不显示必需的错误
【发布时间】:2016-09-09 21:18:14
【问题描述】:

我正在制作没有日历视图的出生日期类型的输入元素。即用户通过键入来填写日期。

代码

angular.module('myApp', [])
.directive('birthDatePicker', [ function () {
        return {
            restrict: 'A',
            require: 'ngModel',
            scope: {
                model: '=ngModel',
            },
            link: function (scope, element, attrs, ngModel) {

                //SET CURSOR POSITION
                var setCursorPosition = function(pos) {
                    if (element[0].setSelectionRange) {
                        element[0].focus();
                        element[0].setSelectionRange(pos, pos);
                    } else if (element[0].createTextRange) {
                        var range = element[0].createTextRange();
                        range.collapse(true);
                        range.moveEnd('character', pos);
                        range.moveStart('character', pos);
                        range.select();
                    }
                };

                // RESET VALIDATION ERRORS
                var resetErrors = function() {
                    ngModel.$setValidity('pattern',true);
                };

                if (!ngModel) return;
                var d1, d2, m1, m2, y1, y2, y3, y4, cursorPos, dateString, parsedDate;
                ngModel.$parsers.unshift(function (inputValue) {
                    var digits = inputValue.split('').filter(function (s) { return (!isNaN(s) && s != ' '); });
                    d1 = digits[0] ? digits[0] : 'd';
                    d2 = digits[1] ? digits[1] : 'd';
                    m1 = digits[2] ? digits[2] : 'm';
                    m2 = digits[3] ? digits[3] : 'm';
                    y1 = digits[4] ? digits[4] : 'y';
                    y2 = digits[5] ? digits[5] : 'y';
                    y3 = digits[6] ? digits[6] : 'y';
                    y4 = digits[7] ? digits[7] : 'y';
                    dateString = d1+d2+'/'+m1+m2+'/'+y1+y2+y3+y4;

                    resetErrors();

                    if(dateString == 'dd/mm/yyyy') {
                        ngModel.$viewValue = '';
                        ngModel.$render();
                        return ngModel.$viewValue;
                    }

                    ngModel.$viewValue = dateString;
                    ngModel.$render();
                    cursorPos = digits.length + 2;
                    if(digits.length < 3) {
                        cursorPos = digits.length;
                    } else if (digits.length < 5) {
                        cursorPos = digits.length + 1;
                    }

                    setCursorPosition(cursorPos);

                    parsedDate = new Date(ngModel.$viewValue);

                    // validation for correct date
                    if(isNaN(parsedDate.getTime())){
                        ngModel.$setValidity('pattern',false);
                        return ngModel.$viewValue;
                    } else {
                        ngModel.$setValidity('pattern',true);
                    }

                    return ngModel.$viewValue;
                });
            }
        };
    }]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
<body ng-app="myApp">
  <form name="myForm" novalidate>
  <input ng-model="date" name="question"
             placeholder="dd/mm/yyyy" birth-date-picker type="tel" autocomplete="off" required>
  <p ng-show="myForm.question.$error.required">Date is Required</p>
  <p ng-show="myForm.question.$error['pattern']">Date is incorrect</p>
  <input type="submit">
  </form>
</body>

问题在于显示错误消息。消息Date is required 仅在第一次显示并且如果提交按钮被按下。当用户按backspace键清除输入值时,它不起作用。

更新: 在AngularJS 的较低版本上,它可以正常工作,但对于AngularJS 1.5.8,我运气不好。 :(

请帮我解决这个问题。

编码愉快!

【问题讨论】:

  • 我工作得很好!我在这里没有看到任何问题或问题......可能是我没有完全明白你的问题,你能详细说明吗?
  • @Angular_10 是的,功能完美。但是有一个小问题,请按照以下步骤操作 - 1. 开始填写日期,2. 按退格键清除字段,3. 您应该会看到一条消息“需要日期”,但实际上您看不到它,除非您按提交按钮。
  • 是的,我刚刚观察到!那么在这种情况下,你可以做的是用 ng-keydown 抓住退格事件,并在你的指令中编写一个函数来设置相应的消息。它对我有用!
  • @Angular_10 谢谢,你说的对我也有效,但我会等待具体的解决方案。

标签: angularjs html


【解决方案1】:

根据https://docs.angularjs.org/api/ngMessages/directive/ngMessages 的文档和该页面上的示例,这就是您应该如何使用 ng-messages...

angular.module('myApp', [])
.directive('birthDatePicker', [ function () {
        return {
            restrict: 'A',
            require: 'ngModel',
            scope: {
                model: '=ngModel',
            },
            link: function (scope, element, attrs, ngModel) {

                //SET CURSOR POSITION
                var setCursorPosition = function(pos) {
                    if (element[0].setSelectionRange) {
                        element[0].focus();
                        element[0].setSelectionRange(pos, pos);
                    } else if (element[0].createTextRange) {
                        var range = element[0].createTextRange();
                        range.collapse(true);
                        range.moveEnd('character', pos);
                        range.moveStart('character', pos);
                        range.select();
                    }
                };

                // RESET VALIDATION ERRORS
                var resetErrors = function() {
                    ngModel.$setValidity('pattern',true);
                };

                if (!ngModel) return;
                var d1, d2, m1, m2, y1, y2, y3, y4, cursorPos, dateString, parsedDate;
                ngModel.$parsers.unshift(function (inputValue) {
                    var digits = inputValue.split('').filter(function (s) { return (!isNaN(s) && s != ' '); });
                    d1 = digits[0] ? digits[0] : 'd';
                    d2 = digits[1] ? digits[1] : 'd';
                    m1 = digits[2] ? digits[2] : 'm';
                    m2 = digits[3] ? digits[3] : 'm';
                    y1 = digits[4] ? digits[4] : 'y';
                    y2 = digits[5] ? digits[5] : 'y';
                    y3 = digits[6] ? digits[6] : 'y';
                    y4 = digits[7] ? digits[7] : 'y';
                    dateString = d1+d2+'/'+m1+m2+'/'+y1+y2+y3+y4;

                    resetErrors();

                    if(dateString == 'dd/mm/yyyy') {
                        ngModel.$viewValue = '';
                        ngModel.$render();
                        return ngModel.$viewValue;
                    }

                    ngModel.$viewValue = dateString;
                    ngModel.$render();
                    cursorPos = digits.length + 2;
                    if(digits.length < 3) {
                        cursorPos = digits.length;
                    } else if (digits.length < 5) {
                        cursorPos = digits.length + 1;
                    }

                    setCursorPosition(cursorPos);

                    parsedDate = new Date(ngModel.$viewValue);

                    // validation for correct date
                    if(isNaN(parsedDate.getTime())){
                        ngModel.$setValidity('pattern',false);
                        return ngModel.$viewValue;
                    } else {
                        ngModel.$setValidity('pattern',true);
                    }

                    return ngModel.$viewValue;
                });
            }
        };
    }]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
<body ng-app="myApp">
  <form name="myForm" novalidate>
  <input ng-model="date" name="question"
             placeholder="dd/mm/yyyy" birth-date-picker type="tel" autocomplete="off" required>
<div ng-messages="myForm.question.$error" role="alert">
      <div ng-message="required">Date is Required</div>
      <div ng-message="pattern">Date is incorrect</div>
</div>
  <input type="submit">
  </form>
</body>

【讨论】:

  • 运行代码 sn-p 时总是显示错误消息。
【解决方案2】:

您正在尝试包装 ng-model 的错误方法。 试试Ben Nadel approach,应该能说明问题。

【讨论】:

    猜你喜欢
    • 2013-08-23
    • 2013-05-11
    • 2016-01-03
    • 1970-01-01
    • 2022-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多