首页 > 解决方案 > 使用 AngularJS 验证一组表单字段

问题描述

使用 Angular 1.5.11

我有一个包含几个文件的 html 表单,例如:

<div ng-app="validationApp" ng-controller="mainController">
  <div class="container">
    <div class="row">
      <form name="weightForm" ng-submit="submitForm()" novalidate>
        <input class="input" data-required="" fn-restrict-integer="" maxlength="4" name="weight1" id="weight1" ng-model="weight1" fn-min-value="1" fn-max-value="9999" />
        <input class="input" data-required="" fn-restrict-integer="" maxlength="4" name="weight2" id="weight2" ng-model="weight2" fn-min-value="1" fn-max-value="9999" />
        <input class="input" data-required="" fn-restrict-integer="" maxlength="4" name="weight3" id="weight3" ng-model="weight3" fn-min-value="1" fn-max-value="9999" />

        <div>
          <dl aria-invalid="{{totalWeightIsAboveLimit()}}">
            <p class="input__error">total weight above limit</p>
          </dl>          
        </div>

        <button type="submit" class="btn btn-primary" ng-disabled="weightForm.$invalid">Submit</button>
      </form>
    </div>
  </div>
</div>

如何构建一个将三个字段的值视为一个组的验证,在这种情况下是输入字段的总和。

我已经构建了一个验证函数来切换消息,但我不知道如何根据此函数的结果使表单无效。

但我不知道如何使整个表单无效以防止提交。

标签: angularjsvalidation

解决方案


使用自定义验证器计算总重量。我在标签中添加了一个valid-weight指令并实现了功能。在这种情况下,Angularjs 为最多 3 个错误创建一个数组, 每个标签一个。inputmyValidation()scope.weightForm.$error.invalidWeightinput

var app = angular.module('validationApp', []);
app.controller('mainController', function($scope) {
  $scope.maxWeight = 99;
  $scope.weights = {};
  $scope.totalWeight = 0;
});
app.directive('validWeight', function() {
  return {
    require: 'ngModel',
    link: function(scope, element, attr, mCtrl) {
      function myValidation(value) {
        scope.weights[attr.id] = Number(value) || 0;
        scope.totalWeight = Object.values(scope.weights).reduce(function(a, b) {
          return a + b;
        });
        let valid = scope.totalWeight <= scope.maxWeight;
        mCtrl.$setValidity('invalidWeight', valid);
        if (valid && scope.weightForm.$error.invalidWeight) { 
          /* clear any previous error on other input tags 
             that were not edited after last change */
          scope.weightForm.$error.invalidWeight = undefined;
        }
        return value;
      }
      mCtrl.$parsers.push(myValidation);
    }
  };
});
.input__error {
  color: red;
  font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js"></script>
<div ng-app="validationApp" ng-controller="mainController">
  <div class="container">
    <div class="row">
      <p>Total weight: {{totalWeight}}</p>
      <p>Maximum weight: {{maxWeight}}</p>
    </div>
    <div class="row">
      <form name="weightForm" ng-submit="submitForm()" novalidate>
        <input class="input" data-required="" fn-restrict-integer="" maxlength="4" name="weight1" id="weight1" ng-model="weight1" fn-min-value="1" fn-max-value="9999" valid-weight />
        <input class="input" data-required="" fn-restrict-integer="" maxlength="4" name="weight2" id="weight2" ng-model="weight2" fn-min-value="1" fn-max-value="9999" valid-weight />
        <input class="input" data-required="" fn-restrict-integer="" maxlength="4" name="weight3" id="weight3" ng-model="weight3" fn-min-value="1" fn-max-value="9999" valid-weight />

        <div>
          <dl ng-show="weightForm.$error.invalidWeight">
            <p class="input__error">Total weight is above limit.</p>
          </dl>
        </div>
        <p></p>
        <button type="submit" class="btn btn-primary" ng-disabled="weightForm.$error.invalidWeight">Submit</button>
      </form>
    </div>
  </div>
</div>


推荐阅读