当前位置: 移动技术网 > IT编程>开发语言>JavaScript > BootstrapValidator实现注册校验和登录错误提示效果

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

2019年06月11日  | 移动技术网IT编程  | 我要评论

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

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网