zarm-web
Version:
基于 React 的桌面端UI库
149 lines (133 loc) • 3.4 kB
JavaScript
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { FormContext } from './createContext';
import { noop } from '../utils';
class Form extends PureComponent {
constructor(...args) {
super(...args);
this.state = {
fields: []
};
this.onSubmit = event => {
const {
onSubmit
} = this.props;
event.preventDefault();
if (typeof onSubmit === 'function') {
onSubmit(event);
}
};
}
static scrollToError(field) {
const fieldNode = field.getControlNode();
const nodeBound = fieldNode.getBoundingClientRect();
const y = nodeBound.top + window.scrollY;
const x = nodeBound.left + window.scrollX;
window.scroll(x, y);
}
resetField() {
const {
fields
} = this.state;
fields.forEach(field => field.resetItem());
}
validate(callback) {
const {
fields
} = this.state;
const {
scrollToError
} = this.props;
const fieldsLength = fields.length;
return new Promise(resolve => {
let validateResult = true;
let count = 0;
const errorsArr = [];
fields.forEach(field => {
field.validateItem('', errors => {
if (errors) {
validateResult = false;
errorsArr.push(field);
} // eslint-disable-next-line no-plusplus
if (++count === fieldsLength) {
resolve(validateResult);
if (callback instanceof Function) {
callback(validateResult);
}
if (scrollToError && !validateResult) {
Form.scrollToError(errorsArr[0]);
}
}
});
});
});
}
validateField(prop, callback) {
const {
fields
} = this.state;
const field = fields.filter(fieldItem => fieldItem.props.prop === prop)[0];
if (!field) {
throw new Error('please check a exist prop for validateField function');
}
field.validateItem('', callback);
}
render() {
const {
fields
} = this.state;
const {
type,
className,
children,
style,
prefixCls,
labelWidth,
labelPosition,
rules,
model
} = this.props;
const cls = classnames({
[prefixCls]: true,
[`${prefixCls}--${type}`]: 'type' in this.props,
[`${prefixCls}--label-${labelPosition}`]: labelPosition,
[className]: !!className
});
const contextValue = {
fields,
rules,
model,
labelWidth,
labelPosition
};
return React.createElement(FormContext.Provider, {
value: contextValue
}, React.createElement("form", {
className: cls,
style: style,
onSubmit: this.onSubmit
}, children));
}
}
Form.defaultProps = {
prefixCls: 'za-form',
type: 'horizontal',
labelPosition: 'right',
scrollToError: false,
onSubmit: noop,
labelWidth: '',
rules: null,
model: null
};
Form.propTypes = {
prefixCls: PropTypes.string,
type: PropTypes.oneOf(['horizontal', 'inline']),
labelWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
labelPosition: PropTypes.oneOf(['left', 'right']),
rules: PropTypes.instanceOf(Object),
model: PropTypes.instanceOf(Object),
scrollToError: PropTypes.bool,
onSubmit: PropTypes.func
};
export default Form;