欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-09-30 10:10:39
使用bootstrapvalidator进行注册校验和登录错误提示,具体内容如下 1、介绍 在admineap框架中,使用了bootstrapvalidator校验...

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

1、介绍

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

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

注册校验:

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

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

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

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