UNPKG

chowa

Version:

UI component library based on React

178 lines (177 loc) 6.6 kB
/** * @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;