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

jQuery实现高度灵活的表单验证功能示例【无UI】

程序员文章站 2022-05-24 13:52:01
本文实例讲述了jquery实现高度灵活的表单验证功能。分享给大家供大家参考,具体如下:表单验证是前端开发过程中常见的一个需求,产品需求、业务逻辑的不同,表单验证的方式方法也有所区别。而最重要的是我们要...

本文实例讲述了jquery实现高度灵活的表单验证功能。分享给大家供大家参考,具体如下:

表单验证是前端开发过程中常见的一个需求,产品需求、业务逻辑的不同,表单验证的方式方法也有所区别。而最重要的是我们要清楚,表单验证的核心原则是——错误信息提示准确,并且尽可能少的打扰/干扰用户的输入和体验。

该插件依赖于jquery,demo地址:https://github.com/captainliao/zujian/tree/master/validator

基于以上原则,个人总结出表单验证的通用方法论:

为了使开发思路更加清晰,我将表单验证的过程分为两步:第一步,用户输入完验证当前输入的有效性;第二步,表单提交时验证整个表单。考虑如下布局:

<form action="">
  <ul>
    <li><label for="username">用户名</label>
      <input type="text" name="username" id="username" placeholder="用户名"/></li>
    <li>
      <label for="password">密码</label>
      <input type="text" name="password" id="password" placeholder="密码"/>
    </li>
    <li>
      <label for="password">确认密码</label>
      <input type="text" name="password2" id="password-confirm" placeholder="确认密码"/>
    </li>
    <li>
      <label for="phone">手机</label>
      <input type="text" name="mobile" id="phone"/>
    </li>
    <li>
      <label for="email">邮箱</label>
      <input type="text" name="email" id="email"/>
    </li>
  </ul>

  <button type="submit" id="submit-btn">提交</button>

</form>

一个较为通用的js验证版本如下:

(function (window, $, undefined) {
  /**
   * @param {string}    $el       表单元素
   * @param {[array]}    rules      自定义验证规则
   * @param {[boolean]}   ischeckall   表单提交前全文验证
   * @param {[function]}  callback    全部验证成功后的回调
   * rules 支持四个字段:name, rule, message, equalto
   */
  function validator($el, rules, ischeckall, callback) {
    var required = 'required';
    var params = array.prototype.slice.call(arguments);
    this.$el = $el;
    this._rules = [
      {// 用户名
        username: required,
        rule: /^[\u4e00-\u9fa5\w]{6,12}$/,
        message: '不能包含敏感字符'
      }, {// 密码
        password: required,
        rule: /^(?![0-9]+$)(?![a-za-z]+$)[0-9a-za-z_@]{6,20}$/,
        message: '只支持数字字母下划线,且不为纯数字或字母'
      }, {// 重复密码
        password2: required,
        rule: /^(?![0-9]+$)(?![a-za-z]+$)[0-9a-za-z_@]{6,20}$/,
        message: '只支持数字字母下划线,且不为纯数字或字母',
        equalto: 'password'
      }, {// 手机
        mobile: required,
        rule: /^1[34578]\d{9}$/,
        message: '请输入有效的手机号码'
      }, {// 验证码
        code : required,
        rule: /^\d{6}$/,
        message: '请输入6位数字验证码'
      }, {// 邮箱
        email : required,
        rule: /^[a-za-z0-9\u4e00-\u9fa5]+@[a-za-z0-9_-]+(\.[a-za-z0-9_-]+)+$/,
        message: '请输入正确的邮箱'
      }
    ];
    this.ischeckall = false;
    this.callback = callback;
    // 合并参数
    this._rules = this._rules.concat(params[1]);
    if(params[2]) {
      if(typeof params[2] == 'function') {
        this.callback = params[2];
      }else {// 提交表单时是否开启全部验证
        this.ischeckall = params[2];
      }
    }
    // 用于存储合去重后的参数
    this.rules = [];
  }

  validator.prototype._getkey = function (obj) {
    var k = '';
    for(var key in obj) {
      if(obj.hasownproperty(key)) {
        if( key !== 'rule' && key !== 'message' && key !== 'equalto') {
          k = key;
        }
      }
    }
    return k;
  };
  /**
   * 数组对象重复数据进行合并,后面的覆盖前面的
   */
  validator.prototype.filterrules = function (arrobj) {
    var _this = this,
      h = {},
      res = [],
      arrobject = this._rules;
    $.each(arrobject, function (i, item) {
      var k = _this._getkey(item);
      try {
        if(!h[k] && h[k] !== 0) {
          h[k] = i;
          res.push(item);
        }else {
          res[h[k]] = $.extend(res[h[k]], item);
        }
      }catch(e) {
        throw new error('不是必填')
      }
    });
    this.rules = res;
  };

  validator.prototype.check = function () {
    var _this = this;
    $.each(_this.rules, function (i, item) {
      var key = _this._getkey(item),
        reg = item.rule,
        equalto = item.equalto,
        errmsg = item.message;

      _this.$el.find('[name='+key+']')
        .on('blur', function () {
          var $this = $(this),
            errormsg = '',
            val = $this.val(),
            ranges = reg.tostring().match(/(\d*,\d*)/),
            range = '',
            min = 0,
            max = 0,
            placeholdertxt = $(this).attr("placeholder") ? $(this).attr("placeholder") : '信息';

          // 定义错误提示信息
          if(val && val != 'undefined') { // 值不为空

            if(ranges) { // 边界限定
              range = ranges[0];
              min = range.split(',')[0] ? range.split(',')[0].trim() : 0;
              max = range.split(',')[1] ? range.split(',')[1].trim() : 0;
              if(val.length < min || val.length > max) { // 处理边界限定的情况
                if(min && max) {
                  errormsg = '<span class="error-msg">请输入'+min+'-'+max+'位'+placeholdertxt+'</span>';
                }else if(min) {
                  errormsg = '<span class="error-msg">最少输入'+min+'位'+placeholdertxt+'</span>';
                }else if(max) {
                  errormsg = '<span class="error-msg">最多输入'+max+'位'+placeholdertxt+'</span>';
                }
              }else { // 边界正确但匹配错误
                errormsg = '<span class="error-msg">'+errmsg+'</span>';

              }
            }else { // 没有边界限定
              errormsg = '<span class="error-msg">'+errmsg+'</span>';
            }

            if(equalto) {
              var equaltoval = _this.$el.find('[name='+equalto+']').val();
              if(val !== equaltoval) {
                errormsg = '<span class="error-msg">两次输入不一致,请重新输入</span>';
              }
            }

          } else { // 值为空
            errormsg = '<span class="error-msg">请输入'+placeholdertxt+'</span>'
          }
          if($('.error-msg').length > 0) return;

          // 验证输入,显示提示信息
          if(!reg.test(val) || (equalto && val !== equaltoval)) {
            if($this.siblings('.error-msg').length == 0) {
              $this.after(errormsg)
                .siblings('.error-msg')
                .hide()
                .fadein();
            }
          }else {
            $this.siblings('.error-msg').remove();
          }
        })
        .on('focus', function () {
          $(this).siblings('.error-msg').remove();
        })
    });

  };
  validator.prototype.checkall = function () {
    var _this = this;
    if(_this.ischeckall) {
      _this.$el.find('[type=submit]')
        .click(function () {
          _this.$el.find('[name]').trigger('blur');
          if($('.error-msg').length > 0) {
            console.log('有错误信息');
            return false;
          }else {
            console.log('提交成功');
            _this.callback();
          }
        });
      return false;
    }
  };
  validator.prototype.init = function () {
    this.filterrules();
    this.check();
    this.checkall();
  };
  $.fn.validator = function (rules, ischeckall, callback) {
    var validate = new validator(this, rules, ischeckall, callback);
    return validate.init();
  };
})(window, jquery, undefined);

你可以这样使用:

  var rules = [
    {// 用户名
      username: 'required',
      rule: /^[\u4e00-\u9fa5\d]{6,12}$/,
      message: '只支持数字loo2222'
    },
    {// 密码
      password: 'required',
      rule: /^(?![0-9]+$)(?![a-za-z]+$)[0-9a-za-z_@]{6,20}$/,
      message: 'mimmimmia'
    },
    {// 重复密码
      password2: 'required',
      rule: /^(?![0-9]+$)(?![a-za-z]+$)[0-9a-za-z_@]{6,20}$/,
      message: '只支持数字字母下划线,不能为纯数字或字母2222',
      equalto: 'password'
    },
    {// 座机
      telephone : 'required',
      rule: /^[a-za-z0-9\u4e00-\u9fa5]+@[a-za-z0-9_-]+(.[a-za-z0-9_-]+)+$/,
      message: '请输入正确的座机'
    }
  ];
  $('form').validator(rules, true)

ps:这里再为大家提供2款非常方便的正则表达式工具供大家参考使用:

javascript正则表达式在线测试工具:

正则表达式在线生成工具: