zoukankan      html  css  js  c++  java
  • BootstrapValidator实现注册校验和登录错误提示效果(转)

    使用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
    });

    //此处为校验的核心代码</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>
      &lt;!--freemark语法,查看是否从后台传送过来错误信息,并初始化错误提示组件LoginValidator--&gt;</br>
      &lt;#if message??&gt;</br>
        new LoginValidator({</br>
          code:"${message.code?default('-1')}",</br>
          message:"${message.message?default('')}",</br>
          userName:'userName',</br>
          password:'password'</br>
        });</br>
      &lt;/#if&gt;</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&amp;&amp;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.code
    1){

    this.addUserNameErrorStyle();

    this.addUserNameErrorMsg();

    }else if(this.code2){

    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:'结束时间不能小于开始时间'
    }

          }</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>
  • 相关阅读:
    软件工程概论第十六周学习进度表
    构建之法阅读笔记06
    软件工程概论第十五周学习进度表
    手机百度输入法的用户体验
    构建之法阅读笔记05
    软件工程概论第十四周学习进度表
    2020/2/1-Python学习计划
    Map Reduce数据清洗及Hive数据库操作
    《大数据技术原理与应用》暑假学习计划_06
    分布式数据库的安装与配置
  • 原文地址:https://www.cnblogs.com/jpfss/p/8472172.html
Copyright © 2011-2022 走看看