|
| 1 | +import PropTypes from '../_util/vue-types' |
| 2 | +import classNames from 'classnames' |
| 3 | +import isRegExp from 'lodash/isRegExp' |
| 4 | +import createDOMForm from '../vc-form/src/createDOMForm' |
| 5 | +import createFormField from '../vc-form/src/createFormField' |
| 6 | +import FormItem from './FormItem' |
| 7 | +import { FIELD_META_PROP, FIELD_DATA_PROP } from './constants' |
| 8 | +import { initDefaultProps } from '../_util/props-util' |
| 9 | + |
| 10 | +export const FormCreateOption = { |
| 11 | + onFieldsChange: PropTypes.func, |
| 12 | + onValuesChange: PropTypes.func, |
| 13 | + mapPropsToFields: PropTypes.func, |
| 14 | + withRef: PropTypes.bool, |
| 15 | +} |
| 16 | + |
| 17 | +// function create |
| 18 | +export const WrappedFormUtils = { |
| 19 | + /** 获取一组输入控件的值,如不传入参数,则获取全部组件的值 */ |
| 20 | + getFieldsValue: PropTypes.func, |
| 21 | + /** 获取一个输入控件的值*/ |
| 22 | + getFieldValue: PropTypes.func, |
| 23 | + /** 设置一组输入控件的值*/ |
| 24 | + setFieldsValue: PropTypes.func, |
| 25 | + /** 设置一组输入控件的值*/ |
| 26 | + setFields: PropTypes.func, |
| 27 | + /** 校验并获取一组输入域的值与 Error */ |
| 28 | + validateFields: PropTypes.func, |
| 29 | + // validateFields(fieldNames: Array<string>, options: Object, callback: ValidateCallback): void; |
| 30 | + // validateFields(fieldNames: Array<string>, callback: ValidateCallback): void; |
| 31 | + // validateFields(options: Object, callback: ValidateCallback): void; |
| 32 | + // validateFields(callback: ValidateCallback): void; |
| 33 | + // validateFields(): void; |
| 34 | + /** 与 `validateFields` 相似,但校验完后,如果校验不通过的菜单域不在可见范围内,则自动滚动进可见范围 */ |
| 35 | + validateFieldsAndScroll: PropTypes.func, |
| 36 | + // validateFieldsAndScroll(fieldNames?: Array<string>, options?: Object, callback?: ValidateCallback): void; |
| 37 | + // validateFieldsAndScroll(fieldNames?: Array<string>, callback?: ValidateCallback): void; |
| 38 | + // validateFieldsAndScroll(options?: Object, callback?: ValidateCallback): void; |
| 39 | + // validateFieldsAndScroll(callback?: ValidateCallback): void; |
| 40 | + // validateFieldsAndScroll(): void; |
| 41 | + /** 获取某个输入控件的 Error */ |
| 42 | + getFieldError: PropTypes.func, |
| 43 | + getFieldsError: PropTypes.func, |
| 44 | + /** 判断一个输入控件是否在校验状态*/ |
| 45 | + isFieldValidating: PropTypes.func, |
| 46 | + isFieldTouched: PropTypes.func, |
| 47 | + isFieldsTouched: PropTypes.func, |
| 48 | + /** 重置一组输入控件的值与状态,如不传入参数,则重置所有组件 */ |
| 49 | + resetFields: PropTypes.func, |
| 50 | + |
| 51 | + getFieldDecorator: PropTypes.func, |
| 52 | +} |
| 53 | + |
| 54 | +export const FormProps = { |
| 55 | + layout: PropTypes.oneOf(['horizontal', 'inline', 'vertical']), |
| 56 | + form: PropTypes.shape(WrappedFormUtils).loose, |
| 57 | + // onSubmit: React.FormEventHandler<any>; |
| 58 | + prefixCls: PropTypes.string, |
| 59 | + hideRequiredMark: PropTypes.bool, |
| 60 | +} |
| 61 | + |
| 62 | +export const ValidationRule = { |
| 63 | + /** validation error message */ |
| 64 | + message: PropTypes.string, |
| 65 | + /** built-in validation type, available options: https://github.com/yiminghe/async-validator#type */ |
| 66 | + type: PropTypes.string, |
| 67 | + /** indicates whether field is required */ |
| 68 | + required: PropTypes.boolean, |
| 69 | + /** treat required fields that only contain whitespace as errors */ |
| 70 | + whitespace: PropTypes.boolean, |
| 71 | + /** validate the exact length of a field */ |
| 72 | + len: PropTypes.number, |
| 73 | + /** validate the min length of a field */ |
| 74 | + min: PropTypes.number, |
| 75 | + /** validate the max length of a field */ |
| 76 | + max: PropTypes.number, |
| 77 | + /** validate the value from a list of possible values */ |
| 78 | + enum: PropTypes.oneOfType([String, PropTypes.arrayOf(String)]), |
| 79 | + /** validate from a regular expression */ |
| 80 | + pattern: PropTypes.custom(isRegExp), |
| 81 | + /** transform a value before validation */ |
| 82 | + transform: PropTypes.func, |
| 83 | + /** custom validate function (Note: callback must be called) */ |
| 84 | + validator: PropTypes.func, |
| 85 | +} |
| 86 | + |
| 87 | +// export type ValidateCallback = (errors: any, values: any) => void; |
| 88 | + |
| 89 | +// export type GetFieldDecoratorOptions = { |
| 90 | +// /** 子节点的值的属性,如 Checkbox 的是 'checked' */ |
| 91 | +// valuePropName?: string; |
| 92 | +// /** 子节点的初始值,类型、可选值均由子节点决定 */ |
| 93 | +// initialValue?: any; |
| 94 | +// /** 收集子节点的值的时机 */ |
| 95 | +// trigger?: string; |
| 96 | +// /** 可以把 onChange 的参数转化为控件的值,例如 DatePicker 可设为:(date, dateString) => dateString */ |
| 97 | +// getValueFromEvent?: (...args: any[]) => any; |
| 98 | +// /** 校验子节点值的时机 */ |
| 99 | +// validateTrigger?: string | string[]; |
| 100 | +// /** 校验规则,参见 [async-validator](https://github.com/yiminghe/async-validator) */ |
| 101 | +// rules?: ValidationRule[]; |
| 102 | +// /** 是否和其他控件互斥,特别用于 Radio 单选控件 */ |
| 103 | +// exclusive?: boolean; |
| 104 | +// /** Normalize value to form component */ |
| 105 | +// normalize?: (value: any, prevValue: any, allValues: any) => any; |
| 106 | +// /** Whether stop validate on first rule of error for this field. */ |
| 107 | +// validateFirst?: boolean; |
| 108 | +// }; |
| 109 | + |
| 110 | +export default { |
| 111 | + name: 'AForm', |
| 112 | + props: initDefaultProps(FormProps, { |
| 113 | + prefixCls: 'ant-form', |
| 114 | + layout: 'horizontal', |
| 115 | + hideRequiredMark: false, |
| 116 | + }), |
| 117 | + // static defaultProps = { |
| 118 | + // prefixCls: 'ant-form', |
| 119 | + // layout: 'horizontal', |
| 120 | + // hideRequiredMark: false, |
| 121 | + // onSubmit (e) { |
| 122 | + // e.preventDefault() |
| 123 | + // }, |
| 124 | + // }; |
| 125 | + |
| 126 | + // static propTypes = { |
| 127 | + // prefixCls: PropTypes.string, |
| 128 | + // layout: PropTypes.oneOf(['horizontal', 'inline', 'vertical']), |
| 129 | + // children: PropTypes.any, |
| 130 | + // onSubmit: PropTypes.func, |
| 131 | + // hideRequiredMark: PropTypes.bool, |
| 132 | + // }; |
| 133 | + |
| 134 | + Item: FormItem, |
| 135 | + |
| 136 | + createFormField: createFormField, |
| 137 | + |
| 138 | + create: (options = {}) => { |
| 139 | + return createDOMForm({ |
| 140 | + fieldNameProp: 'id', |
| 141 | + ...options, |
| 142 | + fieldMetaProp: FIELD_META_PROP, |
| 143 | + fieldDataProp: FIELD_DATA_PROP, |
| 144 | + }) |
| 145 | + }, |
| 146 | + |
| 147 | + // constructor (props) { |
| 148 | + // super(props) |
| 149 | + |
| 150 | + // warning(!props.form, 'It is unnecessary to pass `form` to `Form` after [email protected].') |
| 151 | + // } |
| 152 | + |
| 153 | + // shouldComponentUpdate(...args) { |
| 154 | + // return PureRenderMixin.shouldComponentUpdate.apply(this, args); |
| 155 | + // } |
| 156 | + |
| 157 | + // getChildContext () { |
| 158 | + // const { layout } = this.props |
| 159 | + // return { |
| 160 | + // vertical: layout === 'vertical', |
| 161 | + // } |
| 162 | + // }, |
| 163 | + provide () { |
| 164 | + return { |
| 165 | + FormProps: this.$props, |
| 166 | + } |
| 167 | + }, |
| 168 | + methods: { |
| 169 | + onSubmit (e) { |
| 170 | + const { $listeners } = this |
| 171 | + if (!$listeners.submit) { |
| 172 | + e.preventDefault() |
| 173 | + } else { |
| 174 | + this.$emit('submit', e) |
| 175 | + } |
| 176 | + }, |
| 177 | + }, |
| 178 | + |
| 179 | + render () { |
| 180 | + const { |
| 181 | + prefixCls, hideRequiredMark, layout, onSubmit, $slots, |
| 182 | + } = this |
| 183 | + |
| 184 | + const formClassName = classNames(prefixCls, { |
| 185 | + [`${prefixCls}-horizontal`]: layout === 'horizontal', |
| 186 | + [`${prefixCls}-vertical`]: layout === 'vertical', |
| 187 | + [`${prefixCls}-inline`]: layout === 'inline', |
| 188 | + [`${prefixCls}-hide-required-mark`]: hideRequiredMark, |
| 189 | + }) |
| 190 | + |
| 191 | + return <form onSubmit={onSubmit} class={formClassName}>{$slots.default}</form> |
| 192 | + }, |
| 193 | +} |
0 commit comments