Process field validation into three parts using angle characters

I have a field with three parts of a date that needs to be checked in angular js. I got to creating a custom validation function, but I had a problem developing logic for how the fields should update each other's status.

How can I get all three form fields to sing the same sheet of hymns, and all of them display their status as valid or invalid depending on the others?

Here is the fiddle: http://jsfiddle.net/4GsMm/1/

And the code:

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

and...

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

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

input{
    display: inline;
    width: 3em;
}

and...

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()
      });
    }
  };
});
+4
source share
4 answers

I was also looking for a three-digit date field check using AngularJS, here's what I did (working for me)

HTML:

<form name="myForm" method="post" novalidate ng-submit="somefuncion()" ng-controller="Controller" ng-app="testModule">
    Date (MM-DD-YYYY): <input id="partnerDOBmm" name="partnerDOBmm" class="ddinput" type="text" value="" size="2" maxlength="2" ng-model="partnerDOBmm" required only-digits ng-minlength="2" ng-change="validateDOB(partnerDOBmm,partnerDOBdd,partnerDOByyyy)"  />
    -
    <input id="partnerDOBdd" name="partnerDOBdd" class="ddinput" type="text" value="" size="2" maxlength="2" ng-model="partnerDOBdd" required only-digits ng-minlength="2" ng-change="validateDOB(partnerDOBmm,partnerDOBdd,partnerDOByyyy)" />
    -
    <input id="partnerDOByyyy" name="partnerDOByyyy" class="yyyyinput" type="text" value="" size="4" maxlength="4" ng-model="partnerDOByyyy" required only-digits ng-minlength="4" ng-change="validateDOB(partnerDOBmm,partnerDOBdd,partnerDOByyyy)" />
    <br />
    <span class="error" ng-show="submitted && (myForm.partnerDOBmm.$error.required || myForm.partnerDOBdd.$error.required || myForm.partnerDOByyyy.$error.required)"> Required! </span>
    <span class="error" ng-show="submitted && (myForm.partnerDOBmm.$error.minlength || myForm.partnerDOBdd.$error.minlength || myForm.partnerDOByyyy.$error.minlength)"> Too Short! </span>
    <span class="error" ng-show="notValidDate && !(myForm.partnerDOBmm.$error.required || myForm.partnerDOBdd.$error.required || myForm.partnerDOByyyy.$error.required || myForm.partnerDOBmm.$error.minlength || myForm.partnerDOBdd.$error.minlength || myForm.partnerDOByyyy.$error.minlength)"> Not a Valid Date! </span>
    <br />
    <button type="submit" class="btnSubmit" ng-click="submitted=true">Submit</button>
</form>

Script:

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;
            });
        }
    };
});

, , 'else' validateDOB

+4

, input type="number" max min, ng-change, .

, , "" :

<input type="number" name="year" ng-model="year" min="2000" ng-change="updateDate()"/>
<input type="number" name="month" ng-model="month" min="1" max="12" ng-change="updateDate()" />
<input type="number" name="day" ng-model="day" min="1" max="31" ng-change="updateDate()" />

.

, , , , . (, ). drop down , , , , ... , , .

:

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

, ?

? . ? ? . show/hyde 30 .

plunk.

2001 :

<span ng-show="myForm.year.$error.min">Must be after January 1, 2001</span>
+2

. , , , . , , , , 30 . , , .

- . , Angular, . , , , "" :)

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

JS:

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;
        });
      }
    };
  });

, ( ) .

: http://codepen.io/jciolek/pen/oxBch

: http://float-middle.com/multiple-fields-validation-in-angularjs/

, ,

+1

We add the directive to the last field and use $ watchCollection in the directive as shown below (excuse coffeescript)

@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 >>
+1
source

All Articles