From 3a2977a2eddcc6f2ceb44f033b15d38a0a54fabc Mon Sep 17 00:00:00 2001 From: wangxueliang Date: Sat, 20 Apr 2019 14:19:13 +0800 Subject: [PATCH] feat: update form --- components/form/Form.jsx | 13 +++-- components/form/FormItem.jsx | 52 +++++++++++-------- components/form/demo/advanced-search.vue | 2 +- components/form/demo/coordinated.vue | 2 +- .../form/demo/customized-form-controls.vue | 2 +- components/form/demo/dynamic-form-item.vue | 4 +- components/form/demo/dynamic-rule.vue | 2 +- components/form/demo/form-in-modal.vue | 2 +- components/form/demo/global-state.vue | 1 + components/form/demo/horizontal-login.vue | 2 +- components/form/demo/normal-login.vue | 2 +- components/form/demo/register.vue | 2 +- .../form/demo/time-related-controls.vue | 2 +- components/form/demo/validate-other.vue | 4 +- components/form/demo/validate-static.vue | 4 +- components/form/index.en-US.md | 1 + components/form/index.zh-CN.md | 1 + 17 files changed, 55 insertions(+), 43 deletions(-) diff --git a/components/form/Form.jsx b/components/form/Form.jsx index 2c9030756..39913e701 100755 --- a/components/form/Form.jsx +++ b/components/form/Form.jsx @@ -8,6 +8,7 @@ import createFormField from '../vc-form/src/createFormField'; import FormItem from './FormItem'; import { FIELD_META_PROP, FIELD_DATA_PROP } from './constants'; import { initDefaultProps } from '../_util/props-util'; +import { ConfigConsumerProps } from '../config-provider'; export const FormCreateOption = { onFieldsChange: PropTypes.func, @@ -15,6 +16,7 @@ export const FormCreateOption = { mapPropsToFields: PropTypes.func, validateMessages: PropTypes.any, withRef: PropTypes.bool, + name: PropTypes.string, }; // function create @@ -119,15 +121,11 @@ export const ValidationRule = { const Form = { name: 'AForm', props: initDefaultProps(FormProps, { - prefixCls: 'ant-form', layout: 'horizontal', hideRequiredMark: false, }), - Item: FormItem, - createFormField: createFormField, - create: (options = {}) => { return createDOMForm({ fieldNameProp: 'id', @@ -166,6 +164,9 @@ const Form = { : () => {}, }; }, + inject: { + configProvider: { default: () => ({}) }, + }, watch: { form() { this.$forceUpdate(); @@ -196,7 +197,7 @@ const Form = { render() { const { - prefixCls, + prefixCls: customizePrefixCls, hideRequiredMark, layout, onSubmit, @@ -204,6 +205,8 @@ const Form = { autoFormCreate, options = {}, } = this; + const getPrefixCls = this.configProvider.getPrefixCls || ConfigConsumerProps.getPrefixCls; + const prefixCls = getPrefixCls('form', customizePrefixCls); const formClassName = classNames(prefixCls, { [`${prefixCls}-horizontal`]: layout === 'horizontal', diff --git a/components/form/FormItem.jsx b/components/form/FormItem.jsx index be85cb042..736ae8366 100644 --- a/components/form/FormItem.jsx +++ b/components/form/FormItem.jsx @@ -18,6 +18,7 @@ import getTransitionProps from '../_util/getTransitionProps'; import BaseMixin from '../_util/BaseMixin'; import { cloneElement, cloneVNodes } from '../_util/vnode'; import Icon from '../icon'; +import { ConfigConsumerProps } from '../config-provider'; function noop() {} export const FormItemProps = { @@ -65,6 +66,7 @@ export default { FormProps: { default: () => ({}) }, decoratorFormProps: { default: () => ({}) }, collectFormItemContext: { default: () => noop }, + configProvider: { default: () => ({}) }, }, data() { return { helpShow: false }; @@ -197,8 +199,7 @@ export default { } }, - renderHelp() { - const prefixCls = this.prefixCls; + renderHelp(prefixCls) { const help = this.getHelpMessage(); const children = help ? (
@@ -219,8 +220,7 @@ export default { ); }, - renderExtra() { - const { prefixCls } = this; + renderExtra(prefixCls) { const extra = getComponentFromProp(this, 'extra'); return extra ?
{extra}
: null; }, @@ -244,7 +244,7 @@ export default { return ''; }, - renderValidateWrapper(c1, c2, c3) { + renderValidateWrapper(prefixCls, c1, c2, c3) { const props = this.$props; const onlyControl = this.getOnlyControl; const validateStatus = @@ -252,9 +252,9 @@ export default { ? this.getValidateStatus() : props.validateStatus; - let classes = `${props.prefixCls}-item-control`; + let classes = `${prefixCls}-item-control`; if (validateStatus) { - classes = classNames(`${props.prefixCls}-item-control`, { + classes = classNames(`${prefixCls}-item-control`, { 'has-feedback': props.hasFeedback || validateStatus === 'validating', 'has-success': validateStatus === 'success', 'has-warning': validateStatus === 'warning', @@ -282,13 +282,13 @@ export default { } const icon = props.hasFeedback && iconType ? ( - + ) : null; return (
- + {c1} {icon} @@ -298,8 +298,8 @@ export default { ); }, - renderWrapper(children) { - const { prefixCls, wrapperCol = {} } = this; + renderWrapper(prefixCls, children) { + const { wrapperCol = {} } = this; const { class: cls, style, id, on, ...restProps } = wrapperCol; const className = classNames(`${prefixCls}-item-control-wrapper`, cls); const colProps = { @@ -353,8 +353,8 @@ export default { } }, - renderLabel() { - const { prefixCls, labelCol = {}, colon, id } = this; + renderLabel(prefixCls) { + const { labelCol = {}, colon, id } = this; const label = getComponentFromProp(this, 'label'); const required = this.isRequired(); const { @@ -398,21 +398,29 @@ export default { ) : null; }, - renderChildren() { + renderChildren(prefixCls) { return [ - this.renderLabel(), + this.renderLabel(prefixCls), this.renderWrapper( - this.renderValidateWrapper(this.slotDefault, this.renderHelp(), this.renderExtra()), + prefixCls, + this.renderValidateWrapper( + prefixCls, + this.slotDefault, + this.renderHelp(prefixCls), + this.renderExtra(prefixCls) + ), ), ]; }, - renderFormItem(children) { - const props = this.$props; - const prefixCls = props.prefixCls; + renderFormItem() { + const { prefixCls: customizePrefixCls, colon } = this.$props; + const getPrefixCls = this.configProvider.getPrefixCls || ConfigConsumerProps.getPrefixCls; + const prefixCls = getPrefixCls('form', customizePrefixCls); + const children = this.renderChildren(prefixCls); const itemClassName = { [`${prefixCls}-item`]: true, [`${prefixCls}-item-with-help`]: this.helpShow, - [`${prefixCls}-item-no-colon`]: !props.colon, + [`${prefixCls}-item-no-colon`]: !colon, }; return {children}; @@ -478,8 +486,6 @@ export default { } else { this.slotDefault = child; } - - const children = this.renderChildren(); - return this.renderFormItem(children); + return this.renderFormItem(); }, }; diff --git a/components/form/demo/advanced-search.vue b/components/form/demo/advanced-search.vue index 6a0a65bd2..b7f6e1637 100644 --- a/components/form/demo/advanced-search.vue +++ b/components/form/demo/advanced-search.vue @@ -77,7 +77,7 @@ export default { data () { return { expand: false, - form: this.$form.createForm(this), + form: this.$form.createForm(this, { name: 'advanced_search' }), }; }, computed: { diff --git a/components/form/demo/coordinated.vue b/components/form/demo/coordinated.vue index 131cd71bb..01bf73577 100644 --- a/components/form/demo/coordinated.vue +++ b/components/form/demo/coordinated.vue @@ -65,7 +65,7 @@ export default { data () { return { formLayout: 'horizontal', - form: this.$form.createForm(this), + form: this.$form.createForm(this, { name: 'coordinated' }), }; }, methods: { diff --git a/components/form/demo/customized-form-controls.vue b/components/form/demo/customized-form-controls.vue index 524ac1e0e..dcb684598 100644 --- a/components/form/demo/customized-form-controls.vue +++ b/components/form/demo/customized-form-controls.vue @@ -111,7 +111,7 @@ export default { PriceInput, }, beforeCreate () { - this.form = this.$form.createForm(this); + this.form = this.$form.createForm(this, { name: 'customized_form_controls' }); }, methods: { handleSubmit (e) { diff --git a/components/form/demo/dynamic-form-item.vue b/components/form/demo/dynamic-form-item.vue index 3919d4ae4..94d92d49a 100644 --- a/components/form/demo/dynamic-form-item.vue +++ b/components/form/demo/dynamic-form-item.vue @@ -89,7 +89,7 @@ export default { }; }, beforeCreate () { - this.form = this.$form.createForm(this); + this.form = this.$form.createForm(this, { name: 'dynamic_form_item' }); this.form.getFieldDecorator('keys', { initialValue: [], preserve: true }); }, methods: { @@ -112,7 +112,7 @@ export default { const { form } = this; // can use data-binding to get const keys = form.getFieldValue('keys'); - const nextKeys = keys.concat(++id); + const nextKeys = keys.concat(id++); // can use data-binding to set // important! notify form to detect changes form.setFieldsValue({ diff --git a/components/form/demo/dynamic-rule.vue b/components/form/demo/dynamic-rule.vue index 85af8db01..16bdf0893 100644 --- a/components/form/demo/dynamic-rule.vue +++ b/components/form/demo/dynamic-rule.vue @@ -77,7 +77,7 @@ export default { checkNick: false, formItemLayout, formTailLayout, - form: this.$form.createForm(this), + form: this.$form.createForm(this, { name: 'dynamic_rule' }), }; }, methods: { diff --git a/components/form/demo/form-in-modal.vue b/components/form/demo/form-in-modal.vue index c38a24926..ae99f16c9 100644 --- a/components/form/demo/form-in-modal.vue +++ b/components/form/demo/form-in-modal.vue @@ -29,7 +29,7 @@ When user visit a page with a list of items, and want to create a new item. The const CollectionCreateForm = { props: ['visible'], beforeCreate () { - this.form = this.$form.createForm(this); + this.form = this.$form.createForm(this, { name: 'form_in_modal' }); }, template: ` { this.$emit('change', changedFields); }, diff --git a/components/form/demo/horizontal-login.vue b/components/form/demo/horizontal-login.vue index f35ec0fc0..8b2085e35 100644 --- a/components/form/demo/horizontal-login.vue +++ b/components/form/demo/horizontal-login.vue @@ -72,7 +72,7 @@ export default { data () { return { hasErrors, - form: this.$form.createForm(this), + form: this.$form.createForm(this, { name: 'horizontal_login' }), }; }, mounted () { diff --git a/components/form/demo/normal-login.vue b/components/form/demo/normal-login.vue index 6d0694643..ef8b0fe43 100644 --- a/components/form/demo/normal-login.vue +++ b/components/form/demo/normal-login.vue @@ -82,7 +82,7 @@ Normal login form which can contain more elements. export default { beforeCreate () { - this.form = this.$form.createForm(this); + this.form = this.$form.createForm(this, { name: 'normal_login' }); }, methods: { handleSubmit (e) { diff --git a/components/form/demo/register.vue b/components/form/demo/register.vue index 65ce5fd9d..cf288d1d7 100644 --- a/components/form/demo/register.vue +++ b/components/form/demo/register.vue @@ -248,7 +248,7 @@ export default { }; }, beforeCreate () { - this.form = this.$form.createForm(this); + this.form = this.$form.createForm(this, { name: 'register' }); }, methods: { handleSubmit (e) { diff --git a/components/form/demo/time-related-controls.vue b/components/form/demo/time-related-controls.vue index 15bf549c1..fee759ebd 100644 --- a/components/form/demo/time-related-controls.vue +++ b/components/form/demo/time-related-controls.vue @@ -95,7 +95,7 @@ export default { }; }, beforeCreate () { - this.form = this.$form.createForm(this); + this.form = this.$form.createForm(this, { name: 'time_related_controls' }); }, methods: { handleSubmit (e) { diff --git a/components/form/demo/validate-other.vue b/components/form/demo/validate-other.vue index d991f77e5..b4143f03c 100644 --- a/components/form/demo/validate-other.vue +++ b/components/form/demo/validate-other.vue @@ -5,7 +5,7 @@ #### Other Form Controls -Demostration for validataion configuration for form controls which are not show in the above demos. +Demonstration of validation configuration for form controls which are not shown in the demos above. @@ -252,7 +252,7 @@ export default { }, }), beforeCreate () { - this.form = this.$form.createForm(this); + this.form = this.$form.createForm(this, { name: 'validate_other' }); }, methods: { handleSubmit (e) { diff --git a/components/form/demo/validate-static.vue b/components/form/demo/validate-static.vue index eb9781398..8482ae457 100644 --- a/components/form/demo/validate-static.vue +++ b/components/form/demo/validate-static.vue @@ -77,7 +77,7 @@ We provide properties like `validateStatus` `help` `hasFeedback` to customize yo validate-status="warning" > @@ -91,7 +91,7 @@ We provide properties like `validateStatus` `help` `hasFeedback` to customize yo help="Should be combination of numbers & alphabets" > diff --git a/components/form/index.en-US.md b/components/form/index.en-US.md index 78b38a6f6..4600509f8 100644 --- a/components/form/index.en-US.md +++ b/components/form/index.en-US.md @@ -48,6 +48,7 @@ The following `options` are available: | -------- | ----------- | ---- | | props | Only supports the use of Form.create({})(CustomizedForm). declare props on form(和[like vue props]( https://vuejs.org/v2/api/#props)) | {} | | mapPropsToFields | Convert props to field value(e.g. reading the values from Redux store). And you must mark returned fields with [`Form.createFormField`](#Form.createFormField). If you use `$form.createForm` to create a collector, you can map any data to the Field without being bound by the parent component. | (props) => Object{ fieldName: FormField { value } } | +| name | Set the id prefix of fields under form | - | | validateMessages | Default validate message. And its format is similar with [newMessages](https://github.com/yiminghe/async-validator/blob/master/src/messages.js)'s returned value | Object { [nested.path]: String } | | onFieldsChange | Specify a function that will be called when the value a `Form.Item` gets changed. Usage example: saving the field's value to Redux store. | Function(props, fields) | | onValuesChange | A handler while value of any field is changed | (props, values) => void | diff --git a/components/form/index.zh-CN.md b/components/form/index.zh-CN.md index ce230ca6d..682e26b5c 100644 --- a/components/form/index.zh-CN.md +++ b/components/form/index.zh-CN.md @@ -46,6 +46,7 @@ export default { | --- | --- | --- | | props | 仅仅支持Form.create({})(CustomizedForm)的使用方式,父组件需要映射到表单项上的属性声明(和[vue组件props一致]( https://vuejs.org/v2/api/#props)) | {} | | mapPropsToFields | 把父组件的属性映射到表单项上(如:把 Redux store 中的值读出),需要对返回值中的表单域数据用 [`Form.createFormField`](#Form.createFormField) 标记,如果使用$form.createForm创建收集器,你可以将任何数据映射到Field中,不受父组件约束 | (props) => ({ \[fieldName\]: FormField { value } }) | +| name | 设置表单域内字段 id 的前缀 | - | | validateMessages | 默认校验信息,可用于把默认错误信息改为中文等,格式与 [newMessages](https://github.com/yiminghe/async-validator/blob/master/src/messages.js) 返回值一致 | Object { [nested.path]: String } | | onFieldsChange | 当 `Form.Item` 子节点的值发生改变时触发,可以把对应的值转存到 Redux store | Function(props, fields) | | onValuesChange | 任一表单域的值发生改变时的回调 | (props, values) => void |