如何在提交时强制对所有字段进行表单验证?

时间:2014-04-11 17:15:34

标签: forms angularjs validation

我需要能够验证某些字段,即使它们从未被用户触及过。但是,有些字段是必需的,至少到目前为止我已经体验过,提交时,必填字段无效:它仅在模糊时失效。因此,如果用户实际上从未实际触摸过某个字段(或任何字段),并且点击提交,则表单将成功验证并提交,从而导致服务器端验证错误。

关于AngularJS表单验证的问题:无论用户是否实际触及任何表单字段,您如何强制整个表单在提交时进行验证?

我有很多表单,在大多数表单中有几个必填字段,以及具有最小/最大和最大长度要求的字段。如果我只是构建一个AngularJS表单,应用ng-required等指令,然后点击提交,表单总是会提交。没有什么能阻止它。

我需要我的表单,如果必填字段为空,则不提交,无论用户是否实际触摸并离开(这是模糊事件将被触发的唯一方式,因此这些字段的唯一方式将被验证。 )

使用"禁用"提交按钮方法对我来说是不可接受的。

我引用的资源:

  • Processing Forms in AngularJS
    • 问题:if (form.$invalid) return;成语不起作用。我遇到错误" TypeError:无法读取属性' $ valid'未定义"
  • Form Validation: The AngularJS Way
    • 虽然我认为这是一种有趣的方法,但我们的客户端不希望数千个小的ajax请求对其数据库服务器执行内联(即onblur)验证。因此,使用unique指令验证用户名唯一性等方法对我们来说不是一种选择。

作为参考,这是我在控制器中的当前提交功能:

表格:

<div ng-switch on="state" ng-controller="OwnerCtrl">

<!-- A whole bunch of other layout and informational junk -->

    <form name="ownerForm" novalidate ng-submit="submit(ownerForm)">
        <div class="row-fluid">
            <div class="span3 control-group" ng-class="{error: ownerForm.FirstName.$dirty && ownerForm.FirstName.$invalid }">
                <label class="control-label" for="FirstName" ng-class="">First Name</label>

                <div class="controls">
                    <input class="input-block-level" data-val="true" data-val-required="First Name is required"
                               id="FirstName" name="FirstName" placeholder="First Name" type="text" ng-required ng-model="owner.firstName"/>
            </div>
        </div>

        <!-- A BUNCH of other form controls here -->

        <div class="row-fluid">
            <div class="span3">
                <button class="btn btn-info" ng-click="back()">
                    <span ng-hide="transitionBack"><i class="icon-chevron-left icon-white"></i><i class="icon-chevron-left icon-white"></i>&nbsp;Back</span>
                    <span ng-show="transitionBack">Loading...</span>
                </button>
            </div>
            <div class="span3">
                <button class="btn btn-primary" type="submit">
                    <span ng-hide="transitionForward"></span>Continue<i class="icon-chevron-right icon-white"></i><i class="icon-chevron-right icon-white"></i></span>
                    <span ng-show="transitionForward">Loading...</span>
                </button>
            </div>
        </div>
    </form>
<div>

控制器:

var owner = angular.module("Owner", []);

owner.controller("OwnerCtrl", ["$scope", "$location", "$log", function($scope, $location, $log) {

    $scope.owner = {
        firstName: "",
        lastName: "",
        middleInitial: "",
        birthDate: null,
        ssn: "",
        phoneNumber: ""
    };

    $scope.formSubmitted = false;

    $scope.submit = function(form) {
        // Found this on a blog somewhere, just an attempt to FORCE form validation even
        // on elements that have never been touched by the uyser
        for (var field in form) {
            // look at each form input with a name attribute set
            // checking if it is pristine and not a '$' special field
            if (field[0] != '$' && form[field].$pristine) {
                form[field].$setViewValue(
                    form[field].$modelValue
                );
            }
        }

        $scope.formSubmitted = true;

        if (form.$invalid)
            return;
    }
}

我已从示例中删除了其他不必要的html和js,以保持简洁。这是唯一对手头问题很重要的代码。

作为旁注。我目前正在传递表单,而不是使用$scope.ownerForm.$valid。尽管我确实命名了我的表单,$scope.ownerForm不起作用。表单属性是未定义的,但似乎只有当我尝试访问它的$ valid或$ invalid属性时。具有讽刺意味的是,$scope.ownerForm[field]实际上有效(原来,在我开始传入表单对象之前)。当我访问$valid / $invalid属性时,它似乎失败了。


更新

所以,似乎我的问题比提交表单验证更深刻。它看起来好像我的表格没有验证,期间。我刚刚浏览了整个表单,填写了所有无效数据(太长的字符串,数字字段中的非数字数据,左边的必填字段为空。一旦模糊,Angular应该尽快验证这些字段,就我而言理解。没有一个字段无效。调试我的提交功能,表单当前被标记为有效。此外,我使用Chrome的开发工具浏览了每个字段,并且所有字段都标记为脏,并且< em>有效,无效。

似乎需要/ ng-required并且所有其他表单验证属性都被忽略...但是在Chrome的开发工具中,我可以看到附加到每个输入属性的函数,这些函数已添加到形式对象。例如,在所有必填字段中,我可以看到一个显然旨在验证该要求的功能。 $ parsers数组中也有一些东西。

我完全不知所措。 为什么我的表单验证无效?

2 个答案:

答案 0 :(得分:0)

如果您不想使用ng-disabled方法,我会采用ng-submit方式;您可以在提交时启动自定义验证功能,检查字段&#34;手动&#34;为了错误。类似的东西:

// inside the controller
$scope.onSubmit = function($event) {
  // check for errors; if wrong return/preventDefault/doTheRightThing
  // else continue
};
//...

和HTML:

<form ng-submit="onSubmit">
  <!-- form fields -->
</form>

答案 1 :(得分:0)

你错了。表单元素和表单本身的验证状态始终是最新的。每次用户在元素中输入内容时,或每次基础模型更改时,元素和表单的$invalid / $valid属性都会更新。

因此,在您的提交方法中,您只需要检查表单的$valid属性是真还是假,并采取相应的行动。

如果你有&#34;无法阅读财产&#39; $ valid&#39;未定义&#34;,则表示您没有为表单命名,或者您在控制器中使用了错误的名称。向我们展示您的代码,以帮助我们诊断问题。

工作演示:http://plnkr.co/edit/ImnC4d2WXNdsDqwNlTUa?p=preview