BootstrapValidator实现注册校验和登录错误提示效果(转)
使用BootstrapValidator进行注册校验和登录错误提示,具体内容如下
1、介绍
在AdminEAP框架中,使用了BootstrapValidator校验框架,本文以注册校验的用户名、登录名、密码、确认密码的校验(后面还有时间区间、服务器校验)为例,讲述BootstrapValidator的使用。同时以登录错误提示为例,说明如何在动态改变组件的错误提示信息。
先看下面的注册与登录的校验效果图:
注册校验:

登录错误提示:根据不同的错误类型,动态改变组件的样式和错误提示内容


2、注册校验
1、头部引入bootstrap-validator.css
${basePath}为系统的路径变量
2、form组件
<form action="${basePath}/oauth/register" method="post" id="register-form">
<input type="hidden" name="oAuthId" value="${oAuthInfo.oAuthId?default('-1')}">
<input type="hidden" name="oAuthType" value="${oAuthInfo.oAuthType?default('-1')}">
<div class="form-group has-feedback">
<input type="text" class="form-control" name="userName" id="userName" placeholder="请输入用户名" required>
<span class="glyphicon glyphicon-user form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input type="text" class="form-control" name="loginName" id="loginName" placeholder="请输入登录邮箱/登录名">
<span class="glyphicon glyphicon-envelope form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input type="password" class="form-control" name="password" id="password" placeholder="请输入密码">
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input type="password" class="form-control" name="repassword" id="repassword" placeholder="再次确认密码">
<span class="glyphicon glyphicon-log-in form-control-feedback"></span>
</div>
<div class="row">
<div class="col-xs-12">
<div class="checkbox icheck">
<label>
<input type="checkbox" name="rememberMe" required> 同意遵循<a href="#" rel="external nofollow" >AdminEAP协议</a>
</label>
</div>
</div>
<!-- /.col -->
</div>
<div class="row">
<div class="col-xs-12">
<button type="submit" class="btn btn-danger btn-block btn-flat">注 册</button>
</div>
</div>
</form>
3、引入bootstrap-validator.js
<script src="${basePath}/resources/adminlte/bootstrap/js/bootstrap.min.js"></script>
4、校验的核心js代码
<script>
$(function () {
//将checkbox渲染为icheck样式
$('input').iCheck({
checkboxClass: 'icheckbox_square-red',
radioClass: 'iradio_square-red',
increaseArea: '20%' // optional
});
//此处为校验的核心代码</br>
$("#register-form").bootstrapValidator({</br>
submitHandler: function (valiadtor, loginForm, submitButton) {</br></br>
valiadtor.defaultSubmit();</br>
},</br>
fields: {</br>
userName: {</br>
validators: {</br>
notEmpty: {</br>
message: '用户名不能为空'</br>
},</br>
stringLength: {</br>
/*长度提示*/</br>
min: 4,</br>
max: 30,</br>
message: '用户名长度必须在4到30之间'</br>
}</br>
}</br>
},</br>
loginName: {</br>
validators: {</br>
notEmpty: {</br>
message: '登录邮箱名或用户名不能为空'</br>
},</br>
stringLength: {</br>
/*长度提示*/</br>
min: 4,</br>
max: 30,</br>
message: '用户名长度必须在4到30之间'</br>
},</br>
threshold: 4,//只有4个字符以上才发送ajax请求</br>
remote: {</br>
url: "${basePath}/oauth/checkUnique",</br>
data: function (validator) {</br>
return {</br>
loginName: $("#loginName").val(),</br>
userId: null</br>
};</br>
},</br>
message: '该登录名已被使用,请使用其他登录名',</br>
delay:2000</br>
}</br>
}</br>
},</br>
password: {</br>
validators: {</br>
notEmpty: {</br>
message: '密码不能为空'</br>
},</br>
stringLength: {</br>
/*长度提示*/</br>
min: 6,</br>
max: 30,</br>
message: '密码长度必须在6到30之间'</br>
},</br>
different: {//不能和用户名相同</br>
field: 'loginName',//需要进行比较的input name值</br>
message: '不能和用户名相同'</br>
},</br>
regexp: {</br>
regexp: /^[a-zA-Z0-9_\.]+$/,</br>
message: '密码由数字字母下划线和.组成'</br>
}</br>
}</br>
},</br>
repassword: {</br>
message: '密码无效',</br>
validators: {</br>
notEmpty: {</br>
message: '密码不能为空'</br>
},</br>
stringLength: {</br>
min: 6,</br>
max: 30,</br>
message: '用户名长度必须在6到30之间'</br>
},</br>
identical: {//相同</br>
field: 'password',</br>
message: '两次密码不一致'</br>
},</br>
different: {//不能和用户名相同</br>
field: 'loginName',</br>
message: '不能和用户名相同'</br>
},</br>
regexp: {//匹配规则</br>
regexp: /^[a-zA-Z0-9_\.]+$/,</br>
message: '密码由数字字母下划线和.组成'</br>
}</br>
}</br>
}</br>
}
});
});
5、登录名唯一性校验的后台代码
/**
* 校验当前登录名/邮箱的唯一性
* @param loginName 登录名
* @param userId 用户ID(用户已经存在,即又改回原来的名字还是唯一的)
* @return
*/
@RequestMapping(value = "/oauth/checkUnique", method = RequestMethod.POST)
@ResponseBody
public Map checkExist(String loginName, String userId) {
Map<String, Boolean> map = new HashMap<String, Boolean>();
User user = userService.getUserByLoginName(loginName);
//用户不存在,校验有效
if (user == null) {
map.put("valid", true);
} else {
//用户存在(存在的用户是当前用户,登录名一致,校验通过,否则校验不通过)
if(!StrUtil.isEmpty(userId)&&userId.equals(user.getLoginName())){
map.put("valid",true);
}else {
map.put("valid", false);
}
}
return map;
}
以上的配置完成了注册文本框的各种校验,更多的校验内容,可以查看相关的bootstrap-validator的API文档。
3、登录错误动态提示
1、在后台登录时,会抛出各种登录不成功的提示,需要动态改变前端组件的错误提示信息。不同类型的错误信息编码,要控制不同的组件样式和提示内容。以下是后台抛出的错误类型和错误信息(使用shiro认证)。
try {
subject.login(token);
//通过认证
if (subject.isAuthenticated()) {
Set<String> roles = roleService.getRoleCodeSet(userName);
if (!roles.isEmpty()) {
subject.getSession().setAttribute("isAuthorized", true);
return MAIN_PAGE;
} else {//没有授权
msg = "您没有得到相应的授权!";
model.addAttribute("message", new ResultCode("1", msg));
subject.getSession().setAttribute("isAuthorized", false);
LOGGER.error(msg);
return LOGIN_PAGE;
}
} else {</br>
return LOGIN_PAGE;</br>
}</br>
//0 未授权 1 账号问题 2 密码错误 3 账号密码错误</br>
} catch (IncorrectCredentialsException e) {</br>
msg = "登录密码错误. Password for account " + token.getPrincipal() + " was incorrect";</br>
model.addAttribute("message", new ResultCode("2", msg));</br>
LOGGER.error(msg);</br>
} catch (ExcessiveAttemptsException e) {</br>
msg = "登录失败次数过多";</br>
model.addAttribute("message", new ResultCode("3", msg));</br>
LOGGER.error(msg);</br>
} catch (LockedAccountException e) {</br>
msg = "帐号已被锁定. The account for username " + token.getPrincipal() + " was locked.";</br>
model.addAttribute("message", new ResultCode("1", msg));</br>
LOGGER.error(msg);</br>
} catch (DisabledAccountException e) {</br>
msg = "帐号已被禁用. The account for username " + token.getPrincipal() + " was disabled.";</br>
model.addAttribute("message", new ResultCode("1", msg));</br>
LOGGER.error(msg);</br>
} catch (ExpiredCredentialsException e) {</br>
msg = "帐号已过期. the account for username " + token.getPrincipal() + " was expired.";</br>
model.addAttribute("message", new ResultCode("1", msg));</br>
LOGGER.error(msg);</br>
} catch (UnknownAccountException e) {</br>
msg = "帐号不存在. There is no user with username of " + token.getPrincipal();</br>
model.addAttribute("message", new ResultCode("1", msg));</br>
LOGGER.error(msg);</br>
} catch (UnauthorizedException e) {</br>
msg = "您没有得到相应的授权!" + e.getMessage();</br>
model.addAttribute("message", new ResultCode("1", msg));</br>
LOGGER.error(msg);</br>
}</br></br>
2、前端核心JS代码
<script>
$(function () {
$('input').iCheck({
checkboxClass: 'icheckbox_square-red',
radioClass: 'iradio_square-red',
increaseArea: '20%' // optional
});
fillbackLoginForm();</br>
$("#login-form").bootstrapValidator({</br>
message:'请输入用户名/密码',</br>
submitHandler:function (valiadtor,loginForm,submitButton) {</br>
rememberMe($("input[name='rememberMe']").is(":checked"));</br>
valiadtor.defaultSubmit();</br>
},</br>
fields:{</br>
userName:{</br>
validators:{</br>
notEmpty:{</br>
message:'登录邮箱名或用户名不能为空'</br>
}</br>
}</br>
},</br>
password:{</br>
validators:{</br>
notEmpty:{</br>
message:'密码不能为空'</br>
}</br>
}</br>
}</br>
}</br>
});</br>
<!--freemark语法,查看是否从后台传送过来错误信息,并初始化错误提示组件LoginValidator--></br>
<#if message??></br>
new LoginValidator({</br>
code:"${message.code?default('-1')}",</br>
message:"${message.message?default('')}",</br>
userName:'userName',</br>
password:'password'</br>
});</br>
</#if></br>
});</br></br>
//使用本地缓存记住用户名密码</br>
function rememberMe(rm_flag){</br>
//remember me</br>
if(rm_flag){</br>
localStorage.userName=$("input[name='userName']").val();</br>
localStorage.password=$("input[name='password']").val();</br>
localStorage.rememberMe=1;</br>
}</br>
//delete remember msg</br>
else{</br>
localStorage.userName=null;</br>
localStorage.password=null;</br>
localStorage.rememberMe=0;</br>
}</br>
}</br></br>
//记住回填</br>
function fillbackLoginForm(){</br>
if(localStorage.rememberMe&&localStorage.rememberMe=="1"){</br>
$("input[name='userName']").val(localStorage.userName);</br>
$("input[name='password']").val(localStorage.password);</br>
$("input[name='rememberMe']").iCheck('check');</br>
$("input[name='rememberMe']").iCheck('update');</br>
}</br>
}</br>
</script>
3、LoginValidator组件的代码 login.js
/**
* Created by billJiang on 2017/1/12.
* 登录异常信息显示
*/
function LoginValidator(config) {
this.code = config.code;
this.message = config.message;
this.userName = config.userName;
this.password = config.password;
this.initValidator();
}
//0 未授权 1 账号问题 2 密码错误 3 账号密码错误
LoginValidator.prototype.initValidator = function () {
if (!this.code)
return;
if(this.code0){
this.addPasswordErrorMsg();
}else if(this.code1){
this.addUserNameErrorStyle();
this.addUserNameErrorMsg();
}else if(this.code2){
this.addPasswordErrorStyle();
this.addPasswordErrorMsg();
}else if(this.code3){
this.addUserNameErrorStyle();
this.addPasswordErrorStyle();
this.addPasswordErrorMsg();
}
return;
}
LoginValidator.prototype.addUserNameErrorStyle = function () {
this.addErrorStyle(this.userName);
}
LoginValidator.prototype.addPasswordErrorStyle = function () {
this.addErrorStyle(this.password);
}
LoginValidator.prototype.addUserNameErrorMsg = function () {
this.addErrorMsg(this.userName);
}
LoginValidator.prototype.addPasswordErrorMsg = function () {
this.addErrorMsg(this.password);
}
LoginValidator.prototype.addErrorMsg=function(field){
$("input[name='"+field+"']").parent().append('<small data-bv-validator="notEmpty" data-bv-validator-for="'+field+'" class="help-block">' + this.message + '</small>');
}
LoginValidator.prototype.addErrorStyle=function(field){
$("input[name='" + field + "']").parent().addClass("has-error");
}
以上把错误提示封装成了一个LoginValidator组件,方便前端调用,增强代码的可维护性,因为没有找到Bootstrap-validator改变错误提示的接口,所以查看了源码之后做了封装。
4、补充
1、时间区间校验
"startTime":{
validators:{
date:{
format:'YYYY-MM-DD HH:mm',
message:'日期格式不正确'
},
callback:{
callback:function(value,validator){
var startTime=value;
var endTime=$("#endTime").val();
if(startTime&&endTime){
return DateDiff(endTime,startTime)>0;
}else{
return true;
}
},
message:'结束时间不能小于开始时间'
}
}
},
"endTime":{
validators:{
date:{
format:'YYYY-MM-DD HH:mm',
message:'日期格式不正确'
},
callback:{
callback:function(value,validator){
var startTime=$("#startTime").val();
var endTime=value;
if(startTime&&endTime){
return DateDiff(endTime,startTime)>0;
}else{
return true;
}
},
message:'结束时间不能小于开始时间'
}
}</br>
},</br>
2、服务器校验
"jobClass": {
validators: {
notEmpty: {message: '执行类名不能为空'},
remote:{
url:basePath+"/job/checkJobClass",
data: function(validator) {
return {
jobClass:$('#jobClass').val(),
};
},
message:'该执行类不存在'
}
}
}
后台代码
@RequestMapping(value="/checkJobClass",method = RequestMethod.POST)
@ResponseBody
public Map checkJobClass(String jobClass){
Map map=new HashMap<>();
try {
Class<?> objClass = Class.forName(jobClass);
if(objClass!=null)
map.put("valid", true);
return map;
} catch (Exception ex) {
logger.error(ex.getMessage().toString());
map.put("valid", false);
return map;
}
}
Github: https://github.com/bill1012
AdminEAP:http://www.admineap.com
</div>
BootstrapValidator实现注册校验和登录错误提示效果(转)的更多相关文章
- jenkins用户权限配置错误,导致登录时提示:没有Overall/read权限
jenkins用户权限配置错误,导致登录时提示:没有Overall/read权限 由于初次接触jenkins,于是在搭建好jenkins以后,想要对用户进行管理,于是乎开始在系统管理->conf ...
- 第三百八十五节,Django+Xadmin打造上线标准的在线教育平台—登录功能实现,回填数据以及错误提示html
第三百八十五节,Django+Xadmin打造上线标准的在线教育平台—登录功能实现 1,配置登录路由 from django.conf.urls import url, include # 导入dja ...
- MSSQL 2008错误提示:更改对于登录sa失败
MSSQL 2008错误提示:更改对于登录sa失败: 使用Windows方式登录数据库后,执行以下命令: EXEC sp_password null,"123456"," ...
- Oracle登录时提示错误,导致用户无法登录
Oracle登录时提示错误,导致用户无法登录,错误如下 ------------------------------------------------------------------------ ...
- Mac下jenkins用户权限配置错误,导致登录时提示:没有Overall/read权限
由于初次接触jenkins,于是在搭建好jenkins以后,想要对用户进行管理,于是乎开始在系统管理->configure Global Security里设置用户的权限. 在启用安全-> ...
- 登录PL/SQL无法登录,提示错误:ORA-01017: invalid username/password; logon denied 错误
在使用在登录PL/SQL(使用scott用户)无法登录,提示错误:ORA-01017: invalid username/password; logon denied 错误(程序中的用户和密码无法登录 ...
- selenium(python)登录时账号密码错误提示语
selenium(python)登录时账号密码错误提示语的获取 可以用text
- [转] Citrix XenDesktop桌面登录VM提示Citrix Web插件错误
[From] http://blog.51cto.com/xuhaili100love/1223707 [适用版本] 适用所有Citrix虚拟桌面版本 [现象描述] 使用SC登录虚拟机提示“无法访问您 ...
- 很实用的HTML5+CSS3注册登录窗体切换效果
1. [代码]3个很实用的HTML5+CSS3注册登录窗体切换效果 <!DOCTYPE html><!--[if lt IE 7 ]> <html lang=" ...
随机推荐
- mac使用ssh出现permission denied(publickey)
看出错信息是权限太开放的问题,google了一下,修改权限,不只是需要修改 .pem 文件的权限,还需要修改.ssh目录和用户目录 chmod go-w ~/ chmod ~/.ssh chmod ~ ...
- 04-4-typeof
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- [转]C#中用NamedPipe进程间通信
转自:http://blog.csdn.net/jinjazz/archive/2009/02/03/3861143.aspx 本文只是一个测试例子,核心代码是kernel32.dll中的一组wind ...
- HTML5移动开发中的input输入框类型 (转)
公司的项目开发过程中的,的用户体验忽略了.登录tel就用tel属性.新来的小伙伴提醒的.谢谢他 数字类型number 定义input类型为type="number"时,iOS显示数 ...
- linux学习(一)-----vm、centos安装
安装vm和Centos 1)先安装 virtual machine ,vm12 2)再安装 Linux (CentOS 6.8) 3)原理示意图,这里我们画图说明一下 VM 和 CentOS 的关系. ...
- [code]彩色图像直方图均衡化 histogram_rgb
//2013.9 eageldiao #ifdef HISTOGRAM_RGB unsigned ]; unsigned intncount[]={},ncount1[]={},ncount2[]={ ...
- jquery同级遍历
siblings() 返回被选元素的所有同胞元素. next() 返回被选元素的下一个同胞元素. nextAll() 方法返回被选元素的所有跟随的同胞元素. nextUntil() 方法返回介于两个给 ...
- 015-WebDriver API
1. 从定位元素开始 8种元素定位方法 id find_element_by_id( ) name find_element_by_name( ) tag find_element_by_tag_na ...
- LeetCode412Fizz Buzz
写一个程序,输出从 1 到 n 数字的字符串表示. 1. 如果 n 是3的倍数,输出"Fizz": 2. 如果 n 是5的倍数,输出"Buzz": 3.如果 n ...
- 好用的Win10快捷键
好用的Win10快捷键 Top 01 基础按键 Win+E: 打开"资源管理器". Win+R: 打开"运行"对话框. Win+L: 锁定当前用户. Win+D ...