chowa
Version:
UI component library based on React
178 lines (177 loc) • 6.6 kB
JavaScript
/**
* @license chowa v1.1.3
*
* Copyright (c) Chowa Techonlogies Co.,Ltd.(http://www.chowa.cn).
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const React = require("react");
const PropTypes = require("prop-types");
const classnames_1 = require("classnames");
const utils_1 = require("../utils");
const transition_1 = require("../transition");
const IO_VALUE = 'IO_VALUE';
const IO_BOOLEAN = 'IO_BOOLEAN';
class FormValidator extends React.PureComponent {
constructor(props) {
super(props);
this.computedIoType(props.children);
const value = this.computedIoInitValue(props.children);
this.state = {
value,
initValue: value,
error: false,
message: ''
};
[
'onChangeHandler',
'verifyFiled',
'resetFiled',
'resetValidator'
].forEach((fn) => {
this[fn] = this[fn].bind(this);
});
}
computedIoType(children) {
const { propTypes: childPropTypes } = children.type;
this.ioType = utils_1.isExist(childPropTypes.checked) ? IO_BOOLEAN : IO_VALUE;
}
computedIoInitValue(children) {
if (this.ioType === IO_BOOLEAN) {
return Boolean(children.props.checked);
}
return children.props.value || children.props.defaultValue;
}
componentDidUpdate(preProps) {
if (preProps.children.type !== this.props.children.type) {
this.computedIoType(this.props.children);
const value = this.computedIoInitValue(this.props.children);
this.setState({
value,
initValue: value
});
}
if ((!utils_1.isEqual(preProps.children.props.checked, this.props.children.props.checked)
&& !utils_1.isEqual(this.props.children.props.checked, this.state.value))
|| (!utils_1.isEqual(preProps.children.props.value, this.props.children.props.value)
&& !utils_1.isEqual(this.props.children.props.value, this.state.value))) {
this.setState({
value: this.ioType === IO_VALUE
? this.props.children.props.value
: this.props.children.props.checked
}, () => {
this.verifyFiled();
});
}
}
onChangeHandler(e) {
const { children } = this.props;
let value = e;
if (typeof e === 'object'
&& e.nativeEvent instanceof Event
&& (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement)) {
value = (e.target.type === 'checkbox' || e.target.type === 'radio')
? e.target.checked
: e.target.value;
}
this.setState({
value
}, () => {
this.verifyFiled();
});
if (children.props.onChange) {
children.props.onChange(e);
}
}
componentDidMount() {
const { name, appendField } = this.props;
const { value, error } = this.state;
appendField(name, {
value,
error,
verifyFiled: this.verifyFiled,
resetFiled: this.resetFiled,
resetValidator: this.resetValidator
});
}
componentWillUnmount() {
const { name, removeField } = this.props;
removeField(name);
}
verifyFiled() {
const { value } = this.state;
const { rules, name } = this.props;
let verifyMsg = '';
let hasError = false;
const hasResult = utils_1.isExist(value);
if (utils_1.isExist(rules)) {
hasError = !rules.every(({ required, length, min, max, regex, validation, message }) => {
if (required && !hasResult) {
verifyMsg = message;
return false;
}
else if (length && hasResult && value.length !== length) {
verifyMsg = message;
return false;
}
else if (min && hasResult && value.length < min) {
verifyMsg = message;
return false;
}
else if (max && hasResult && value.length > max) {
verifyMsg = message;
return false;
}
else if (regex && hasResult && !regex.test(value)) {
verifyMsg = message;
return false;
}
else if (validation && hasResult && !validation(value)) {
verifyMsg = message;
return false;
}
return true;
});
}
this.setState({
error: hasError,
message: verifyMsg
});
this.props.updateField(name, {
error: hasError,
value
});
return hasError;
}
resetFiled(value) {
const { initValue } = this.state;
this.setState({
value: value === undefined ? initValue : value,
error: false
});
return value === undefined ? initValue : value;
}
resetValidator() {
this.setState({ error: false });
}
render() {
const { children } = this.props;
const { error, message, value } = this.state;
const fieldClass = classnames_1.default({
[utils_1.preClass('has-error')]: error,
[children.props.className]: utils_1.isExist(children.props.className)
});
return (React.createElement("div", { className: utils_1.preClass('form-control') },
React.createElement("div", { className: utils_1.preClass('form-field') }, React.cloneElement(children, Object.assign({ className: fieldClass, onChange: this.onChangeHandler }, ({ [this.ioType === IO_BOOLEAN ? 'checked' : 'value']: value })))),
React.createElement(transition_1.default, { appear: utils_1.preClass('slide-down-appear'), leave: utils_1.preClass('slide-down-leave'), enter: utils_1.preClass('slide-down-enter'), visible: error },
React.createElement("div", { className: utils_1.preClass('form-notice') }, message))));
}
}
FormValidator.propTypes = {
name: PropTypes.string.isRequired,
rule: PropTypes.array
};
exports.default = FormValidator;