UNPKG

zarm-web

Version:
149 lines (133 loc) 3.4 kB
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;