lm-form
Version:
* 作者:liuduan * 邮箱:liuduan.05.05@163.com * 版本:**`1.0.2`**
134 lines (116 loc) • 5.71 kB
JavaScript
import React, { Component } from 'react';
import Validaterule from './validate.rule';
const ValidateHoc = (Form, rules) => {
const validRules = rules ? Object.assign({}, Validaterule, rules) : Validaterule;
return class ValidateHoc extends Component {
constructor(props) {
super(props);
this.formValidate = this.formValidate.bind(this);
this.inputValidate = this.inputValidate.bind(this);
this.timer = null;
}
componentWillUnmount() {
clearTimeout(this.timer);
}
// 表单提交校验方法
formValidate(validData = []) {
return new Promise((resolve, reject) => {
let flag = true, query = {}, msg;
let i = 0, len = validData.length;
for (i; i < len; i++) {
const item = validData[i];
const { ref, name, value, rule, param, required, err, requireMsg, errMsg } = item;
// 判断是否需要验证
if (required || rule) {
const { isValid, message } = this.inputValidate({ value, rule, param, required, err, errMsg, requireMsg});
if (!isValid) {
this.validateRef.setState({
[err]: true
});
// 自动选中错误项焦点,异步执行,防止先与onBlur事件执行
clearTimeout(this.timer);
this.timer = setTimeout(() => {
if (ref && ref.inputRef) ref.inputRef.focus();
}, 0);
msg = message === 'required' && requireMsg ? requireMsg : message;
flag = false;
reject(msg);
break;
}
// 验证通过将其添加到query中
if (name) query[name] = typeof value === "string" ? value.trim() : value;
}
}
// 校验成功 提交表单
if (flag) {
resolve(query);
}
});
}
// errMsg 、 rule 统一为数组类型
stirngToArr(value) {
if ((typeof value === 'string' && value) || (Object.prototype.toString.call(value) === '[object Array]' && value.length) || (typeof value === 'function')) {
return [].concat(value);
} else {
return [];
}
}
// input校验方法
inputValidate({ value, rule, param = [], required, err, errMsg }) {
let isValid = true, message = '', rules = [], errMsgs = [];
// 支持 多种 规则校验
rules = this.stirngToArr(rule);
errMsgs = this.stirngToArr(errMsg);
let noEmpty = (Object.prototype.toString.call(value) === '[object Array]' && value.length) || (typeof value === 'string' && value !== '') || typeof value === 'number' || (typeof value === 'boolean' && value);
// 先判断是否必填
if (!noEmpty && required) {
isValid = false;
message = 'required';
// 判断是否符合检验规则
} else if (noEmpty && rules.length) {
let i = 0, len = rules.length;
for (i; i < len ; i++) {
// 现在已有的规则函数中查找,找不到,判断rule是不是函数
let validateFun = validRules[rules[i]] || rules[i];
if (validateFun && typeof validateFun === 'function') {
const validateObj = validateFun(value, param);
if (Object.prototype.toString.call(validateObj) === '[object Object]') {
isValid = !!validateObj.validator;
message = errMsgs[i] || validateObj.message || '输入不符合规则';
} else {
isValid = !!validateObj;
message = errMsgs[i] || '输入不符合规则';
}
// 如果验证通过但仍爆红,自动处理
if (err && isValid && this.validateRef.state[err]) this.validateRef.setState({
[err]: false
});
// 如果验证没有通过直接返回
if (!isValid) break;
}
}
} else if (noEmpty && (rule instanceof RegExp)) {
// 支持正值表达式直接校验
isValid = rule.test(value);
message = errMsgs[0] || '输入不符合规则';
// 如果验证通过但仍爆红,自动处理
if (err && isValid && this.validateRef.state[err]) this.validateRef.setState({
[err]: false
});
}
return { isValid, message };
}
render() {
let others = {
inputValidate: this.inputValidate
};
if (Form.name !== 'InputValidate') {
Object.assign(others, {
formValidate: this.formValidate
})
}
return <Form {...this.props} {...others} ref={el => this.validateRef = el} />
}
};
};
export default ValidateHoc;