简易版表单验证

249 阅读1分钟

有个很小的表单验证不想使用第三方插件了,就自己动手实现了一个简易版的表单验证,目前支持输入框,默认所有项都是必填,可以增加自定义校验规则。以后有空了再慢慢完善。样式简陋就不贴样式啦。。。

正则验证html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="./css/reset.css">
  <link rel="stylesheet" href="./css/common.css">
  <script src="./js/formCheck.js"></script>
  <script src="./js/utils.js"></script>
  <script src="./js/message.js"></script>
  <style>
    .content {
      padding: 50px 0 0;
    }

    .footer {
      padding: 15px 15% 20px;
    }

    .btn {
      margin-left: 70px;
    }
  </style>
  <title>测试</title>
</head>

<body>
  <h3 class="header-box">标题</h3>
  <div class="content">
    <ul class="form-box" id="formBox">
      <li class="form-item" prop="ip">
        <span class="label">IP:</span>
        <div class="form-item_content">
          <input type="text" autocomplete="off" placeholder="请输入需要连接的IP地址">
          <p class="hint-text"></p>
        </div>
      </li>
      <li class="form-item" prop="port">
        <span class="label">端口:</span>
        <div class="form-item_content">
          <input type="text" autocomplete="off" placeholder="请输入需要连接的端口">
          <p class="hint-text"></p>
        </div>
      </li>
    </ul>
  </div>
  <div class="footer">
    <button class="btn" onclick="clickBtn()">确定</button>
  </div>
  <script>
    var ipReg = /^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$/;
    var portReg = /^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/;
    var rules = {
      ip: [{
        reg: ipReg,
        message: '请输入正确的ip'
      }],
      port: [{
        reg: portReg,
        message: '请输入正确的端口号'
      }]
    };
    var fc = new FormCheck({
      rules: rules,
      formId: 'formBox'
    });

    function clickBtn() { // 点击按钮
      fc.checkFrom().then(_ => {
        console.log("pass")
        // Message({
        //   msg: '登录成功',
        //   type: 'success'
        // });
      }).catch(_ => {
        console.log("no")
      });
    }
  </script>
</body>

</html>

自定义校验规则html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="./css/reset.css">
  <link rel="stylesheet" href="./css/common.css">
  <script src="./js/formCheck.js"></script>
  <script src="./js/utils.js"></script>
  <script src="./js/message.js"></script>
  <style>
    .content {
      padding: 50px 0 0;
    }

    .footer {
      padding: 15px 15% 20px;
    }

    .btn {
      margin-left: 100px;
    }

    .label {
      width: 100px;
    }
  </style>
  <title>修改PIN码</title>
</head>

<body>
  <h3 class="header-box">修改PIN码</h3>
  <div class="content" id="formBox">
    <ul class="form-box">
      <li class="form-item" prop="oldPin">
        <span class="label">旧PIN码:</span>
        <div class="form-item_content">
          <input type="text" autocomplete="off" id="oldPin" placeholder="请输入旧PIN码">
          <p class="hint-text"></p>
        </div>
      </li>
      <li class="form-item" prop="newPin">
        <span class="label">新PIN码:</span>
        <div class="form-item_content">
          <input type="text" autocomplete="off" id="newPin" placeholder="请输入新PIN码">
          <p class="hint-text"></p>
        </div>
      </li>
      <li class="form-item" prop="newPin2">
        <span class="label">确认PIN码:</span>
        <div class="form-item_content">
          <input type="text" autocomplete="off" id="newPin2" placeholder="请输入确认PIN码">
          <p class="hint-text"></p>
        </div>
      </li>
    </ul>
  </div>
  <div class="footer">
    <button class="btn">取消</button>
    <button class="btn" onclick="clickBtn()" style="margin-left: 10px;">确定</button>
  </div>
  <script>
    var oldPin = document.getElementById('oldPin');
    var newPin = document.getElementById('newPin');
    var newPin2 = document.getElementById('newPin2');
    var rules = {
      newPin: [{
        custom: function (val, callback) {
          if (newPin.value && newPin2.value && newPin2.value !== newPin.value) {
            return callback('两次输入的PIN码不一样');
          }
          callback();
        }
      }],
      newPin2: [{
        custom: function (val, callback) {
          if (newPin.value && newPin2.value && newPin2.value !== newPin.value) {
            return callback('两次输入的PIN码不一样');
          }
          callback();
        }
      }],
    };
    var fc = new FormCheck({
      rules: rules,
      formId: 'formBox'
    });

    function clickBtn() { // 点击按钮
      fc.checkFrom().then(_ => {
        console.log("pass")
        // Message({
        //   msg: '登录成功',
        //   type: 'success'
        // });
      }).catch(_ => {
        console.log("no")
      });
    }
  </script>
</body>

</html>

核心代码formCheck.js

;
(function (global) {
  var deOpt = {
    rules:{},
    formId: null
  };
  function FormCheck(opt) {
    if(!opt || !opt.rules || !opt.formId){
      console.error('请设置正确的参数');
      return;
    };
    var formBox = document.getElementById(opt.formId);
    if(!formBox){
      console.error('formId不存在');
      return;
    }
    this.rules = opt.rules || deOpt.rules;
    this.inps = formBox.getElementsByTagName('input');
    this.customResult = {}; // 自义验证的结果
    for(var key in this.rules){
      this.customResult[key] = true;
    }
    this.setCheck();
  }
  FormCheck.prototype.setCheck = function () { // 给表单添加验证规则
    var _this = this;
    for (var i = 0, item; item = this.inps[i++];) {
      (function () {
        var prop = item.parentNode.parentNode.getAttribute('prop');
        item.onchange = _this.checkInp(item, _this.rules[prop],prop);
        item.oninput = _this.checkInp(item, _this.rules[prop],prop);
      }());
    }
  }

  FormCheck.prototype.checkInp = function (target, relusArr,prop) { // 输入验证
    var _this = this;
    return function () {
      var val = target.value;
      var placeholder = target.getAttribute('placeholder');
      var hintEl = target.parentNode.querySelector('.hint-text');
      if(!val.replace(/\s+/g,'')){  // 如果为空直接提示
        hintEl.innerHTML = placeholder || '请输入';
        hintEl.style.display = 'block';
        return false;
      }

      if(!relusArr || relusArr.length == 0) {  // 如果不存在验证规则 直接返回true
        hintEl.style.display = 'none';
        return true;
      }
      for (var i = 0, item; item = relusArr[i++];) {
        if (item.reg) { // 正则验证
          if(item.reg.test(val)){
            hintEl.style.display = 'none';
          }else {
            hintEl.innerHTML = item.message;
            hintEl.style.display = 'block';
            return false;
          }
        } else if(item.custom && item.custom instanceof Function) { // 如果存在自定义规则
          item.custom(val,customCallBack);
          function customCallBack(msg){
            if(msg){
              hintEl.innerHTML = msg;
              hintEl.style.display = 'block';
              _this.customResult[prop] = false;
            }else {
              _this.customResult[prop] = true;
              hintEl.style.display = 'none';
            }
          }
        }
      }
      return true;
    }
  }

  FormCheck.prototype.checkFrom = function () { // 表单验证
    var result = []; // 普通验证规则结果
    for (var i = 0, item; item = this.inps[i++];) {
      var isPass = item.onchange();
      result.push(isPass);
    }
    return new Promise((resolve, reject) => {
      if (result.indexOf(false) === -1 && this.checkCustom()) { // 如果通过
        resolve();
      } else { // 不通过
        reject();
      }
    })
  }

  FormCheck.prototype.checkCustom = function(){ // 验证用户自定义的规则  
    for(var key in this.customResult){
      if(!this.customResult[key]){
        return false;
      }
    }
    return true;
  } 
  global.FormCheck = FormCheck;
}(window));