Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用angularjs处理三部分日期字段验证_Javascript_Angularjs - Fatal编程技术网

Javascript 使用angularjs处理三部分日期字段验证

Javascript 使用angularjs处理三部分日期字段验证,javascript,angularjs,Javascript,Angularjs,我需要在angular js中验证一个由三部分组成的日期字段。我已经创建了一个自定义验证函数,但是在设计字段如何更新彼此状态的逻辑时遇到了问题 我如何才能让所有三个表单字段唱出同一首赞美诗,并根据其他字段显示其有效或无效状态 这是小提琴: 和代码: <div ng-app="myApp" ng-controller="myCtrl"> <form action="" name="myForm"> <div class="date-group"

我需要在angular js中验证一个由三部分组成的日期字段。我已经创建了一个自定义验证函数,但是在设计字段如何更新彼此状态的逻辑时遇到了问题

我如何才能让所有三个表单字段唱出同一首赞美诗,并根据其他字段显示其有效或无效状态

这是小提琴:

和代码:

<div ng-app="myApp" ng-controller="myCtrl">
    <form action="" name="myForm">
        <div class="date-group">
            <input type="text" name="day" ng-model="day" ng-valid-func="validator" />
            <input type="text" name="month" ng-model="month" ng-valid-func="validator" />
            <input type="text" name="year" ng-model="year" ng-valid-func="validator" />
        </div>
    </form>
</div>
而且

input.ng-invalid{
    background-color: #fdd !important;    
}

input.ng-valid{
    background-color: #dfd !important;    
}

input{
    display: inline;
    width: 3em;
}
var app = angular.module('myApp', [])

var myCtrl = function($scope){

    $scope.day = "01"
    $scope.month = "01"
    $scope.year = "2000"

    $scope.validator = function(val){
        var day = $('[name=day]').val()
        var month = $('[name=month]').val()
        var year = $('[name=year]').val()
        var d = new Date([year,month,day].join('-'))
        console.log(d, [year,month,day].join('-'))
        return d > new Date('2000-01-01')
    }

}

app.directive('ngValidFunc', function() {
  return {
    require: 'ngModel',
    link: function(scope, elm, attrs, ctrl) {
      ctrl.$parsers.unshift(function(viewValue) {
        if (attrs.ngValidFunc && scope[attrs.ngValidFunc] && scope[attrs.ngValidFunc](viewValue, scope, elm, attrs, ctrl)) {
          ctrl.$setValidity('custom', true);
        } else {
          ctrl.$setValidity('custom', false);
        }
        return elm.val()
      });
    }
  };
});

实际上,您最好只使用
input type=“number”
max
min
验证器,并添加调用函数更新日期的
ng change
指令

由于如果输入内容无效,则不会触发更改,因此您永远不会得到“错误”日期:


但是使用月和日的文本框可能是不好的解决方案,因为这将变得更加复杂,确保日值符合犹太标准。(以二月和闰年为例)。对于整个解决方案,我建议至少在几天内使用下拉列表,也可能在一个月内使用下拉列表。。。因为有一组固定的结果是必需的,并且您可以根据月份选项的值显示或隐藏日期选项

下面是一个例子:

<form name="myForm">
    <input type="number" name="year" ng-model="year" min="2000" ng-change="updateDate()"/>
    <select name="month" ng-model="month" ng-change="updateDate()">
      <option value="1">Jan</option>
      <option value="2">Feb</option>
      <option value="3">Mar</option>
      <option value="4">Apr</option>
      <option value="5">May</option>
      <option value="6">Jun</option>
      <option value="7">Jul</option>
      <option value="8">Aug</option>
      <option value="9">Sep</option>
      <option value="10">Oct</option>
      <option value="11">Nov</option>
      <option value="12">Dec</option>
    </select>
    <select name="day" ng-model="day" ng-change="udpateDate()">
      <option>1</option>
      <option>2</option>
      <option>3</option>
      <!-- ... SNIP!... -->
      <option>27</option>
      <option>28</option>
      <option ng-show="month != 2 || !(year % 4)")>
        29
      </option>
      <option ng-show="month != 2">
        30
      </option>
      <option ng-show="month == 1 || month == 3 || month == 5 || month == 7 || 
          month == 8 || month == 10 || month == 12">
        31
      </option>
    </select>
    <p>
      {{date | date: 'yyyy-MMM-dd'}}
    </p>
  </form>

简
二月
破坏
四月
也许
六月
七月
八月
九月
十月
十一月
12月
1.
2.
3.
27
28
29
30
31

{{date}日期:'yyyy-MMM-dd'}

但是,为什么不动态创建这些选择呢?

您能否动态创建上述选择?当然值得吗?大概可能不会。只需30秒即可将选项与show/hyde逻辑一起键入

在上述两种情况下,您只需验证2001年的年度验证:

<span ng-show="myForm.year.$error.min">Must be after January 1, 2001</span>
必须在2001年1月1日之后

我也在寻找AngularJS的三部分日期字段验证,以下是我所做的(为我工作)

HTML:


日期(年月日):
-
-

必修的! 太短了! 不是有效日期!
提交
脚本:

function Controller ($scope) {
    $scope.notValidDate = false;
    $scope.somefuncion = function(event) {
        if ($scope.myForm.$valid) {
            alert("Form is working as expected");
            return true;
        }
        else
        {
            alert("Something is not correct");
            return false;
        }
    };
    $scope.validateDOB  = function(mm,dd,yyyy)
    {
        var flag = true;
        var month = mm;
        var date = dd;
        var year = yyyy;
        if(month == null || date == null || year == null || month.length != 2 || date.length!= 2 || year.length!= 4)
            flag = false;
        if(month < 1 || month > 12)
            flag = false;
        if(year < 1900 || year > 2100)
            flag = false;
        if(date < 1 || date > 31)
            flag = false;

        if((month == 04 || month == 06 || month == 9 || month == 11) && (date >= 31))
            flag = false;

        if(month == 02)
        {
            if(year % 4 != 0)
            {
                if(date > 28)
                    flag = false;
            }
            if(year % 4 == 0)
            {
                if(date > 29)
                    flag = false;
            }
        }

        var dob = new Date();
        dob.setFullYear(year, month - 1, date);
        var today = new Date();
        if(dob > today)
            flag = false;

        if(flag)
        {
            $scope.notValidDate = false;
            $scope.myForm.$valid = true;
        }
        else
        {
            $scope.notValidDate = true;
            $scope.myForm.$valid = false;
            form.partnerDOBmm.focus();
        }
    }
}

angular.module('testModule', [])
.directive('onlyDigits', function () {

    return {
        restrict: 'A',
        require: '?ngModel',
        link: function (scope, element, attrs, ngModel) {
            if (!ngModel) return;
            ngModel.$parsers.unshift(function (inputValue) {
                var digits = inputValue.replace(/[^\d]/g, "");
                ngModel.$viewValue = digits;
                ngModel.$render();
                return digits;
            });
        }
    };
});
功能控制器($scope){
$scope.notValidDate=false;
$scope.someFunction=函数(事件){
如果($scope.myForm.$valid){
警报(“表单按预期工作”);
返回true;
}
其他的
{
警惕(“某些东西不正确”);
返回false;
}
};
$scope.validateDOB=函数(月、日、年)
{
var标志=真;
var月=mm;
var日期=dd;
变量年份=yyy;
如果(月==null | | |日期==null | | |年==null | | |月.长!=2 | | |年.长!=4)
flag=false;
如果(月<1 | |月>12)
flag=false;
如果(年份<1900 |年份>2100)
flag=false;
如果(日期<1 | |日期>31)
flag=false;
如果((月==04 | |月==06 | |月==9 | |月==11)和&(日期>=31))
flag=false;
如果(月份==02)
{
如果(年份%4!=0)
{
如果(日期>28)
flag=false;
}
如果(第%4年==0)
{
如果(日期>29)
flag=false;
}
}
var dob=新日期();
dob.setFullYear(年、月-1日);
var today=新日期();
如果(dob>今天)
flag=false;
国际单项体育联合会(旗)
{
$scope.notValidDate=false;
$scope.myForm.$valid=true;
}
其他的
{
$scope.notValidDate=true;
$scope.myForm.$valid=false;
form.partnerdomm.focus();
}
}
}
角度.module('testModule',[])
.directive('onlyDigits',函数(){
返回{
限制:“A”,
要求:“?ngModel”,
链接:功能(范围、元素、属性、模型){
如果(!ngModel)返回;
ngModel.$parsers.unshift(函数(inputValue){
var digits=inputValue.replace(/[^\d]/g,“”);
ngModel.$viewValue=位数;
ngModel.$render();
返回数字;
});
}
};
});

请随意即兴回答,希望您可以在“validateDOB”函数中使用“else”

我遇到了一个非常类似的问题。问题是,您可能不想检查字段之间的关系。如果你这样做,很难确定日期是否确实有效,例如如果不是2月30日。您要做的是通过中间元素检查整个日期

作为旁注,根据设计,控制器不应参与此类活动。验证应该在指令级别上进行,所以它是可重用的,并且与Angular一致,这给了您验证程序链的好处。例如,如果您只需要检查一个有效日期,但在另一个示例中,您需要检查出生日期的年龄,那么您将最终“弄湿”您的代码:)

我提出了一个相当简单的解决方案,非常符合角度哲学。诀窍是使用中间表单元素(例如隐藏输入),它将所有三个下拉列表汇集在一起,并一次性对整个日期执行验证

以下是HTML,用于设置焦点:

<form name="dateForm" novalidation>
  <input type="hidden"
      ng-model="modelDate"
      date-type-multi="viewDate"
      ng-init="viewDate = {}"
      class="form-control"
  />
  <select ng-model="viewDate.day">
    <option value="">select day</option>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    <option value="6">6</option>
    <option value="7">7</option>
    <option value="8">8</option>
    <option value="9">9</option>
    <option value="10">10</option>
    <option value="11">11</option>
    <option value="12">12</option>
    <option value="13">13</option>
    <option value="14">14</option>
    <option value="15">15</option>
    <option value="16">16</option>
    <option value="17">17</option>
    <option value="18">18</option>
    <option value="19">19</option>
    <option value="20">20</option>
    <option value="21">21</option>
    <option value="22">22</option>
    <option value="23">23</option>
    <option value="24">24</option>
    <option value="25">25</option>
    <option value="26">26</option>
    <option value="27">27</option>
    <option value="28">28</option>
    <option value="29">29</option>
    <option value="30">30</option>
    <option value="31">31</option>
  </select>
  <select ng-model="viewDate.month">
    <option value="">select month</option>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    <option value="6">6</option>
    <option value="7">7</option>
    <option value="8">8</option>
    <option value="9">9</option>
    <option value="10">10</option>
    <option value="11">11</option>
    <option value="12">12</option>
  </select>
  <select ng-model="viewDate.year">
    <option value="">select year</option>
    <option value="1981">1981</option>
    <option value="1982">1982</option>
    <option value="1983">1983</option>
    <option value="1984">1984</option>
    <option value="1985">1985</option>
    <option value="1986">1986</option>
    <option value="1987">1987</option>
    <option value="1988">1988</option>
    <option value="1989">1989</option>
    <option value="1990">1990</option>
    <option value="1991">1991</option>
    <option value="1992">1992</option>
  </select>
</form>
在指令上设置低优先级是很重要的,因为这样解析器作为第一个启动(与格式化程序的顺序相反),该字段上的其他验证器将获得解析日期

你可以在这里玩:

我在这里详细描述了思考过程: function Controller ($scope) { $scope.notValidDate = false; $scope.somefuncion = function(event) { if ($scope.myForm.$valid) { alert("Form is working as expected"); return true; } else { alert("Something is not correct"); return false; } }; $scope.validateDOB = function(mm,dd,yyyy) { var flag = true; var month = mm; var date = dd; var year = yyyy; if(month == null || date == null || year == null || month.length != 2 || date.length!= 2 || year.length!= 4) flag = false; if(month < 1 || month > 12) flag = false; if(year < 1900 || year > 2100) flag = false; if(date < 1 || date > 31) flag = false; if((month == 04 || month == 06 || month == 9 || month == 11) && (date >= 31)) flag = false; if(month == 02) { if(year % 4 != 0) { if(date > 28) flag = false; } if(year % 4 == 0) { if(date > 29) flag = false; } } var dob = new Date(); dob.setFullYear(year, month - 1, date); var today = new Date(); if(dob > today) flag = false; if(flag) { $scope.notValidDate = false; $scope.myForm.$valid = true; } else { $scope.notValidDate = true; $scope.myForm.$valid = false; form.partnerDOBmm.focus(); } } } angular.module('testModule', []) .directive('onlyDigits', function () { return { restrict: 'A', require: '?ngModel', link: function (scope, element, attrs, ngModel) { if (!ngModel) return; ngModel.$parsers.unshift(function (inputValue) { var digits = inputValue.replace(/[^\d]/g, ""); ngModel.$viewValue = digits; ngModel.$render(); return digits; }); } }; });
<form name="dateForm" novalidation>
  <input type="hidden"
      ng-model="modelDate"
      date-type-multi="viewDate"
      ng-init="viewDate = {}"
      class="form-control"
  />
  <select ng-model="viewDate.day">
    <option value="">select day</option>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    <option value="6">6</option>
    <option value="7">7</option>
    <option value="8">8</option>
    <option value="9">9</option>
    <option value="10">10</option>
    <option value="11">11</option>
    <option value="12">12</option>
    <option value="13">13</option>
    <option value="14">14</option>
    <option value="15">15</option>
    <option value="16">16</option>
    <option value="17">17</option>
    <option value="18">18</option>
    <option value="19">19</option>
    <option value="20">20</option>
    <option value="21">21</option>
    <option value="22">22</option>
    <option value="23">23</option>
    <option value="24">24</option>
    <option value="25">25</option>
    <option value="26">26</option>
    <option value="27">27</option>
    <option value="28">28</option>
    <option value="29">29</option>
    <option value="30">30</option>
    <option value="31">31</option>
  </select>
  <select ng-model="viewDate.month">
    <option value="">select month</option>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    <option value="6">6</option>
    <option value="7">7</option>
    <option value="8">8</option>
    <option value="9">9</option>
    <option value="10">10</option>
    <option value="11">11</option>
    <option value="12">12</option>
  </select>
  <select ng-model="viewDate.year">
    <option value="">select year</option>
    <option value="1981">1981</option>
    <option value="1982">1982</option>
    <option value="1983">1983</option>
    <option value="1984">1984</option>
    <option value="1985">1985</option>
    <option value="1986">1986</option>
    <option value="1987">1987</option>
    <option value="1988">1988</option>
    <option value="1989">1989</option>
    <option value="1990">1990</option>
    <option value="1991">1991</option>
    <option value="1992">1992</option>
  </select>
</form>
angular.module('dateApp', []).
  directive('dateTypeMulti', function() {
    return {
      priority: -1000,
      require: 'ngModel',
      link: function(scope, elem, attrs, ngModel) {
        ngModel.$render = function() {
          angular.extend(scope.$eval(attrs.dateTypeMulti), ngModel.$viewValue);
        };

        scope.$watch(attrs.dateTypeMulti, function(viewValue) {
          ngModel.$setViewValue(viewValue);
        }, true);

        ngModel.$formatters.push(function(modelValue) {
          if (!modelValue) return;

          var parts = String(modelValue).split('/');

          return {
            year: parts[0],
            month: parts[1],
            day: parts[2]
          };
        });

        ngModel.$parsers.unshift(function(viewValue) {
          var isValid = true,
            modelValue = '',
            date;

          if (viewValue) {
            date = new Date(viewValue.year, viewValue.month - 1, viewValue.day);
            modelValue = [viewValue.year, viewValue.month, viewValue.day].join('/');

            if ('//' === modelValue) {
              modelValue = '';
            } else if (
              date.getFullYear() != viewValue.year ||
              date.getMonth() != viewValue.month - 1 ||
              date.getDate() != viewValue.day) {
              isValid = false;
            }
          }

          ngModel.$setValidity('dateTypeMulti', isValid);

          return isValid ? modelValue : undefined;
        });
      }
    };
  });
@validateDateDirective = ->
    require: "ngModel"
    link: (scope, elem, attr, ngModel) ->
        # Get the base model name without the _day _month _year appended
        # e.g for field 'birth_date_year', this would equal 'birth_date'
        modelName = attr.ngModel.replace('_day', '').replace('_month', '').replace('_year', '')

        # use base model name to watch all models in target fieldset
        scope.$watchCollection '['+modelName+'_day, '+modelName+'_month, '+modelName+'_year]', ->
            # Set global value
            value = [scope.$eval(modelName+'_year'),
                    scope.$eval(modelName+'_month'), 
                    scope.$eval(modelName+'_day')]

            # << do your validation here >>