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 }); //此处为校验的核心代码 $("#register-form").bootstrapvalidator({ submithandler: function (valiadtor, loginform, submitbutton) { valiadtor.defaultsubmit(); }, fields: { username: { validators: { notempty: { message: '用户名不能为空' }, stringlength: { /*长度提示*/ min: 4, max: 30, message: '用户名长度必须在4到30之间' } } }, loginname: { validators: { notempty: { message: '登录邮箱名或用户名不能为空' }, stringlength: { /*长度提示*/ min: 4, max: 30, message: '用户名长度必须在4到30之间' }, threshold: 4,//只有4个字符以上才发送ajax请求 remote: { url: "${basepath}/oauth/checkunique", data: function (validator) { return { loginname: $("#loginname").val(), userid: null }; }, message: '该登录名已被使用,请使用其他登录名', delay:2000 } } }, password: { validators: { notempty: { message: '密码不能为空' }, stringlength: { /*长度提示*/ min: 6, max: 30, message: '密码长度必须在6到30之间' }, different: {//不能和用户名相同 field: 'loginname',//需要进行比较的input name值 message: '不能和用户名相同' }, regexp: { regexp: /^[a-za-z0-9_\.]+$/, message: '密码由数字字母下划线和.组成' } } }, repassword: { message: '密码无效', validators: { notempty: { message: '密码不能为空' }, stringlength: { min: 6, max: 30, message: '用户名长度必须在6到30之间' }, identical: {//相同 field: 'password', message: '两次密码不一致' }, different: {//不能和用户名相同 field: 'loginname', message: '不能和用户名相同' }, regexp: {//匹配规则 regexp: /^[a-za-z0-9_\.]+$/, message: '密码由数字字母下划线和.组成' } } } } }); });
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 { return login_page; } //0 未授权 1 账号问题 2 密码错误 3 账号密码错误 } catch (incorrectcredentialsexception e) { msg = "登录密码错误. password for account " + token.getprincipal() + " was incorrect"; model.addattribute("message", new resultcode("2", msg)); logger.error(msg); } catch (excessiveattemptsexception e) { msg = "登录失败次数过多"; model.addattribute("message", new resultcode("3", msg)); logger.error(msg); } catch (lockedaccountexception e) { msg = "帐号已被锁定. the account for username " + token.getprincipal() + " was locked."; model.addattribute("message", new resultcode("1", msg)); logger.error(msg); } catch (disabledaccountexception e) { msg = "帐号已被禁用. the account for username " + token.getprincipal() + " was disabled."; model.addattribute("message", new resultcode("1", msg)); logger.error(msg); } catch (expiredcredentialsexception e) { msg = "帐号已过期. the account for username " + token.getprincipal() + " was expired."; model.addattribute("message", new resultcode("1", msg)); logger.error(msg); } catch (unknownaccountexception e) { msg = "帐号不存在. there is no user with username of " + token.getprincipal(); model.addattribute("message", new resultcode("1", msg)); logger.error(msg); } catch (unauthorizedexception e) { msg = "您没有得到相应的授权!" + e.getmessage(); model.addattribute("message", new resultcode("1", msg)); logger.error(msg); }
2、前端核心js代码
<script> $(function () { $('input').icheck({ checkboxclass: 'icheckbox_square-red', radioclass: 'iradio_square-red', increasearea: '20%' // optional }); fillbackloginform(); $("#login-form").bootstrapvalidator({ message:'请输入用户名/密码', submithandler:function (valiadtor,loginform,submitbutton) { rememberme($("input[name='rememberme']").is(":checked")); valiadtor.defaultsubmit(); }, fields:{ username:{ validators:{ notempty:{ message:'登录邮箱名或用户名不能为空' } } }, password:{ validators:{ notempty:{ message:'密码不能为空' } } } } }); <!--freemark语法,查看是否从后台传送过来错误信息,并初始化错误提示组件loginvalidator--> <#if message??> new loginvalidator({ code:"${message.code?default('-1')}", message:"${message.message?default('')}", username:'username', password:'password' }); </#if> }); //使用本地缓存记住用户名密码 function rememberme(rm_flag){ //remember me if(rm_flag){ localstorage.username=$("input[name='username']").val(); localstorage.password=$("input[name='password']").val(); localstorage.rememberme=1; } //delete remember msg else{ localstorage.username=null; localstorage.password=null; localstorage.rememberme=0; } } //记住回填 function fillbackloginform(){ if(localstorage.rememberme&&localstorage.rememberme=="1"){ $("input[name='username']").val(localstorage.username); $("input[name='password']").val(localstorage.password); $("input[name='rememberme']").icheck('check'); $("input[name='rememberme']").icheck('update'); } } </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.code==0){ this.addpassworderrormsg(); }else if(this.code==1){ this.addusernameerrorstyle(); this.addusernameerrormsg(); }else if(this.code==2){ this.addpassworderrorstyle(); this.addpassworderrormsg(); }else if(this.code==3){ 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:'结束时间不能小于开始时间' } } },
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:
admineap:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 怎么在1年时间把百度权重做到6