JavaScript

超轻量级php框架startmvc

BootstrapValidator实现注册校验和登录错误提示效果

更新时间:2020-04-29 08:12:01 作者:startmvc
使用BootstrapValidator进行注册校验和登录错误提示,具体内容如下1、介绍在AdminEAP框架中,使

使用BootstrapValidator进行注册校验和登录错误提示,具体内容如下

1、介绍

在AdminEAP框架中,使用了BootstrapValidator校验框架,本文以注册校验的用户名、登录名、密码、确认密码的校验(后面还有时间区间、服务器校验)为例,讲述BootstrapValidator的使用。同时以登录错误提示为例,说明如何在动态改变组件的错误提示信息。

先看下面的注册与登录的校验效果图:

注册校验:

注册校验

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

账号问题

账号问题

2、注册校验

1、头部引入bootstrap-validator.css

<link rel="stylesheet"  href="${basePath}/resources/adminlte/plugins/bootstrap-validator/dist/css/bootstrap-validator.css" rel="external nofollow" />

${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: https://github.com/bill1012 AdminEAP:http://www.admineap.com

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

bootstrap validator 注册校验 登录错误提示