validate.js源碼解讀

/**
 * 表單驗證
 * @param  {[type]} require [description]
 * @param  {[type]} exports [description]
 * @param  {[type]} module  [description]
 * @return {[type]}         [description]
 */
var validator = {
  required: {
    regex: /[^(^\s*)|(\s*$)]/,
    msg: "此項必填"
  },
  email: {
    regex: /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
    msg: "郵箱格式不正確。參考格式: wzp@upg.cn"
  },
  qq: {
    regex: /^\d+$/,
    msg: "qq號碼必須是1位以上的數(shù)字"
  },
  money: {
    regex: /^(([1-9]{1}\d*)|([0]{1}))(\.(\d){1,2})?$/,
    msg: "金額格式不符,僅允許輸入數(shù)字和小數(shù)點效拭,并最多輸入兩位小數(shù)卦洽,如1000.00"
  },
  url: {
    msg: "鏈接格式不正確。參考格式:http://www.ifsc.com.cn"
  },
  id: {
    msg: "此項必填"
  },
  lengthRange: {
    msg: "長度為 #0# 到 #1# 位"
  },
  fixedLength: {
    msg: "長度必須為#0#位"
  },
  payPwd: {
    msg: "支付密碼必須為#0#位數(shù)字!"
  },
  notMatch: {
    msg: "please enter a value differnt from '#0#'"
  },
  match: {
    msg: "請保證兩次輸入一致"
  },
  realname: {
    regex: /^[\u0391-\uFFE5A-Za-z0-9]+$/,
    msg: "中文,英文, 0-9"
  },
  receiptname: {
    regex: /^[\u0391-\uFFE5A-Za-z]+$/,
    msg: "中文,英文"
  },
  chinese: {
    regex: /^[\u4e00-\u9fa5]+$/,
    msg: "格式錯誤"
  },
  //安全問答的驗證
  safeAnswer: {
    regex: /^[\u0391-\uFFE5A-Za-z0-9\s]+$/,
    msg: "答案只允許中文罩润、英文、數(shù)字"
  },
  alphanumeric: {
    regex: /^[A-Za-z0-9_-]+$/,
    msg: "英文, 0-9, - and _"
  },
  idcard: {
    msg: "身份證號碼錯誤"
  },
  mobile: {
    // regex: /^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){10,12})+$/,
    regex: /^[1][3,4,5,7,8]\d{9}$/,
    msg: "手機(jī)號碼格式錯誤"
  },
  phone: {
    //regex: /^((\d{11,12})|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$)$/,
    regex: /^((\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})$)$/,
    msg: "座機(jī)號碼格式錯誤,格式 0571-88888888"
  },
  mobileOrPhone: {
    msg: "此項格式為手機(jī)或座機(jī)號碼"
  },
  // 驗證座機(jī)區(qū)號
  areaPart: {
    // 匹配區(qū)號0開頭的3位或4位數(shù)字
    regex: /^0\d{2}$|^0\d{3}$/,
    msg: "區(qū)號格式錯誤"
  },
  // 驗證座機(jī)號金度,不包括區(qū)號
  phonePart: {
    // 匹配電話號碼為7位或8位數(shù)字
    regex: /^((\d{7,8})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})$)$/,
    msg: "座機(jī)號碼格式錯誤"
  },
  year: {
    regex: /^[1,2][0,9]\d{2}$/,
    msg: "年格式填寫錯誤严沥!"
  },
  month: {
    regex: /^[0,1]\d{1}$|^\d{1}$/,
    msg: "月格式填寫錯誤!"
  },
  day: {
    regex: /^[0,1,2,3]\d{1}$|^\d{1}$/,
    msg: "日格式填寫錯誤消玄!"
  },
  number: {
    msg: "此項為數(shù)字格式"
  },
  notAllNum: {
    regex: /^\d+$/,
    msg: "不能全為數(shù)字"
  },
  uploadImg: {
    msg: "圖片類型錯誤"
  },
  uploadFile: {
    msg: "附件類型錯誤"
  },
  uploadFileImg: {
    msg: "附件類型錯誤"
  },
  uploadSound: {
    msg: "錄音類型錯誤"
  },
  maxValue: {
    msg: "請輸入數(shù)字小于  #0#"
  },
  minValue: {
    msg: "請輸入數(shù)字大于  #0#"
  },
  maxDecimal: {
    msg: "有效數(shù)字不多于 #0#"
  },
  integer: {
    regex: /^[1-9]\d*$/,
    msg: "請輸入正整數(shù)"
  },
  // 利率判斷 eg: 43 | 32. | 32.1 | 32.33
  rate: {
    regex: /^\d{1,2}(\.\d{1,2}?)?$/,
    msg: "請輸入有效數(shù)字"
  },
  // 最小金額
  minNumber: {
    regex: /^\d*(\.(\d{1,2})?)?$/,
    msg: "請輸入大于等于 #0# 數(shù)字"
  }
};
function cmdCallback(require, exports, module) {
  require('tipsy/tipsy');
  (function($) {
    var _formObj;
    var _isFocus = false;

    var showErr = function(obj, fieldName, msg) {
      try {
        obj.tipsy("hide");
      } catch (e) {}
      if (obj.is(':visible')) {
        obj.attr("valid-msg-text", msg);
      } else {
        obj.parent().attr("valid-msg-text", msg);
      }

      var options = obj.attr("valid-msg-options") == null ? {} : $.parseJSON(obj.attr("valid-msg-options"));
      $.extend(options, {
        show: true
      })
      var isFocus = false;
      if (_isFocus) {
        $.extend(options, {
          unFocus: true
        })
      }
      isFocus = createTipsyErr(obj.is(':visible') ? obj : obj.parent(), options);
      if (!_isFocus) {
        _isFocus = isFocus;
      }
    }

    var getElemetByNameOrId = function(targetObjIdOrName, visible) {
      var targetObj = $('[name="' + targetObjIdOrName + '"]', _formObj).length > 0 ? $('[name="' + targetObjIdOrName + '"]', _formObj) : $('#' + targetObjIdOrName);
      targetObj = targetObj.size() > 0 ? targetObj : $('[valid-name=' + targetObjIdOrName + ']'); //fix 360記住用戶輸入的問題
      if (visible) {
        targetObj = targetObj.filter(":visible");
      }
      return targetObj;
    }

    $.fn.valid = function(formObj, callback) {
      if (!$(this).attr("valid")) {
        return false;
      }

      _formObj = formObj || $("body");

      var obj = $(this);
      if(obj.parents('form').size() > 0){
        _formObj = obj.parents('form')[0];
      }
      var validTypes = obj.attr("valid").split('|')[0].split(',');
      var validMsges = obj.attr("valid").split('|')[1] ? obj.attr("valid").split('|')[1].split(',') : [];
      var fieldVal = ((obj.attr("type") || '').toLowerCase() == 'radio' ? $('[name=' + obj.attr('name') + ']:checked').val() : obj.val()) || ""; // fix by 000802: radio取值
      var fieldLength = fieldVal.length;
      var fieldName = obj.attr("name") || obj.attr('valid-name'); //fix 360記住用戶輸入的問題
      var isValid = true;

      $.each(validTypes, function(i, validType) {
        validType = $.trim(validType);
        var validValue;
        if (validType.indexOf("@") >= 0) {
          validValue = validType.split("@")[1];
          validType = validType.split("@")[0];
        }

        if (validType == 'ajax') {
          var data = {};
          var extendData = obj.attr('valid-extend-data') && obj.attr('valid-extend-data').split('|');
          data[fieldName] = fieldVal;
          if (extendData && extendData.length > 0) {
            for (var i = 0; i < extendData.length; i++) {

              // 有時候一個頁面多個 extendData
              // 這時過濾掉disabled
              var $input = _formObj.find('[name=' + extendData + ']');
              if($input.size() > 1) {
                $input = $input.filter(function() {
                  var state = $(this).attr('disabled');
                  if(!state){
                    return this;
                  }
                })
              }
              data[extendData[i]] = $input.val();
            }
          }
          $.ajax({
            type: 'post',
            url: validValue,
            data: data,
            dataType: 'json',
            cache: false,
            async: false,
            success: function(json) {
              if (json.boolen == "0") {
                showErr(obj, fieldName, json.message);
                isValid = false;
              }
              callback && callback(json);
            }
          });
        } else {
          var msg = validMsges[i] || validator[validType]['msg'];

          if (validType == 'lengthRange') {
            var rangeMin = validValue.split("~")[0];
            var rangeMax = validValue.split("~")[1];
            if (fieldLength < rangeMin || fieldLength > rangeMax) {
              msg = msg.replaceAll("#0#", rangeMin);
              msg = msg.replaceAll("#1#", rangeMax);
              showErr(obj, fieldName, msg);
              isValid = false;
              return false;
            }
          }else if(validType == 'fixedLength'){
            var len = validValue;

            if(len != $.trim(fieldVal).length){
              msg = msg.replaceAll("#0#", validValue);
              showErr(obj, fieldName, msg);
              isValid = false;
              return false;
            }
          }else if(validType == 'payPwd'){
            var len = validValue;

            if(len != $.trim(fieldVal).length || !(new RegExp('[0-9]{'+len+'}')).test($.trim(fieldVal))){
              msg = msg.replaceAll("#0#", validValue);
              showErr(obj, fieldName, msg);
              isValid = false;
              return false;
            }
          } else if (validType == 'number') {
            //          if (isNaN(fieldVal) || fieldVal<0 || fieldVal.indexOf("+")>=0) {
            if (isNaN(fieldVal) || fieldVal.indexOf("+") >= 0) {
              showErr(obj, fieldName, msg);
              isValid = false;
              return false;
            }
          } else if (validType == 'notAllNum') {
            if (fieldVal.length == 0) {
              isValid = true;
              return isValid;
            }
            var isNumber = validator['notAllNum']['regex'].test(fieldVal);
            if (isNumber) { // 全為數(shù)字,提示不能全為數(shù)字
              showErr(obj, fieldName, msg);
              isValid = false;
              return false;
            }
          } else if(validType == 'chinese'){
            var isChinese = validator['chinese']['regex'].test(fieldVal);
            if (!isChinese) { // 不是全為漢字
              showErr(obj, fieldName, msg);
              isValid = false;
              return false;
            }
          }else if (validType == 'notMatch') {
            if (fieldVal == getElemetByNameOrId(validValue).val()) {
              msg = msg.replaceAll("#0#", getElemetByNameOrId(validValue).val());
              showErr(obj, fieldName, msg);
              isValid = false;
              return false;
            }
          } else if (validType == 'minValue') {
            if (isNaN(validValue)) {
              validValue = getElemetByNameOrId(validValue).val();
            }
            if (validValue) {
              if (parseFloat(fieldVal) <= parseFloat(validValue)) {
                msg = msg.replaceAll("#0#", validValue);
                showErr(obj, fieldName, msg);
                isValid = false;
                return false;
              }
            }
          } else if (validType == 'maxValue') {
            if (isNaN(validValue)) {
              validValue = getElemetByNameOrId(validValue).val();
            }
            if (validValue) {
              if (parseFloat(fieldVal) > parseFloat(validValue)) {
                msg = msg.replaceAll("#0#", validValue);
                showErr(obj, fieldName, msg);
                isValid = false;
                return false;
              }
            }
          } else if (validType == 'maxDecimal') {
            var cleanNum = parseFloat(fieldVal).toFixed(validValue);
            if (fieldVal / cleanNum > 1) {
              msg = msg.replaceAll("#0#", validValue);
              showErr(obj, fieldName, msg);
              isValid = false;
              return false;
            }
          } else if (validType == 'match') {
            if (fieldVal != getElemetByNameOrId(validValue).val()) {
              msg = msg.replaceAll("#0#", getElemetByNameOrId(validValue).attr("name"));
              showErr(obj, fieldName, msg);
              isValid = false;
              return false;
            }
          } else if (validType == 'id') {
            fieldName = validValue ? validValue : fieldName;
            var fieldObj = getElemetByNameOrId(fieldName);
            fieldVal = fieldObj.is(":radio") || fieldObj.is(":checkbox") ? fieldObj.filter(":checked").val() : fieldObj.val();
            if (fieldVal === null || fieldVal === undefined || fieldVal === '' || fieldVal < 0) {
              showErr(obj, fieldName, msg);
              isValid = false;
              return false;
            }
          } else if (validType == 'idcard') {
            /* 140602198007196708 */
            if (fieldVal.length == 0) {
              isValid = true;
              return isValid;
            }
            isValid = false;
            if (fieldVal.length == 15) {
              isValid = isChineseIdentifyNo15(fieldVal);
            } else if (fieldVal.length == 18) {
              isValid = isChineseIdentifyNo18(fieldVal);
            }
            if (!isValid) {
              showErr(obj, fieldName, msg);
              return false;
            }
          } else if (validType == 'url') {
            if (fieldVal.length == 0) {
              isValid = true;
              return isValid;
            }
            isValid = false;
            if (fieldVal.indexOf('http://') !== -1 || fieldVal.indexOf('https://') !== -1) {
              isValid = true;
            }
            if (!isValid) {
              showErr(obj, fieldName, msg);
              return false;
            }
          } else if (validType == 'rate') {
            isValid = validator['rate']['regex'].test(fieldVal);
            if (!isValid) {
              showErr(obj, fieldName, msg);
              return false;
            }
          } else if (validType == 'uploadImg') {
            var fieldObj = obj || getElemetByNameOrId(fieldName);
            if (!fieldVal) {
              fieldName = validValue ? validValue : fieldName;
              fieldVal = fieldObj.is(":radio") || fieldObj.is(":checkbox") ? fieldObj.filter(":checked").val() : fieldObj.val();
            }
            if (fieldVal.length == 0) {
              return true;
            }
            var ext = fieldVal.split('.').pop().toLowerCase();
            var type = ['jpg', 'gif', 'png', 'jpeg', 'bmp'];
            if ($.inArray(ext, type) == -1) {
              // IE fixes: Cannot empty file value.
              fieldObj.replaceWith(fieldObj.val("").clone(true));
              fieldObj = getElemetByNameOrId(fieldName, true)
              fieldObj.removeData("tipsy");

              showErr(fieldObj, fieldName, msg);
              isValid = false;
            }
          } else if (validType == 'uploadFile') {
            var fieldObj = obj || getElemetByNameOrId(fieldName);
            if (!fieldVal) {
              fieldName = validValue ? validValue : fieldName;
              fieldVal = fieldObj.is(":radio") || fieldObj.is(":checkbox") ? fieldObj.filter(":checked").val() : fieldObj.val();
            }
            if (fieldVal.length == 0) {
              return true;
            }
            var ext = fieldVal.split('.').pop().toLowerCase();
            var type = ['zip', 'rar', 'doc', 'xls', 'ppt', 'docx', 'xlsx', 'pptx', 'pdf', 'htm', 'html', 'wps', 'et', 'dps', 'txt'];
            if ($.inArray(ext, type) == -1) {
              // IE fixes: Cannot empty file value.
              fieldObj.replaceWith(fieldObj.val("").clone(true));
              fieldObj = getElemetByNameOrId(fieldName, true)
              fieldObj.removeData("tipsy");

              showErr(fieldObj, fieldName, msg);
              isValid = false;
            }
          } else if (validType == 'uploadFileImg') {
            var fieldObj = obj || getElemetByNameOrId(fieldName);
            if (!fieldVal) {
              fieldName = validValue ? validValue : fieldName;
              fieldVal = fieldObj.is(":radio") || fieldObj.is(":checkbox") ? fieldObj.filter(":checked").val() : fieldObj.val();
            }
            if (fieldVal.length == 0) {
              return true;
            }
            var ext = fieldVal.split('.').pop().toLowerCase();
            var type = ['zip', 'rar', 'doc', 'xls', 'ppt', 'docx', 'xlsx', 'pptx', 'pdf', 'htm', 'html', 'wps', 'et', 'dps', 'jpg', 'gif', 'png', 'jpeg', 'bmp', 'txt'];
            if ($.inArray(ext, type) == -1) {
              // IE fixes: Cannot empty file value.
              fieldObj.replaceWith(fieldObj.val("").clone(true));
              fieldObj = getElemetByNameOrId(fieldName, true)
              fieldObj.removeData("tipsy");

              showErr(fieldObj, fieldName, msg);
              isValid = false;
            }
          } else if (validType == 'uploadSound') {
            var fieldObj = obj || getElemetByNameOrId(fieldName);
            if (!fieldVal) {
              fieldName = validValue ? validValue : fieldName;
              fieldVal = fieldObj.is(":radio") || fieldObj.is(":checkbox") ? fieldObj.filter(":checked").val() : fieldObj.val();
            }
            if (fieldVal.length == 0) {
              return true;
            }
            var ext = fieldVal.split('.').pop().toLowerCase();
            var type = ['mp3', 'wma', 'flac', 'aac', 'mmf', 'amr', 'm4a', 'm4r', 'ogg', 'mp2', 'wav', 'wv'];
            if ($.inArray(ext, type) == -1) {
              // IE fixes: Cannot empty file value.
              fieldObj.replaceWith(fieldObj.val("").clone(true));
              fieldObj = getElemetByNameOrId(fieldName, true)
              fieldObj.removeData("tipsy");

              showErr(fieldObj, fieldName, msg);
              isValid = false;
            }
          } else if (validType == 'mobileOrPhone') {
            if (fieldVal.length == 0) {
              isValid = true;
              return isValid;
            }
            var isPhone = validator['phone']['regex'].test(fieldVal);
            var isMobile = validator['mobile']['regex'].test(fieldVal);
            if (!isPhone && !isMobile) {
              showErr(obj, fieldName, msg);
              isValid = false;
              return false;
            }
          } else if (validType == 'year') {
            if (fieldVal.length == 0) {
              isValid = true;
              return isValid;
            }
            var isYear = validator['year']['regex'].test(fieldVal);
            if (!isYear) {
              showErr(obj, fieldName, msg);
              isValid = false;
              return false;
            }
          } else if (validType == 'month') {
            if (fieldVal.length == 0) {
              isValid = true;
              return isValid;
            }
            var isMonth = validator['month']['regex'].test(fieldVal);
            if (!isMonth) {
              showErr(obj, fieldName, msg);
              isValid = false;
              return false;
            }
          } else if (validType == 'day') {
            if (fieldVal.length == 0) {
              isValid = true;
              return isValid;
            }
            var isDay = validator['day']['regex'].test(fieldVal);
            if (!isDay) {
              showErr(obj, fieldName, msg);
              isValid = false;
              return false;
            }
          } else if (validType == 'areaPart') {
            if (fieldVal.length == 0) {
              isValid = true;
              return isValid;
            }
            var isAreaNumber = validator['areaPart']['regex'].test(fieldVal);
            if (!isAreaNumber) {
              showErr(obj, fieldName, msg);
              isValid = false;
              return false;
            }
          } else if (validType == 'phonePart') {
            if (fieldVal.length == 0) {
              isValid = true;
              return isValid;
            }
            var isPhoneNumber = validator['phonePart']['regex'].test(fieldVal);
            if (!isPhoneNumber) {
              showErr(obj, fieldName, msg);
              isValid = false;
              return false;
            }
          } else if (validType == 'minNumber') {
            var msg = msg.replace('#0#', validValue),
              rg = validator[validType].regex,
              state = rg.test(fieldVal);

            // 匹配失敗則說明含非法字符
            if(!state || parseFloat(fieldVal) < parseFloat(validValue)) {
              if(!state) {
                msg = '您輸入的數(shù)字有誤';
              }
              showErr(obj, fieldName, msg);
              isValid = false;
              return false;
            };
          } else {
            if (validType != 'required' && fieldVal.length == 0) {
              isValid = true;
              return true;
            }
            if (!obj.is(":disabled")) {
              if (!validator[validType]['regex'].test(fieldVal)) {
                showErr(obj, fieldName, msg);
                isValid = false;
                return false;
              }
            }
            // special validate for realname (Punctuation)
            if (validType == 'realname') {
              var punctuations = ['~', '翩瓜!', '@', '#', '$', '%', '︿', '&', '*', '(', ')', '_', '+', '‵', '-', '=', '[', ']', '\', '{', '}', '|', '受扳;', '’', ':', '"', ',', '奥溺。', '/', '<', '>', '辞色?'];
              for (i in punctuations) {
                if (fieldVal.indexOf(punctuations[i]) >= 0) {
                  showErr(obj, fieldName, msg);
                  isValid = false;
                  return false;
                }
              }
            }
          }
        }
      });

      if (isValid) {
        try {
          obj.tipsy("hide");
        } catch (e) {}
      }

      return isValid;
    }
  })(jQuery);

  function createTipsyErr(obj, options) {
    var show = options && options.show ? true : false;
    var unFocus = options && options.unFocus ? true : false;
    var gravity = options && options.gravity ? options.gravity : "w";
    var html = options && options.html ? options.html : true;
    var offset = options && options.offset ? options.offset : 0;
    var fieldId = obj.attr("name") == null ? obj.attr("valid-msg") : obj.attr("name");
    var msgHolderId = options && options.msgHolderId ? options.msgHolderId : false;
    var width = options.width;
    var formId = "";
    if (obj.parents("form").length) {
      var $form = obj.parents("form");
      formId = $form.attr("name") || $form.attr("id");

      if (!formId) {
        var randomNum = Math.ceil(Math.random() * 10000);
        formId = "randomId-" + randomNum;
      }
    }
    fieldId = fieldId == null ? obj.attr("id") : fieldId;

    if (msgHolderId) {
      var _validMsgText = obj.attr("valid-msg-text");
      obj = $("#" + msgHolderId);
      obj.attr("valid-msg-text", _validMsgText);
    }
    obj.tipsy({
      title: "valid-msg-text",
      trigger: "manual",
      gravity: gravity,
      fade: true,
      color: "red",
      opacity: 1,
      html: html,
      offset: offset,
      id: fieldId,
      formId: formId,
      width: width
    });
    var isFocus = false;

    if (!unFocus) {
      isFocus = focusErr(obj);
    }
    if (show) {
      setTimeout(function() {
        obj.tipsy("show");
        if (obj.is("input")) {
          obj.addClass("textMess_bd");
        }
      }, 10);
    }

    return isFocus;
  }

  function removeErrorMsg(tipsyid) {
    try {
      if (tipsyid) {
        if (typeof tipsyid === "object") {
          if (typeof tipsyid.tipsy == 'function') {
            var t = tipsyid.tipsy("tip");
            t.hide();
          }
        } else {
          $("[tipsyid='" + tipsyid + "']").remove();
        }
      } else {
        $("[tipsy].tipsy-red").remove();
      }
    } catch (e) {}
  }

  function focusErr(obj) {
    var isFocus = false;
    try {
      var $colorbox = $("#colorbox:visible");
      if (!$colorbox.length) {
        //$(window).scrollTop(0);
      }
      setTimeout(function() {
        var _tabindex = obj.attr("tabindex");
        if (!obj.is(":input")) {
          obj.attr("tabindex", "-1");
          if (!obj.is(":visible")) {
            obj.append("&nbsp;");
          }
          obj.focus();
          if (_tabindex) {
            obj.attr("tabindex", _tabindex);
          } else {
            obj.removeAttr("tabindex");
          }
        } else {
          obj.focus();
        }
      }, 1);
      isFocus = true;
    } catch (e) {}
    return isFocus;
  }

  function isValidError(formObj) {
    var result = false;
    var $obj = $("[tipsy]");
    if (formObj) {
      var formId = formObj.attr("name") || formObj.attr("id");
      $obj = $("[tipsy][tipsyformId=" + formId + "]");
    }
    $obj.each(function() {
      if ($(this).is(":visible")) {
        result = true;
      }
    });
    return result;
  }

  /**
   * boolean String.isChineseIdentifyNo15()
   * 驗證中國居民15位身份證號碼是否合法
   * 返回:合法返回true,不合法返回false
   */
  function isChineseIdentifyNo15(str) {
    var _id = str;
    for (var i = 0; i < _id.length; i++) {
      //校驗每一位的合法性
      if (_id.charAt(i) < '0' || _id.charAt(i) > '9') {
        return false;
        break;
      }
    }
    var year = _id.substr(6, 2);
    var month = _id.substr(8, 2);
    var day = _id.substr(10, 2);
    //校驗?zāi)攴菸?    if (year < '01' || year > '90') return false;
    //校驗月份
    if (month < '01' || month > '12') return false;
    //校驗日
    if (day < '01' || day > '31') return false;
    return true;
  };

  /**
   * boolean String.isChineseIdentifyNo18()
   * 驗證中國居民18位身份證號碼是否合法
   * 返回:合法返回true,不合法返回false
   */
  function isChineseIdentifyNo18(str) {
    var powers = new Array("7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2");
    var parityBit = new Array("1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2");

    var _id = str;
    var _num = _id.substr(0, 17);
    var _parityBit = _id.substr(17);
    var _power = 0;
    for (var i = 0; i < 17; i++) {
      //校驗每一位的合法性
      if (_num.charAt(i) < '0' || _num.charAt(i) > '9') {
        return false;
        break;
      } else {
        //加權(quán)
        _power += parseInt(_num.charAt(i)) * parseInt(powers[i]);
      }
    }
    //取模
    var mod = parseInt(_power) % 11;
    if (_parityBit == "X") _parityBit = _parityBit.toLocaleUpperCase();
    if (parityBit[mod] == _parityBit) {
      return true;
    }
    return false;
  };

  /**
   * 驗證form
   * @param  {[type]} $form  [description]
   * @param  {[type]} _$form [description]
   * @return {[type]}        [description]
   */
  var validForm = function($form, _$form) {
    _$form = _$form || $form;
    var result = true;
    var isFocus = false;
    $("[valid]", $form).each(function() {
      var $this = $(this);
      if($this.attr('disabled')) return;

      if ($this.is(":visible")) {
        result = $this.valid(_$form) && result;
        if (!result && !isFocus) {
          isFocus = focusErr($this);
        }
      } else {
        if ($this.attr('valid-hide') != undefined) {
          result = $this.valid(_$form) && result;
          if (!result && !isFocus) {
            isFocus = focusErr($this);
          }
        }
      }
    });
    return result;
  }

  /**
   * 動態(tài)修正錢的數(shù)目,支持輸入框與一般標(biāo)簽
   * 去掉字母和多余的位數(shù)保留小數(shù)點后兩位
   * isChange判斷內(nèi)容是否改過不包括不符合要求的輸入
   * callback不存在的話則自動更新val值
   * 否則由callback來完成
   * obj = {
   *  elem: $elem,
   *  callback: null,
   *  decimalLen: null,
   *  decimalLen: 2
   * }
   */
  function amendAmount(opts) {
    var defaults = {
        elem: null, // input 元素
        callback: null, // 回調(diào)
        intLen: null, // 保留整數(shù)位數(shù)
        decimalLen: 2 // 保留小數(shù)位
      },
      sets = $.extend({}, defaults, opts),
      $elem = $(sets.elem),
      isInput = $elem.is(':input'),

    // original保存原有值
    // 最后通過與val判斷得出有沒有被處理
      original = val = isInput ? $elem.val() : $elem.text(),
      oldVal = $elem.data('val'),

    // 這個變量主要是用來防止多次無意義的ajax請求
      isChange = false,
      intLen = sets.intLen,
      decimalLen = sets.decimalLen;

    if(!$elem.length) return;

    if(val) {
      // 替換掉非數(shù)字與"."的值以及后面的值
      // 去掉開頭的0的數(shù)字
      // 去掉第二個"."級后面的值
      val = val.replace(/[^\d\.].*/, '').replace(/^0(\d+)/, '$1').replace(/(\.[^.]*)\..*/, '$1');

      // 保留小數(shù)位數(shù)
      if(decimalLen !== null) {
        val = val.replace(new RegExp('(\\.\\d{' + decimalLen + '}).*'), '$1');
      };

      // 處理整數(shù)
      if(intLen !== null) {
        val = val.replace(new RegExp('^(\\d{' + intLen + '})\\d.*'), '$1');
      };
    };

    // 給個默認(rèn)值
    val = val || 0;

    if(val !== oldVal) {
      isChange = true;
      $elem.data('val', val);
    };

    // 如果有回調(diào)就回調(diào)
    if (sets.callback) {
      sets.callback.call($elem, val, isChange);

      // 沒回調(diào)的話自動修改元素
    } else {

      // 這時說明原有值被處理過,要把處理過的值重新填充
      // 這時會默認(rèn)光標(biāo)放在最后浮定,如果是正確輸入則會影響用戶體驗
      if(original !== val) {
        isInput ? $elem.val(val) : $elem.text(val);
      };
    }
  }

  exports.createTipsyErr = createTipsyErr;
  exports.removeErrorMsg = removeErrorMsg;
  exports.focusErr = focusErr;
  exports.isValidError = isValidError;
  exports.isChineseIdentifyNo15 = isChineseIdentifyNo15;
  exports.isChineseIdentifyNo18 = isChineseIdentifyNo18;
  exports.validForm = validForm;
  exports.amendAmount = amendAmount;
  exports.showErr = function(obj, msg, focus) {
    if (typeof focus != 'undefined') {
      focus = !focus;
    } else {
      focus = false;
    }
    obj.attr("valid-msg-text", msg);
    var options = obj.attr("valid-msg-options") == null ? {} : $.parseJSON(obj.attr("valid-msg-options"));
    $.extend(options, {
      show: true,
      unFocus: focus
    });
    createTipsyErr(obj, options);
  };
}

//cmd
if ( typeof define == 'function' && define.cmd ) {
  define(function(require, exports, module) {
    cmdCallback(require, exports, module)
  })
} else if ( typeof define == 'function' && define.amd ) {//amd  暫時不處理
} else { //no module
  window.Regex = validator;
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末相满,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子桦卒,更是在濱河造成了極大的恐慌立美,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件方灾,死亡現(xiàn)場離奇詭異建蹄,居然都是意外死亡碌更,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進(jìn)店門洞慎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來痛单,“玉大人,你說我怎么就攤上這事劲腿⌒袢蓿” “怎么了挥吵?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵忽匈,是天一觀的道長矿辽。 經(jīng)常有香客問我嗦锐,道長,這世上最難降的妖魔是什么萎羔? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任贾陷,我火速辦了婚禮髓废,結(jié)果婚禮上该抒,老公的妹妹穿的比我還像新娘。我一直安慰自己冈爹,他們只是感情好频伤,可當(dāng)我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布憋肖。 她就那樣靜靜地躺著,像睡著了一般岸更。 火紅的嫁衣襯著肌膚如雪怎炊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天,我揣著相機(jī)與錄音糟港,去河邊找鬼秸抚。 笑死歹垫,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的吭敢。 我是一名探鬼主播鹿驼,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼畜晰,長吁一口氣:“原來是場噩夢啊……” “哼瑞筐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起块蚌,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤匈子,失蹤者是張志新(化名)和其女友劉穎虎敦,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體其徙,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡访锻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年期犬,在試婚紗的時候發(fā)現(xiàn)自己被綠了避诽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡鲤妥,死狀恐怖棉安,靈堂內(nèi)的尸體忽然破棺而出贡耽,到底是詐尸還是另有隱情羡滑,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布凳宙,位于F島的核電站氏涩,受9級特大地震影響有梆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜饺汹,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一兜辞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧凶硅,春花似錦扫皱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至粥航,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間柄延,已是汗流浹背缀程。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工杨凑, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蜒程。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓昭躺,卻偏偏與公主長得像伪嫁,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子帝洪,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,947評論 2 355

推薦閱讀更多精彩內(nèi)容