虽然说AngularJS的实时表单验证非常有用,非常高效方便,但是当用户还没有完成输入时便弹出一个错误提示,这种体验是非常糟糕的。

正常的表单验证逻辑应该是在用户提交表单后或完成当前字段中的输入后,再提示验证信息,这样才是用户友好的。下面就来看看如何实现

  • 在表单提交后显示验证信息
  • 在失焦后显示验证信息

  在表单提交后显示验证信息

  在用户试图提交表单时,你可以在作用域中捕获一个submitted值,然后对表单内容进行验证并显示错误信息。

下面通过一个简单的例子来说明,只在用户提交表单时才显示错误信息。在ng-show 指令中添加对submitted(判断表单是否提交)的检查,仅有当submitted的值为true(即表示表单已提交)同时该表单元素是处于$invalid状态的时候,错误信息就会显示出来

  HTML代码

<form name="registerForm" class="registerForm" novalidate ng-submit="register(user)">
<div class="title">欢迎注册,和我们一起甜蜜生活</div>
<div class="form-group " ng-class="registerForm.username.$invalid ? '' : 'has-success'">
<div class="input-group">
<div class="input-group-addon"><span class=" iconfont icon-register icon-phone"></span></div>
<input type="text" name="username" class="form-control" placeholder="请输入手机号码"
ng-model="user.username"
maxlength="11" required ng-pattern="/1[3|5|7|8|][0-9]{9}/"/>
</div>
<div class="form-error"
ng-show="registerForm.username.$invalid && submitted ">
<span ng-show="registerForm.username.$error.required">手机号不能为空</span>
<span ng-show="registerForm.username.$error.pattern">请输入正确的手机号码</span>
</div>
</div>
<input type="submit" value="注册" class="btn btn-register btn-tianmi"/>
{{result}}
</form>

Controller代码

$scope.submitted = false
$scope.register = function (user) {
//表单正常提交
if($scope.registerForm.$valid){
//正常提交表单
}
else{
$scope.submitted = true;
}
};

通过上面的方法,便可以实现用户在有非法输入的情况下提交表单,将显示错误信息

  在失焦后显示验证信息

  要想保留用户在输入某个字段失焦后提示错误信息,需要实现一个ngFocus的指令,并在表单中添加该指令

  ngFocus指令代码

.directive('ngFocus', function () {
var FOCUS_CLASS = "ng-focused";
return{
restrict:'A',
require:'ngModel',
link: function (scope, element, attrs,ctrl) {
ctrl.$focused = false;
element.bind('focus', function (evt) {
element.addClass(FOCUS_CLASS);
scope.$apply(function () {
ctrl.$focused = true;
});
}).bind('blur', function () {
element.removeClass(FOCUS_CLASS);
scope.$apply(function(){
ctrl.$focused = false;
})
})
}
}
})

接下来将ngFocus指令添加到input的元素上就可以使用该指令,依然用上面的表单例子

<form name="registerForm" class="registerForm" novalidate ng-submit="register(user)">
<div class="title">欢迎注册,和我们一起甜蜜生活</div>
<div class="form-group " ng-class="registerForm.username.$invalid ? '' : 'has-success'">
<div class="input-group">
<div class="input-group-addon"><span class=" iconfont icon-register icon-phone"></span></div>
<input type="text" name="username" class="form-control" placeholder="请输入手机号码"
ng-model="user.username"
maxlength="11" required ng-pattern="/1[3|5|7|8|][0-9]{9}/" ng-focus/>
</div>
<div class="form-error"
ng-show="registerForm.username.$invalid && !registerForm.username.$focused ">
<span ng-show="registerForm.username.$error.required">手机号不能为空</span>
<span ng-show="registerForm.username.$error.pattern">请输入正确的手机号码</span>
</div>
</div>
<input type="submit" value="注册" class="btn btn-register btn-tianmi"/>
{{result}}
</form>

ngFocus指令给表单输入字段的blur和focus添加了相应的行为,添加了一个名为ng-focused的类,并将$focused的值设置为true。这样就可以通过判断表单是否具有焦点来显示错误信息

            <div class="form-error"
ng-show="registerForm.username.$invalid && !registerForm.username.$focused ">
<span ng-show="registerForm.username.$error.required">手机号不能为空</span>
<span ng-show="registerForm.username.$error.pattern">请输入正确的手机号码</span>
</div>

  当然了,在正常的情况下,我们一般是使用失焦后验证+表单提交后验证两种方式相结合的形式来进行表单验证。下面就通过一个完整的用户注册例子来显示如果实现这种验证方式。

HTMl代码

    <form name="registerForm" class="registerForm" novalidate ng-submit="register(user)">
<div class="title">欢迎注册,和我们一起甜蜜生活</div>
<div class="form-group " ng-class="registerForm.username.$invalid ? '' : 'has-success'">
<div class="input-group">
<div class="input-group-addon"><span class=" iconfont icon-register icon-phone"></span></div>
<input type="text" name="username" class="form-control" placeholder="请输入手机号码"
ng-model="user.username"
maxlength="11" required ng-pattern="/1[3|5|7|8|][0-9]{9}/" ng-focus/>
</div>
<div class="form-error"
ng-show="(registerForm.username.$invalid && registerForm.username.$dirty && !registerForm.username.$focused) || (registerForm.username.$invalid && submitted )">
<span ng-show="registerForm.username.$error.required">手机号不能为空</span>
<span ng-show="registerForm.username.$error.pattern">请输入正确的手机号码</span>
</div>
</div> <div class="form-group row sms-code-row">
<div class="col-xs-6 input-sms-code">
<input type="text" value="" name="sms_code" class="form-control" ng-model="user.sms_code"
placeholder="请输入6位验证码" required ng-maxlength="6" maxlength="6"/>
</div>
<div class="col-xs-6 btn-sms-code">
<button type="button" class="btn btn-default btn-register btn-tianmi"
ng-click="getVerifyCode(user.username)"
ng-disabled="sms_code_status || registerForm.username.$invalid">{{sms_code_content}}
</button>
</div>
<div class="clearfix"></div>
<div class="form-error"
ng-show="(registerForm.sms_code.$invalid && registerForm.sms_code.$dirty) ||(registerForm.sms_code.$invalid && submitted) ">
<span ng-show="registerForm.sms_code.$error.required">请输入验证码</span>
</div>
</div> <div class="form-group">
<div class="input-group">
<div class="input-group-addon"><span class=" iconfont icon-register icon-key"></span></div>
<input type="password" name="password" ng-model="user.password" class="form-control"
placeholder="请输入登录密码"
required
ng-focus
minlength="6"
ng-pattern="/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$/"/>
</div>
<div class="form-error"
ng-show="(registerForm.password.$invalid && registerForm.password.$dirty && !registerForm.password.$focused) || (registerForm.password.$invalid && submitted)">
<span ng-show="registerForm.password.$error.minlength">密码不能少于6位</span>
<span ng-show="registerForm.password.$error.pattern">密码必须由数字和字母组成</span>
<span ng-show="registerForm.password.$error.required">密码不能为空</span>
</div>
</div> <div class="form-group">
<div class="input-group">
<div class="input-group-addon"><span class=" iconfont icon-register icon-key"></span></div>
<input type="password" name="repeat_password" class="form-control"
ng-model="user.repeat_password" ng-focus
placeholder="请再次输入密码" required pw-check match="user.password"/>
<!--<span class="iconfont icon-yonghu"></span>-->
</div>
<div class="form-error"
ng-show="(registerForm.repeat_password.$invalid && registerForm.repeat_password.$dirty && registerForm.repeat_password.$focused) || (registerForm.repeat_password.$invalid && submitted)">
<span ng-show="registerForm.repeat_password.$error.required">密码不能为空</span>
<span ng-show="registerForm.$error.matchError">两次密码不一样</span>
</div>
</div> <div class="form-group">
<div class="input-group">
<div class="input-group-addon"><span class=" iconfont icon-register icon-yonghu"></span></div>
<input type="text" name="nick_name" class="form-control" ng-model="user.nick_name"
placeholder="请输入昵称"
minlength="2"
maxlength="20"
ng-focus
ng-pattern="/^[a-zA-Z0-9\u0391-\uFFE5]{2,20}$/ "
required/>
</div>
<div class="form-error"
ng-show="(registerForm.nick_name.$invalid && registerForm.nick_name.$dirty && registerForm.nick_name.$focused) || (registerForm.nick_name.$invalid && submitted)">
<span ng-show="registerForm.nick_name.$error.required">昵称不能为空</span>
<span ng-show="registerForm.nick_name.$error.pattern">昵称为2-20个字符,可由中文、字母和数字组成</span>
</div>
</div> <div class="checkbox">
<label>
<input type="checkbox" name="protocol" ng-model="protocol" required> 同意&nbsp;&nbsp;<a
class="protocol" href="http://123.57.246.184/wordpress/?p=1941" target="_blank">添米用户注册协议</a>&nbsp;和&nbsp;<a
class="protocol" href="http://123.57.246.184/wordpress/?p=1939" target="_blank">添米投资服务协议</a>
</label>
<div class="form-error" ng-show="!protocol && submitted">
<span>请先同意协议</span>
</div>
</div>
<input type="submit" value="注册" class="btn btn-register btn-tianmi"/>
{{result}}
</form>

controller代码

$scope.submitted = false
$scope.register = function (user) {
//表单正常提交
if($scope.registerForm.$valid){
//正常提交表单
}
else{
$scope.submitted = true;
}
};

AngularJS 表单提交后显示验证信息与失焦后显示验证信息的更多相关文章

  1. AngularJs 表单提交按钮状态

    表单属性: $invalid:未经过验证的表单,就是表单里面信息通过验证就为false,没有通过为true $valid:经过验证的表单,表单里信息验证通过为true,反之为false $dirty: ...

  2. thinkPHP5.0使用form表单提交数据和删除文章,不用TP的提示页面,使用弹出提示信息

    form表单提交数据和删除文章时,TP的默认信息提示页面的看起来不是很好看,想要实现弹窗提示怎么做呢? 前端:可以使用前端的一个知识--iframe,iframe元素会创建包含另外一个文档的内联框架: ...

  3. js实现表单提交submit(),onsubmit

    通常表单的提交有两种方式,一是直接通过html的form提交,代码如下: <form action="" method="" id="forms ...

  4. tp框架表单提交注意!不要提交到当前方法

    tp框架  表单提交到当前方法,会重复执行显示部分和保存部分的代码.导致不知名的错误.

  5. MVC Html.AntiForgeryToken(); 防止跨站伪造请求(建议所有表单提交都加这个)

    视图页面from表单中添加 @Html.AntiForgeryToken(); 然后每个表单提交的时候都会带__RequestVerificationToken 字段 后端控制器验证时添加  [Val ...

  6. javascript实现表单提交加密

    javascript实现表单提交加密 通常表单的提交有两种方式,一是直接通过html的form提交,代码如下: <form action="" method="&q ...

  7. 在客户端先通过JS验证后再将表单提交到服务器

    问题:想要在客户端先通过JS验证后再将表单提交到服务器 参考资料: jQuery 事件 - submit() 方法 试验过程: 服务器端使用PHP <html> <head> ...

  8. springmvc下js控制表单提交(表单提交前检验,提交后获取json返回值)

    这个问题我搞了四天,终于搞懂.因为对js很不熟悉.郁闷的是后台代码出错总可以设置断点调试,前端js代码出错只能通过浏览器提供一些运行数据来分析,很不习惯. 首先说下逻辑:这是一个注册功能,我希望,注册 ...

  9. AngularJS表单验证,手动验证或自动验证

    AngularJS的表单验证大致有两种,一种是手动验证,一种是自动验证. 手动验证 所谓手动验证是通过AngularJS表单的属性来验证.而成为AngularJS表单必须满足两个条件:1.给form元 ...

随机推荐

  1. js打印(控件)及多种方式

    非常好用的LODOP打印控件 Lodop打印控件简单使用方法 1.安装. 2.调用LodopFuncs.js文件. 3.增加OBJECT对象 <script language="jav ...

  2. 如何用rake tasks 生成migration对应的sql

    how-to-use-rake-tasks-to-generate-migration-sql Rakefile文件里有load_tasks的方法 http://api.rubyonrails.org ...

  3. 对于(function(){}())和function(){}实例的作用域分析(里面有很多问题……)

    今天在群里看到一个问题,让我纠结了好一会.下面是我的分析,感觉里面还有很多问题,关于作用域还是不太理解,希望大家看到问题第一时间反馈给我,看到实在受不了的地方说几句都没关系,谢谢. 请看题: 1.对象 ...

  4. OpenStack 的Nova组件详解

    Open Stack Compute Infrastructure (Nova) Nova是OpenStack云中的计算组织控制器.支持OpenStack云中实例(instances)生命周期的所有活 ...

  5. 用chrome模拟微信浏览器访问需要OAuth2.0网页授权的页面

    现在很流行微信网页小游戏,用html5制作的小游戏移过来,可以放到微信浏览器中打开,关键是可以做成微信分享朋友圈的形式,大大提高游戏的传播,增强好友的游戏互动. 微信浏览器中打开网页游戏效果还不错,对 ...

  6. 【Redis】Redis分布式集群几点说道

    Redis数据量日益增大,使用的公司越来越多,不仅用于做缓存,同时趋向于存储这一块,这样必促使集群的发展,各个公司也在收集适合自己的集群方案,目前行业用的比较多的是下面几种集群架构,大部分都是采用分片 ...

  7. 【leetcode】Palindrome Partitioning

    Palindrome Partitioning Given a string s, partition s such that every substring of the partition is ...

  8. sina第三方登录

    Sina  第三方登录 添加网站的流程如下: Sina接入主要审核点: • 1.网站可正常访问:若页面无法打开,或加载时间过长,或未建设完成的网站.或空白网站将无法通过审核: • 2.站点已部署微连接 ...

  9. 【python-mysql】在ubuntu下安装python-mysql环境

    1.先安装mysql sudo apt-get install mysql-server apt-get isntall mysql-client sudo apt-get install libmy ...

  10. Fresco 源码分析(三) Fresco服务端处理(3) DataSource到Producer的适配器逻辑以及BitmapMemoryCacheProducer处理的逻辑

    4.3.1.2.1 Producer和DataSource之间适配器处理的逻辑 还是从程序的入口开始说吧 CloseableProducerToDataSourceAdapter.create() 源 ...