lm-form
Version:
* 作者:liuduan * 邮箱:liuduan.05.05@163.com * 版本:**`1.0.2`**
153 lines (134 loc) • 5.14 kB
JavaScript
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Hint from './hint';
import emitter from './events';
import './index.scss';
// 识别每个input实例的唯一id。
let id = 0;
const InputValidateHoc = Input => {
return class InputValidate extends Component {
static propTypes = {
hintClassName: PropTypes.string, // hint自定义类名
value: PropTypes.oneOfType([ // 值,配合onChange使用
PropTypes.string,
PropTypes.number
]),
validate: PropTypes.object, // 验证参数配置
required: PropTypes.bool, // 是否必填
onChange: PropTypes.func, // onchange事件回调
onFocus: PropTypes.func, // onfocus事件回调
onBlur: PropTypes.func, // onblur事件回调
};
static defaultProps = {
validate: {},
required: false,
onChange() { },
onFocus() { },
onBlur() { },
};
constructor(props) {
super(props);
this.state = {
hintShow: false,
err: false,
message: ''
};
this.validateChange = this.validateChange.bind(this);
this.validateFocus = this.validateFocus.bind(this);
this.validateBlur = this.validateBlur.bind(this);
this.handleErrState = this.handleErrState.bind(this);
}
id = id++;
_timeout;
componentDidMount() {
this.props.validate.type === "submitValidate" && emitter.on('inputErrEvent', this.handleErrState);
}
componentWillUnmount() {
this.props.validate.type === "submitValidate" && emitter.removeListener('inputErrEvent', this.handleErrState)
clearTimeout(this._timeout);
}
handleErrState(param) {
if (param.id === this.id) {
this.setState({
err: true
});
}
}
validateChange(value) {
// 触发回调
this.props.onChange(value);
// 恢复状态时机
if (this.state.err) {
// input验证
const { isValid } = this.validateValue(value);
if (isValid) {
this.setState({
err: !isValid
});
}
}
}
validateFocus(value) {
// 当校验不同过,显示错误信息
if (this.state.err && this.props.validate.type !== "submitValidate") {
this.showHint();
}
// 触发回调
this.props.onFocus(value);
}
validateBlur(value) {
const { type } = this.props.validate;
// 如果有hint,blur时去掉
if (this.state.hintShow && type !== "submitValidate") {
this.destroyHint();
}
// 失去焦点开始验证
const { isValid, message } = this.validateValue(value);
// 验证不通过
if (!isValid && type !== "submitValidate") {
// 文字爆红
this.setState({
err: true,
message
});
}
// 将验证信息发送出去--->Form接收
emitter.emit('validateEvent', { id: this.id }, { isValid, message, name: this.props.name, value, type });
// 触发回调
this.props.onBlur(value, { isValid, message });
}
// 验证值
validateValue(value) {
const { validate, required } = this.props;
return this.props.inputValidate({ value, ...validate, required });
}
// 显示错误信息
showHint() {
this.setState({
hintShow: true
}, () => {
this._timeout = setTimeout(() => {
this.destroyHint();
}, 3000);
});
}
// 销毁错误信息
destroyHint() {
if (this._timeout) this._timeout = clearTimeout(this._timeout);
this.setState({
hintShow: false
});
}
render() {
const { hintClassName, inputValidate, onChange, onFocus, onBlur, validate, required, err, onlySubmitValidate, ...others } = this.props;
const { hintShow, message } = this.state;
return <div className="lm-validate">
<Input err={this.state.err} onChange={this.validateChange} onFocus={this.validateFocus} onBlur={this.validateBlur} {...others}>
{hintShow ? <i className={`lm-validate-arrow`}></i> : null}
</Input>
<Hint className={hintClassName} show={hintShow} message={message} requireMsg={validate.requireMsg} />
</div>
}
}
}
export default InputValidateHoc;