如何简化表单验证?

时间:2013-02-22 10:38:10

标签: angularjs

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

如果字段为脏+无效,则表单显示红色的名称是必需的消息;如果字段为脏+有效,则表单显示 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属性。

11 个答案:

答案 0 :(得分:35)

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

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

}

答案 1 :(得分:8)

我知道这个问题已经过时了,但我想与世界分享我的新角度指令,我在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"中定义我想要的任何数量的验证规则,并且错误消息将始终显示在下一个<span>你们不喜欢它们吗?输入的1行代码,错误显示的1行代码,你不能比那简单...哦,如果你想添加:)我甚至支持你的自定义正则表达式:)

当你需要的只有2行时,不再需要10行代码的集群表格,即使对于有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
重构了该指令,以便需要使用<span>来显示错误,该指令现在自己处理它,请参阅顶部反映的代码更改。

样本
Plunker

上添加了一个实时演示

答案 2 :(得分:5)

请使用此CSS

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

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

答案 3 :(得分:4)

您可以使用Angular-Validator

它将

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

    1. 显示成功消息(即将支持成功消息)。
    2. 实施例

      <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的作者

答案 4 :(得分:3)

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

指向demo site的链接 https://github.com/refactorthis/xtform

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

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

答案 5 :(得分:1)

考虑使用我一直在努力的 ngValidate 模块。

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

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

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

答案 6 :(得分:0)

试试这个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>

答案 7 :(得分:0)

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

答案 8 :(得分:0)

对于这个问题,我可能为时已晚,但您可以使用外部库来为您处理验证。 Angular form validator(由我编写)通过使用少量标准验证器(例如

)使其变得更容易
  1. 必需
  2. 字符串(最小/最大长度)
  3. 数字(最小/最大值)
  4. 模式
  5. 电子邮件
  6. 地址
  7. 等于(用于验证电子邮件/密码)
  8. 自定义(您可以插入自己的验证)
  9. 它允许将多个验证器组合到一个字段中。

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

答案 9 :(得分:0)

codpen link

上查看我的angularJS表格验证

我已经展示了如何在我的演示中验证所需,minlength,maxlength,电子邮件,密码大小写,确认密码匹配的示例。

以下是代码:

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>

答案 10 :(得分:-2)

index.php

Error: ClusterManager instance has no attribute 'sub_services'

app.js 中包含此功能:

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