【问题标题】:How can I simplify form validation?如何简化表单验证?
【发布时间】:2013-02-22 10:38:09
【问题描述】:

下面的代码似乎可以很好地完成基本的必需表单验证。

当字段脏 + 无效时,表单显示红色 Name is required 消息,如果字段脏 + 有效,则显示 Great! 消息。

但是对于表单中的每个字段都重复此代码是一团糟:

<form name="myForm">
    <div class="control-group" 
     ng-class="{error: myForm.name.$invalid && myForm.name.$dirty}">
        <label>Name:</label>
        <input type="text" name="name" ng-model="user.name" required/>
        <span ng-show="myForm.name.$invalid && myForm.name.$dirty" 
            class="help-inline">Name is required</span>
        <span ng-show="myForm.names.$valid && myForm.names.$dirty">Great!</span>
    </div>
</form>

我希望能够以更简单的方式指定ng-showng-class 属性。

【问题讨论】:

  • 我将这些东西封装在一个指令中。我还使用 DOM 操作添加了验证类和跨度。所以我的标记只是标签和输入。
  • 我知道这是一个老问题,但我写了一个 Article 试图解决这个问题
  • 你可以试试这个 Angular 模块 jonsamwell.github.io/angular-auto-validate - 它采用降低 html 表达式复杂性的方法来显示/隐藏验证消息以支持编码的消息。
  • 另一个无耻的自我推销:johannesjo.github.io/ng-fab-form,它比 angular-auto-validate 具有优势,它还显示了很好的全局可配置错误消息,而无需您更改任何标记。

标签: angularjs


【解决方案1】:

您可以这样做的一种方法是将您的验证表达式抽象为范围方法:

PLUNKER

HTML

<div class="control-group" ng-class="{error: isInvalid('name')}">
  <label>Name:</label>
  <input type="text" name="name" placeholder="Name" ng-model="user.name" required/>
  <span ng-show="isInvalid('name')" class="help-inline">Name is required</span>
  <span ng-show="isValid('name')">Great!</span>
</div>

控制器

function Ctrl($scope) {
  $scope.isInvalid = function(field){
    return $scope.myForm[field].$invalid && $scope.myForm[field].$dirty;
  };

  $scope.isValid = function(field){
    return $scope.myForm[field].$valid && $scope.myForm[field].$dirty;
  };

}

【讨论】:

  • 好主意,但我如何获得myForm 参考(它不在范围内,只有标记)?我更新了 html 以提供更多上下文。
  • myForm 被自动引用。见this plnkr
  • 你是对的(我在错误的控制器中检查了 $scope...duh)。感谢您回答我的问题!
【解决方案2】:

我知道这个问题很老了,但我想与世界分享我很棒的新 angular 指令,我在 Github 上做了一个项目,我认为它与现有/可用的任何东西相比简直太棒了......我基于自己优秀的 Laravel PHP 框架,并使其在 Angular 下可用......说得够多了,让我们举一些例子:

<!-- example 1 -->
<label for="input1">Simple Integer</label>
<input type="text" validation="integer|required" ng-model="form1.input1" name="input1" />

<!-- example 2 -->
<label for="input2">Alphanumeric + Exact(3) + required</label>
<input type="text" validation="alpha|exact_len:3|required" ng-model="form1.input2" name="input2" />

所以我可以在一个简单的指令validation="min_len:2|max_len:10|required|integer" 中定义我想要的任何数量的验证规则,并且错误消息将始终显示在下一个&lt;span&gt; 中你们不喜欢吗? 1 行代码用于输入,1 行代码用于错误显示, 你不能比这更简单......哦,如果你想添加我什至支持你的自定义 Regex :)

当您唯一需要的是 2 行代码时,不再需要 10 行代码用于 1 个输入的集群表单,即使对于带有 5 个验证器的输入也是如此。不用担心表格不会失效,我也处理好了,这一切都处理得很好。

看看我的 Github 项目 Angular-Validation 并传播这个词 =)

编辑
为了使用户体验更加流畅,我添加了计时器验证。这个概念很简单,不要在用户忙于打字时打扰用户,但要验证他是否暂停或更改输入(onBlur)......喜欢它!
您甚至可以根据自己的喜好自定义计时器,我决定在指令中将其默认为 1 秒,但如果您想自定义,您可以调用例如 typing-limit="5000" 来设置 5 秒。超时。完整示例:

<input type="text" validation="integer|required" typing-limit="5000" ng-model="form1.input1" name="input1" />


编辑 #2
还添加了输入匹配确认验证(例如:密码确认),这是一个示例代码

<!-- input match confirmation, as for example: password confirmation -->
<label for="input4">Password</label>
<input type="password" name="input4" ng-model="form1.input4" validation="alpha|min_len:4|required"  />
<label for="input4c">Password Confirmation</label>
<input type="password" name="input4c" ng-model="form1.input4c" validation="match:form1.input4,Password|required"  />

编辑 #3
重构了指令,因此不需要使用&lt;span&gt; 来显示错误,指令现在自己处理它,请参阅顶部反映的代码更改。

演示
Plunker

上添加了现场演示

【讨论】:

  • 伟大的指令。谢谢你为我照顾这件事。 :)
【解决方案3】:

请使用此 CSS

.myForm input.ng-invalid.ng-dirty {
    background-color: #FA787E;
}

.myForm input.ng-valid.ng-dirty {
    background-color: #78FA89;
}

【讨论】:

    【解决方案4】:

    您可以使用Angular-Validator

    会的

    1. 以红色显示所需的错误消息(可选择使用引导类)
    2. 如果该字段未通过验证器,则将其标记为无效
    3. 防止表单无效时提交
    4. 仅在字段脏时显示消息
    5. 清理您的代码!

    不会

    1. 显示成功消息(即将支持成功消息)。

    示例

    <form name="myForm" angular-validator>
        <div class="control-group">
            <label>Name:</label>
            <input type="text" 
                   name="name"
                   ng-model="user.name"
                   required-message="'Name is required'"
                   required/>
        </div>
    </form>
    

    显示成功消息的解决方法:

    <form name="myForm" angular-validator>
        <div class="control-group">
            <label>Name:</label>
            <input type="text" 
                   name="name"
                   ng-model="user.name"
                   required-message="'Name is required'"
                   required/>
            <span ng-show="myForm.names.$valid && myForm.names.$dirty">Great!</span>
        </div>
    </form>
    

    查看更多Angular-validator use cases and examples

    免责声明:我是 Angular-Validator 的作者

    【讨论】:

      【解决方案5】:

      github上有一个名为xtForm的角度指令/项目。看起来它是一个简单的角度字段验证的良好开端。 XtForm 减少了输入标签之后的验证消息标记量。

      链接到demo site https://github.com/refactorthis/xtform

      小用法示例。不需要额外的标记(ng-show on spans)来获取此字段是必需的错误消息/工具提示。

      <form xt-form novalidate>
        <input name="email" ng-model="modelVal" xt-validate required>
        <button type="submit">Submit</button>
      </form>
      

      【讨论】:

      • 感谢 Jeroen 的提示,模块的“使用”确实有助于解决简化验证标记的问题。
      【解决方案6】:

      考虑使用我一直在研究的这个 ngValidate 模块。

      <input name="demo-field-1" ng-model="user.name" ng-validate="customStrategy">
      

      该指令将添加一个跨度来保存您的错误消息。您可以定义自定义验证策略和单独的错误消息。

      ngValidateFactory.strategies.customStrategy = [
      {
          value:ngValidate.required;
          message:"This field is required"
      },
      {
          value:[ngValidate.minLength,8];
          message:"Minimum 8 characters are required"
      },
      {
          value:[myFunction,arg1,arg2];
          message:"This field fails my custom function test"
      }]
      

      demo plnkr

      【讨论】:

        【解决方案7】:

        试试这个 HTML:

        <form name="myForm" ng-submit="submitForm()" novalidate>
        
                    <!-- NAME -->
                    <div class="form-group" ng-class="{'has-error' : myForm.name.$invalid && !myForm.name.$pristine }">
                        <label>Client Name</label>
                        <input type="email" name="email" class="form-control" ng-model="formValues.userName" required placeholder="User Name">
                        <p ng-show="myForm.email.$invalid && !myForm.email.$pristine" class="error">Your email is required.</p>
                    </div>
        
        
                    <div class="form-group">
                        <label >Password</label>
                        <input type="password" name="formValues.password" class="form-control" placeholder="Password" ng-model="formValues.password" ng-maxlength="6" required>
                    </div>
                    <div class="form-group">
                        <label>Confirm Password</label>
                        <input type="password" name="formValues.confirmPassword"  class="form-control"  placeholder="Confirm Password" ng-model="formValues.confirmPassword" required>
                        <span class="error" ng-if="formValues.confirmPassword" ng-show="formValues.password!=formValues.confirmPassword">password should not match</span>
                    </div>
        
                    <div class="form-group">
                        <label>First Name</label>
                        <input type="text" name="formValues.firstName"  class="form-control" placeholder="First Name" ng-model="formValues.firstName" ng-keyup="acceptAlphabets(formValues.firstName,$event)" required>
                        <span class="error"  ng-show="myString">Accept only letters</span>
                        <span class="error" ng-show="myStringLength">Accept only 50 characters</span>
                    </div>
        
                    <div class="form-group">
                        <label>Last Name</label>
                        <input type="text" name="formValues.larstName" class="form-control"  placeholder="Last Name" ng-model="formValues.larstName" required>
        
                    </div>
                    <div class="form-group">
                        <label>Date Of Birth</label>
                        <input type="text" name="formValues.dateOfBirth" class="form-control" id="exampleInputPassword1" placeholder="Date Of Birth" ng-model="formValues.dateOfBirth" ng-keyup="dateFun(formValues.dateOfBirth,$event)" required>
                        <span class="error" ng-show="dateVal">Incorrect Format, should be MM/DD/YYYY</span>
        
                    </div>
        
                    <button type="submit" class="btn btn-primary" ng-disabled="myForm.$invalid" ng-model="formValues.submit">Submit</button>
        
                </form>
        

        【讨论】:

          【解决方案8】:
          <form ng-app="demoApp" ng-controller="validationCtrl" 
          name="myForm" novalidate>
          
          <p>Username:<br>
          <input type="text" name="user" ng-model="user" required>
          <span style="color:red" ng-show="myForm.user.$dirty && myForm.user.$invalid">
          <span ng-show="myForm.user.$error.required">Your Username is required.</span>
          </span>
          </p>
          
          <p>Email:<br>
          <input type="email" name="email" ng-model="email" required>
          <span style="color:red" ng-show="myForm.email.$dirty && myForm.email.$invalid">
          <span ng-show="myForm.email.$error.required">Your Email is required.</span>
          <span ng-show="myForm.email.$error.email">Invalid email address.</span>
          </span>
          </p>
          
          <p>Mobile:<br>
          <input type="number" name="number" ng-model="number" required>
          <span style="color:red" ng-show="myForm.number.$dirty && myForm.number.$invalid">
          <span ng-show="myForm.number.$error.required">Your Phone is required.</span>
          <span ng-show="myForm.number.$error.number">Invalid number.</span>
          </span>
          </p>
          
          <p>
          <input type="submit"
          ng-disabled="myForm.user.$dirty && myForm.user.$invalid ||  
          myForm.email.$dirty && myForm.email.$invalid || myForm.number.$dirty && myForm.number.$invalid">
          </p>
          </form>
          
          <script>
          //This is controller
          var app = angular.module('demoApp', []);
          app.controller('validationCtrl', function($scope) {
              $scope.user = 'angular';
              $scope.email = 'angular.js@gmail.com';
          });
          </script>
          

          【讨论】:

            【解决方案9】:

            我可能为时已晚,但您可以使用外部库为您处理验证。 Angular form validator(由我编写)通过使用很少的标准验证器(例如

            )使其变得更容易
            1. 必填
            2. 字符串(最小/最大长度)
            3. 数字(最小值/最大值)
            4. 模式
            5. 电子邮件
            6. 网址
            7. 等于(用于验证电子邮件/密码)
            8. 自定义(您可以插入自己的验证)

            它允许将多个验证器组合到一个字段。

            <form name="introform" ng-controller="intro">
                <div class="form-group" validator="required['Field is required'],string[5,20,'Should between 5 and 20 characters']">
                    <label for="requiredField">Required Field</label>
                    <input type="text" class="form-control" id="requiredField" name="requiredField"
                           placeholder="Required Field" ng-model="model.requiredField">
                </div>
                <button type="submit" class="btn btn-default" ng-disabled="!introform.$valid">Submit</button>
            </form>
            

            【讨论】:

              【解决方案10】:

              codpen link 上查看我的 angularJS 表单验证

              我在演示中展示了如何验证所需的最小长度、最大长度、电子邮件、密码大小写、确认密码匹配的示例。

              代码如下:

              var myApp = angular.module('myApp',[]);
              myApp.controller('mainController',['$scope', function($scope) {
              	
              }]);
              myApp.directive('validConfirmPassword', function() {
              	return {
              		require:'ngModel',
              		link: function(scope, elem, attrs, ctrl) {
              			ctrl.$parsers.unshift(function(viewValue, $scope) {
              				var noMatch = viewValue != scope.myForm.password.$viewValue;
              				ctrl.$setValidity('noMatch', !noMatch)
              			})
              		}
              	}
              })	
              .content{ margin-top:50px;  }
              .danger-text { color: red; }
              <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" rel="stylesheet"/>
              <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
              <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
              <div ng-app="myApp">
              <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
                    <div class="container">
                      <a class="navbar-brand" href="#">AngularJS Form Validation</a>
                      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExample07" aria-controls="navbarsExample07" aria-expanded="false" aria-label="Toggle navigation">
                        <span class="navbar-toggler-icon"></span>
                      </button>
                  </nav>
              
              	<div class="container content" ng-controller="mainController">
              		<div class="row">
              			<div class="col-sm-12">
              				<form name="myForm" novalidate>
              					<div class="row">
              		    			<div class="col-md-6 mb-3">
              							
              								<label for="first_name">First Name</label>
              								<input type="text" name="firstname" ng-model="firstname" id="firstname"  class="form-control" required>
              								<p ng-show="myForm.firstname.$touched && myForm.firstname.$invalid" class="danger-text">Please enter your first name</p>	
              							
              						</div>
              						<div class="col-md-6 mb-3">
              							
              								<label for="last_name">Last Name</label>
              								<input type="text" name="last_name" ng-model="last_name" id="last_name"  class="form-control"  required>
              								<p ng-show="myForm.last_name.$invalid && myForm.last_name.$touched" class="danger-text">Please enter your last name</p>
              							
              						</div>
              					</div> <!-- End of row -->
              					<div class="row">
              						<div class="col-md-6 mb-3">
              							<label for="username">Username</label>
              							<input type="text" name="username" id="username" ng-model="username" class="form-control" ng-required="true" ng-minlength="4" ng-maxlength="10" >
              							<p ng-show="myForm.username.$error.required && myForm.username.$touched" class="danger-text">Please enter username</p>
              							<p ng-show="myForm.username.$error.minlength" class="danger-text">Username is too short</p>
              							<p ng-show="myForm.username.$error.maxlength" class="danger-text">Username is too long</p>
              						</div>
              						<div class="col-md-6 mb-3">
              							<label for="email">Email</label>
              							<input type="email" name="email" id="email" class="form-control" ng-model="email">
              							<p ng-show="myForm.email.$invalid && !myForm.email.$pristine" class="danger-text">Enter a valid email address</p>
              						</div>
              					</div> <!-- ENd of row -->
              					<div class="row">
              						<div class="col-md-6 mb-3">
              							<label for="password">Password</label>
              							<input type="password" class="form-control" id="password" name="password" ng-model="password" ng-minlength="8" ng-maxlength="20" ng-pattern="/(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z])/" required  />
                 <p class="danger-text" ng-show="myForm.password.$error.required && myForm.password.$touched">Password is required</p>
                 <p class="danger-text" ng-show="!myForm.password.$error.required && (myForm.password.$error.minlength || myForm.password.$error.maxlength) && myForm.password.$dirty">Passwords must be between 8 and 20 characters.</p>
                 <p class="danger-text" ng-show="!myForm.password.$error.required && !myForm.password.$error.minlength && !myForm.password.$error.maxlength && myForm.password.$error.pattern && myForm.password.$dirty">Must contain one lower &amp; uppercase letter, and one non-alpha character (a number or a symbol.)</p>
              						</div> <!-- End of col md 6 -->
              						<div class="col-md-6 mb-3">
              							<label>Confirm Password</label>
              							<input type="password" id="confirm_password" name="confirm_password" class="form-control" ng-model="confirm_password" valid-confirm-password required  />
                 <p class="danger-text" ng-show="myForm.confirm_password.$error.required && myForm.confirm_password.$dirty">Please confirm your password.</p>
                 <p class="danger-text" ng-show="!myForm.confirm_password.$error.required && myForm.confirm_password.$error.noMatch && myForm.password.$dirty">Passwords do not match.</p>
              						</div>
              					</div> <!-- ENd of row -->
              					<div class="row">
              						<div class="col-md-12">
              							<button type="submit"  class="btn btn-primary">Submit</button>
              						</div>
              					</div>
              				</form> <!-- End of form -->
              			</div> <!-- End of col sm 12 -->
              		</div> <!-- End of row -->
              	</div> <!-- End of container -->
                </div>

              【讨论】:

                【解决方案11】:

                index.php

                <form class="add-task" id="myForm" name="myForm" method="post" ng-submit="submitForm(myForm.$valid)" novalidate>
                   <div class="form-actions">
                      <!-- ng-patten for validation -->
                      <span class="error" ng-show="myForm.username.$error.required">
                      Required!</span> 
                      <div class="input-group">
                         <input type="text"  ng-model="user2.username"  name="username" ng-pattern="example.word" placeholder="User Name" required>
                         <input  type="password"  ng-model="user2.password"   name="password" placeholder="user password" ng-minlength="4"
                            ng-maxlength="10" required>
                         <button class="btn btn-success" ng-show="displayadd" type="submit"  ng-click="addUser(user2)" ng-disabled="myForm.$invalid"><i class="glyphicon glyphicon-plus"></i> Add New user</button>
                         <button class="btn btn-default" ng-show="displayupdate"  ng-click="updateUser(user2)" value="Update"ng-disabled="myForm.$invalid"><span class="glyphicon glyphicon-save"></span>Save Change</button>
                         <p style="color:red" ng-show="myForm.password.$error.minlength" class="help-block">Password Is Very Short.</p>
                         <p style="color:red"  ng-show="myForm.password.$error.maxlength" class="help-block">Password Is Very Long.</p>
                      </div>
                   </div>
                </form>
                

                app.js 中包含这个函数:

                 $scope.submitForm = function() {
                     if ($scope.myForm.$valid) {
                         alert('Our Form Is Submited....');
                     }
                 };
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2013-11-16
                  • 2012-01-15
                  • 2011-05-18
                  • 1970-01-01
                  • 2013-05-19
                  • 2011-03-12
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多