From 38142fd25cb1c77c3a36c443d6920741d0aced85 Mon Sep 17 00:00:00 2001 From: infinite-yy Date: Mon, 21 Aug 2017 16:28:37 +0800 Subject: [PATCH] add validate to simpleForm and TextInput --- src/widgets/form/SimpleForm.js | 33 +++++--- src/widgets/input/TextInput.js | 17 +++- src/widgets/validate.js | 142 +++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+), 13 deletions(-) create mode 100644 src/widgets/validate.js diff --git a/src/widgets/form/SimpleForm.js b/src/widgets/form/SimpleForm.js index 6245913..2d917c0 100644 --- a/src/widgets/form/SimpleForm.js +++ b/src/widgets/form/SimpleForm.js @@ -6,37 +6,52 @@ import Toolbar from './Toolbar'; import MobxReactForm from 'mobx-react-form'; import { SaveButton } from '../button'; +import {validateForm} from '../validate' + class DefaultForm extends MobxReactForm { } + + @observer -export default class SimpleForm extends React.Component { +@validateForm +class SimpleForm extends React.Component { + constructor(){ + super(); + this.inputs = []; + } render() { let { record, children, onSubmit, invalid, form, fields, showToolbar, plugins } = this.props const submitHandler = (e) => { + e.preventDefault(); if (onSubmit) { - onSubmit(this.record) + onSubmit(record) } - e.preventDefault(); } if (form == null) { form = new DefaultForm(fields, plugins) } const createChangeHandler = (element) => { return (e) => { - //this.handleFieldChange(e, element.props.source, e.target.value) - if (element.props.onChange) { - element.props.onChange(e, element.props.source, e.target.value) - } + + // //this.handleFieldChange(e, element.props.source, e.target.value) + // if (element.props.onChange) { + // element.props.onChange(e, element.props.source, e.target.value) + // } } } return
{React.Children.map(children, input => (
- {React.cloneElement(input, { record: record, source: input.props.source, onChange: createChangeHandler(input) })} + {React.cloneElement(input, { record: record, source: input.props.source, onChange: createChangeHandler(input), ref: component => {this.inputs.push(component)}})}
))}
{showToolbar && } } -} \ No newline at end of file +} + +export default SimpleForm; + + + diff --git a/src/widgets/input/TextInput.js b/src/widgets/input/TextInput.js index 69dc47d..6dc205c 100644 --- a/src/widgets/input/TextInput.js +++ b/src/widgets/input/TextInput.js @@ -5,6 +5,8 @@ import { observer } from 'mobx-react' import TextField from 'material-ui/TextField'; import { fetchValue, writeValue } from '../utils' +import {validateInput} from '../validate' + /** * An Input component for a string * @@ -21,23 +23,30 @@ import { fetchValue, writeValue } from '../utils' */ @observer class TextInput extends Component { + @validateInput handleChange = (event) => { this.props.writeValue(this, event.target.value) if (this.props.onChange) { this.props.onChange(event, this.props.source, event.target.value) } + + } + @observable _errorText; + @observable _value = '' render() { - const { fetchValue, label, style, type, disabled} = this.props + const { fetchValue, label, style, type, disabled } = this.props return {label}} + + errorText={this._errorText || ''} /> } } @@ -53,7 +62,7 @@ TextInput.propTypes = { fetchValue: PropTypes.func, writeValue: PropTypes.func, type: PropTypes.string, - convert: PropTypes.oneOfType([PropTypes.func,PropTypes.object]) + convert: PropTypes.oneOfType([PropTypes.func, PropTypes.object]) }; TextInput.defaultProps = { diff --git a/src/widgets/validate.js b/src/widgets/validate.js new file mode 100644 index 0000000..f559644 --- /dev/null +++ b/src/widgets/validate.js @@ -0,0 +1,142 @@ +import React from 'react'; +import { getValues } from './utils' + +export function validateInput(target, key, descriptor) { + const method = descriptor.initializer; + descriptor.initializer = function () { + return function (event) { + this.props.validators.map((validator, index) => { + check.apply(this, [validator, this.props.errorMessages[index], event.target.value]); + }); + this._value = event.target.value; + method.apply(this)(event); + } + }; + return descriptor; +} +export function validateForm(Form) { + + return class extends React.Component { + onSubmit(data) { + if (this.wci) { + let all_clear = true; + this.wci.map((child) => { + if (child.props.validators) { + for (var i = 0, l = child.props.validators.length; i < l; i++) { + if (!check.apply(child, [child.props.validators[i], child.props.errorMessages[i], getValues(child.props.record, child.props.source)[0]])) { + all_clear = false; + break; + } + } + } + }); + if (all_clear) { + console.log('all clear'); + this.props.onSubmit(data); + } + } + } + proc(wrappedComponentInstance) { + if(wrappedComponentInstance){ + this.wci = wrappedComponentInstance.inputs; + } + } + render() { + const props = Object.assign({}, this.props, { ref: this.proc.bind(this) }) + return
+ } + } +} + +function check(validator, errorMsg, data) { + if (!getValidator(validator)(data)) { + this._errorText = errorMsg; + this.props.writeValue(this, 'Error'); + return false; + } else { + this._errorText = ''; + return true; + } +} + +function getValidator(validator) { + switch (validator) { + case 'required': + return validations.required + break; + case 'email': + return validations.isEmail + break; + case 'phone': + return validations.isNumber + break; + default: + return function () { return true }; + } +} + +// ValidationRules +// copy from +// ----------------------------------------------------------------------------------------------------------------- +var isExisty = function isExisty(value) { + return value !== null && value !== undefined; +}; + +var _isEmpty = function _isEmpty(value) { + return value === '' || value === undefined || value == null; +}; + +var isEmptyTrimed = function isEmptyTrimed(value) { + if (typeof value === 'string') { + return value.trim() === ''; + } + return true; +}; + +var validations = { + matchRegexp: function matchRegexp(value, regexp) { + var validationRegexp = regexp instanceof RegExp ? regexp : new RegExp(regexp); + return !isExisty(value) || _isEmpty(value) || validationRegexp.test(value); + }, + + // eslint-disable-next-line + isEmail: function isEmail(value) { + return validations.matchRegexp(value, /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i); + }, + + isEmpty: function isEmpty(value) { + return _isEmpty(value); + }, + + required: function required(value) { + return !_isEmpty(value); + }, + + trim: function trim(value) { + return !isEmptyTrimed(value); + }, + + isNumber: function isNumber(value) { + return validations.matchRegexp(value, /^-?[0-9]\d*(\d+)?$/i); + }, + + isFloat: function isFloat(value) { + return validations.matchRegexp(value, /^(?:[1-9]\d*|0)?(?:\.\d+)?$/i); + }, + + isPositive: function isPositive(value) { + if (isExisty(value)) { + return (validations.isNumber(value) || validations.isFloat(value)) && value >= 0; + } + return true; + }, + + maxNumber: function maxNumber(value, max) { + return !isExisty(value) || _isEmpty(value) || parseInt(value, 10) <= parseInt(max, 10); + }, + + minNumber: function minNumber(value, min) { + return !isExisty(value) || _isEmpty(value) || parseInt(value, 10) >= parseInt(min, 10); + } +}; +// ----------------------------------------------------------------------------------------------------------------- \ No newline at end of file