如何使用 ng-messages 显示复选框集和无线电集的错误消息?

How to show error messages for Checkbox set and Radio set using ng-messages?

我一直在尝试验证复选框集和无线电集并使用 ng-messages 指令显示错误消息,但它没有按预期工作。 ng-messages 根本不显示错误消息。我正在使用 html 文件填充错误消息。在错误得到解决之前,我的表单中的提交按钮将被禁用。

在以下情况下如何显示复选框集和单选框集的错误消息:

  1. Radio set中有一个选项没有选中?

  2. 复选框组中至少有一个选项未选中?

  3. 缩放 Checkbox 集的检查,以便我们可以检查至少 2 个或更多被选中,等等?

这是我的表格:

<form name="userForm" ng-submit="submitForm()" novalidate>
    <div class="form-group" ng-class="{ 'has-error' : userForm.subscribe.$invalid && !userForm.subscribe.$touched }">
        <label class="checkbox-inline">
            <input type="checkbox" id="subscribe1" value="option1" name="subscribe[]" ng-model="user.subscribe" required> 1
        </label>
        <label class="checkbox-inline">
            <input type="checkbox" id="subscribe2" value="option2" name="subscribe[]" ng-model="user.subscribe" required> 2
        </label>
        <label class="checkbox-inline">
            <input type="checkbox" id="subscribe3" value="option3" name="subscribe[]" ng-model="user.subscribe" required> 3
        </label>

        <div class="help-block" ng-messages="userForm.subscribe.$error" ng-show="userForm.subscribe.$invalid">
            <div ng-messages-include="home/messages.html"></div>
        </div>
    </div>

    <div class="form-group" ng-class="{ 'has-error' : userForm.gender.$invalid && !userForm.gender.$touched }">
        <div class="radio">
            <label>
                <input type="radio" name="gender" value="male" ng-model="user.gender" />
                male
            </label>
        </div>
        <div class="radio">
            <label>
                <input type="radio" name="gender" value="female" ng-model="user.gender" />
                female
            </label>
        </div>

        <div class="help-block" ng-messages="userForm.gender.$error" ng-show="userForm.gender.$invalid">
            <div ng-messages-include="home/messages.html"></div>
        </div>
    </div>
    <button type="submit" class="btn btn-primary btn-success " ng-disabled="userForm.$invalid">Submit</button>
</form>

messages.html

<span ng-message="required">This field is required</span>
<span ng-message="minlength">This field is too short</span>
<span ng-message="maxlength">This field is too long</span>
<span ng-message="required">This field is required</span>
<span ng-message="email">This needs to be a valid email</span>

controller.js

angular.module('myApp', ['ngRoute', 'ngAnimate', 'ngMessages']);

angular
    .module('myApp')
    .controller('HomeCtrl', HomeCtrl);

HomeCtrl.$inject = ['$scope'];

function HomeCtrl($scope) {
    $scope.userForm = {};
}

付款复选框设置:

<div class="form-group" ng-class="{ 'has-error' : userForm.payment.$invalid && userForm.payment.$touched }">
    <label class="checkbox-inline">
        <input type="checkbox" id="payment1" value="Visa" name="payment" ng-blur="doTouched()" ng-model="user.payment[1]" ng-required="!someSelected(user.payment)"> Visa
    </label>
    <label class="checkbox-inline">
        <input type="checkbox" id="payment2" value="Mastercard" name="payment" ng-blur="doTouched()" ng-model="user.payment[2]" ng-required="!someSelected(user.payment)"> Mastercard
    </label>
    <label class="checkbox-inline">
        <input type="checkbox" id="payment3" value="Cash" name="payment" ng-blur="doTouched()" ng-model="user.payment[3]" ng-required="!someSelected(user.payment)"> Cash
    </label>

    <div class="help-block" ng-messages="userForm.payment.$error" ng-show="userForm.payment.$invalid && userForm.payment.$touched">
        <div ng-messages-include="home/messages.html"></div>
    </div>
</div>

检查此示例:

http://plnkr.co/edit/2w0lIf?p=preview

复选框列表使用 ng-required 指令和 someSelected 函数(在控制器中定义)检查是否至少选择了一项:

<div class="form-group" ng-class="{ 'has-error' : userForm.subscribe.$invalid && userForm.subscribe.$touched }">
    <label class="checkbox-inline">
        <input type="checkbox" id="subscribe1" value="option1" name="subscribe" ng-blur="doTouched()" ng-model="user.subscribe[1]" ng-required="!someSelected(user.subscribe)"> 1
    </label>
    <label class="checkbox-inline">
        <input type="checkbox" id="subscribe2" value="option2" name="subscribe" ng-blur="doTouched()" ng-model="user.subscribe[2]" ng-required="!someSelected(user.subscribe)"> 2
    </label>
    <label class="checkbox-inline">
        <input type="checkbox" id="subscribe3" value="option3" name="subscribe" ng-blur="doTouched()" ng-model="user.subscribe[3]" ng-required="!someSelected(user.subscribe)"> 3
    </label>

    <div class="help-block" ng-messages="userForm.subscribe.$error" ng-show="userForm.subscribe.$invalid && userForm.subscribe.$touched">
        <div ng-messages-include="messages.html"></div>
    </div>
</div>

选项按钮组更简单,使用条件为 !user.gender:

ng-required 指令
<div class="form-group" ng-class="{ 'has-error' : userForm.gender.$invalid && userForm.gender.$touched }">
    <div class="radio">
        <label>
            <input type="radio" name="gender" value="male" ng-model="user.gender" ng-required="!user.gender"/>
            male
        </label>
    </div>
    <div class="radio">
        <label>
            <input type="radio" name="gender" value="female" ng-model="user.gender" ng-required="!user.gender"/>
            female
        </label>
    </div>

    <div class="help-block" ng-messages="userForm.gender.$error" ng-if="userForm.gender.$touched">
        <div ng-messages-include="messages.html"></div>
    </div>
</div>

ngBlur 指令解决了只有当列表中的所有项目都模糊时,复选框列表才会变成 "touched" 的问题,调用 doTouched() 函数::

  $scope.doTouched = function() {
     $scope.userForm.subscribe.$setTouched();
  }

P.S.注意正确命名:userForm<form>的HTML名字,user 是表单绑定到的模型的名称。

这是我创建的一个适合我们目的的示例。
我们的应用程序会在每个页面创建多个复选框问题,并且 $touched 似乎不适用于所有具有相同名称属性的输入复选框字段。
我还看到自定义 angular plugins/directives 复选框很好(它们只绑定到 1 个数组模型)但似乎不支持 'required'.

在这里,我为每个问题设置了一个 custom_touched 事件,我通过 ng-click 设置:

http://jsfiddle.net/armyofda12mnkeys/9gLndp5y/7/

<li ng-repeat="choice in currentquestion.choices">
                  <input
                    type="checkbox"
                    ng-model="choice.selected"
                    ng-required="!somethingSelectedInTheGroup(currentquestion.required, currentquestion.choices)"
                    ng-click="currentquestion.custom_touched = true;"
                    name="{{currentquestion.question_code}}"
                    id="{{currentquestion.question_code}}_{{choice.option_value}}"                                      
                    value="{{choice.option_value}}"
                  /> {{choice.orig_option_txt}}

              </li> 


$scope.somethingSelectedInTheGroup = function (is_required, choices) {
    if(is_required) {
      for(var i = 0; i < choices.length; i++) {
        var choice = choices [i];
        if(choice.selected) {
            return true;
        }
      }

      return false;
    } else {
        return false;
    }
  }

注意:我原来用过<div ng-if="questionform.$dirty && questionform[currentquestion2.question_code].$invalid"> 但这不适用于每个 form/page.

的多个复选框问题