Merge branch 'feat-form-template'
commit
d718914fa7
|
@ -57,6 +57,8 @@ export const FormProps = {
|
||||||
// onSubmit: React.FormEventHandler<any>;
|
// onSubmit: React.FormEventHandler<any>;
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
hideRequiredMark: PropTypes.bool,
|
hideRequiredMark: PropTypes.bool,
|
||||||
|
autoFormCreate: PropTypes.func,
|
||||||
|
options: PropTypes.object,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ValidationRule = {
|
export const ValidationRule = {
|
||||||
|
@ -143,23 +145,6 @@ export default {
|
||||||
fieldDataProp: FIELD_DATA_PROP,
|
fieldDataProp: FIELD_DATA_PROP,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// constructor (props) {
|
|
||||||
// super(props)
|
|
||||||
|
|
||||||
// warning(!props.form, 'It is unnecessary to pass `form` to `Form` after antd@1.7.0.')
|
|
||||||
// }
|
|
||||||
|
|
||||||
// shouldComponentUpdate(...args) {
|
|
||||||
// return PureRenderMixin.shouldComponentUpdate.apply(this, args);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// getChildContext () {
|
|
||||||
// const { layout } = this.props
|
|
||||||
// return {
|
|
||||||
// vertical: layout === 'vertical',
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
provide () {
|
provide () {
|
||||||
return {
|
return {
|
||||||
FormProps: this.$props,
|
FormProps: this.$props,
|
||||||
|
@ -178,7 +163,7 @@ export default {
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const {
|
const {
|
||||||
prefixCls, hideRequiredMark, layout, onSubmit, $slots,
|
prefixCls, hideRequiredMark, layout, onSubmit, $slots, autoFormCreate, options = {},
|
||||||
} = this
|
} = this
|
||||||
|
|
||||||
const formClassName = classNames(prefixCls, {
|
const formClassName = classNames(prefixCls, {
|
||||||
|
@ -187,6 +172,43 @@ export default {
|
||||||
[`${prefixCls}-inline`]: layout === 'inline',
|
[`${prefixCls}-inline`]: layout === 'inline',
|
||||||
[`${prefixCls}-hide-required-mark`]: hideRequiredMark,
|
[`${prefixCls}-hide-required-mark`]: hideRequiredMark,
|
||||||
})
|
})
|
||||||
|
if (autoFormCreate) {
|
||||||
|
const DomForm = this.DomForm || createDOMForm({
|
||||||
|
fieldNameProp: 'id',
|
||||||
|
...options,
|
||||||
|
fieldMetaProp: FIELD_META_PROP,
|
||||||
|
fieldDataProp: FIELD_DATA_PROP,
|
||||||
|
templateContext: this.$parent,
|
||||||
|
})({
|
||||||
|
provide () {
|
||||||
|
return {
|
||||||
|
decoratorFormProps: this.$props,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
children: $slots.default,
|
||||||
|
formClassName: formClassName,
|
||||||
|
submit: onSubmit,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
autoFormCreate(this.form)
|
||||||
|
},
|
||||||
|
render () {
|
||||||
|
const { children, formClassName, submit } = this
|
||||||
|
return <form onSubmit={submit} class={formClassName}>{children}</form>
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if (this.domForm) {
|
||||||
|
this.domForm.children = $slots.default
|
||||||
|
this.domForm.submit = onSubmit
|
||||||
|
this.domForm.formClassName = formClassName
|
||||||
|
}
|
||||||
|
this.DomForm = DomForm
|
||||||
|
|
||||||
|
return <DomForm wrappedComponentRef={(inst) => { this.domForm = inst }}/>
|
||||||
|
}
|
||||||
|
|
||||||
return <form onSubmit={onSubmit} class={formClassName}>{$slots.default}</form>
|
return <form onSubmit={onSubmit} class={formClassName}>{$slots.default}</form>
|
||||||
},
|
},
|
||||||
|
|
|
@ -20,6 +20,8 @@ export const FormItemProps = {
|
||||||
hasFeedback: PropTypes.bool,
|
hasFeedback: PropTypes.bool,
|
||||||
required: PropTypes.bool,
|
required: PropTypes.bool,
|
||||||
colon: PropTypes.bool,
|
colon: PropTypes.bool,
|
||||||
|
fieldDecoratorId: PropTypes.string,
|
||||||
|
fieldDecoratorOptions: PropTypes.object,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -33,21 +35,18 @@ export default {
|
||||||
}),
|
}),
|
||||||
inject: {
|
inject: {
|
||||||
FormProps: { default: {}},
|
FormProps: { default: {}},
|
||||||
|
decoratorFormProps: { default: {}},
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return { helpShow: false }
|
return { helpShow: false }
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
warning(
|
warning(
|
||||||
this.getControls(this.$slots.default, true).length <= 1,
|
this.getControls(this.slotDefault, true).length <= 1,
|
||||||
'`Form.Item` cannot generate `validateStatus` and `help` automatically, ' +
|
'`Form.Item` cannot generate `validateStatus` and `help` automatically, ' +
|
||||||
'while there are more than one `getFieldDecorator` in it.',
|
'while there are more than one `getFieldDecorator` in it.',
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
// shouldComponentUpdate(...args: any[]) {
|
|
||||||
// return PureRenderMixin.shouldComponentUpdate.apply(this, args);
|
|
||||||
// }
|
|
||||||
methods: {
|
methods: {
|
||||||
getHelpMsg () {
|
getHelpMsg () {
|
||||||
const help = getComponentFromProp(this, 'help')
|
const help = getComponentFromProp(this, 'help')
|
||||||
|
@ -90,7 +89,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
getOnlyControl () {
|
getOnlyControl () {
|
||||||
const child = this.getControls(this.$slots.default, false)[0]
|
const child = this.getControls(this.slotDefault, false)[0]
|
||||||
return child !== undefined ? child : null
|
return child !== undefined ? child : null
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -303,12 +302,11 @@ export default {
|
||||||
) : null
|
) : null
|
||||||
},
|
},
|
||||||
renderChildren () {
|
renderChildren () {
|
||||||
const { $slots } = this
|
|
||||||
return [
|
return [
|
||||||
this.renderLabel(),
|
this.renderLabel(),
|
||||||
this.renderWrapper(
|
this.renderWrapper(
|
||||||
this.renderValidateWrapper(
|
this.renderValidateWrapper(
|
||||||
filterEmpty($slots.default || []),
|
this.slotDefault,
|
||||||
this.renderHelp(),
|
this.renderHelp(),
|
||||||
this.renderExtra(),
|
this.renderExtra(),
|
||||||
),
|
),
|
||||||
|
@ -333,6 +331,18 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
const { $slots, decoratorFormProps, fieldDecoratorId, fieldDecoratorOptions = {}} = this
|
||||||
|
const child = filterEmpty($slots.default || [])
|
||||||
|
if (decoratorFormProps.form && fieldDecoratorId && child.length) {
|
||||||
|
const getFieldDecorator = decoratorFormProps.form.getFieldDecorator
|
||||||
|
child[0] = getFieldDecorator(fieldDecoratorId, fieldDecoratorOptions)(child[0])
|
||||||
|
warning(
|
||||||
|
!(child.length > 1),
|
||||||
|
'`autoFormCreate` just `decorator` then first children. but you can use JSX to support multiple children',
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.slotDefault = child
|
||||||
const children = this.renderChildren()
|
const children = this.renderChildren()
|
||||||
return this.renderFormItem(children)
|
return this.renderFormItem(children)
|
||||||
},
|
},
|
||||||
|
|
|
@ -221,7 +221,7 @@ exports[`renders ./components/form/demo/dynamic-form-item.vue correctly 1`] = `
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`renders ./components/form/demo/dynamic-rule.vue correctly 1`] = `
|
exports[`renders ./components/form/demo/dynamic-rule.vue correctly 1`] = `
|
||||||
<div>
|
<form class="ant-form ant-form-horizontal">
|
||||||
<div class="ant-row ant-form-item">
|
<div class="ant-row ant-form-item">
|
||||||
<div class="ant-col-4 ant-form-item-label">
|
<div class="ant-col-4 ant-form-item-label">
|
||||||
<label for="username" title="Name" class="ant-form-item-required">Name</label>
|
<label for="username" title="Name" class="ant-form-item-required">Name</label>
|
||||||
|
@ -244,7 +244,9 @@ exports[`renders ./components/form/demo/dynamic-rule.vue correctly 1`] = `
|
||||||
</div>
|
</div>
|
||||||
<div class="ant-row ant-form-item">
|
<div class="ant-row ant-form-item">
|
||||||
<div class="ant-col-8 ant-col-offset-4 ant-form-item-control-wrapper">
|
<div class="ant-col-8 ant-col-offset-4 ant-form-item-control-wrapper">
|
||||||
<div class="ant-form-item-control"><span class="ant-form-item-children"><label class="ant-checkbox-wrapper"><span class="ant-checkbox"><input type="checkbox" class="ant-checkbox-input"><span class="ant-checkbox-inner"></span></span><span>Nickname is required</span></label>
|
<div class="ant-form-item-control"><span class="ant-form-item-children"><label class="ant-checkbox-wrapper"><span class="ant-checkbox"><input type="checkbox" class="ant-checkbox-input"><span class="ant-checkbox-inner"></span></span><span>
|
||||||
|
Nickname is required
|
||||||
|
</span></label>
|
||||||
</span>
|
</span>
|
||||||
<!---->
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
|
@ -258,7 +260,7 @@ exports[`renders ./components/form/demo/dynamic-rule.vue correctly 1`] = `
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`renders ./components/form/demo/form-in-modal.vue correctly 1`] = `
|
exports[`renders ./components/form/demo/form-in-modal.vue correctly 1`] = `
|
||||||
|
@ -314,7 +316,7 @@ exports[`renders ./components/form/demo/horizontal-login.vue correctly 1`] = `
|
||||||
</div>
|
</div>
|
||||||
<div class="ant-row ant-form-item">
|
<div class="ant-row ant-form-item">
|
||||||
<div class="ant-form-item-control-wrapper">
|
<div class="ant-form-item-control-wrapper">
|
||||||
<div class="ant-form-item-control"><span class="ant-form-item-children"><button type="submit" class="ant-btn ant-btn-primary" disabled="disabled"><span>Log in</span></button>
|
<div class="ant-form-item-control"><span class="ant-form-item-children"><button type="submit" class="ant-btn ant-btn-primary"><span>Log in</span></button>
|
||||||
</span>
|
</span>
|
||||||
<!---->
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,6 +13,7 @@ Because the width of label is not fixed, you may need to adjust it by customizin
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Form } from 'vue-antd-ui'
|
import { Form } from 'vue-antd-ui'
|
||||||
|
import { setTimeout } from 'timers'
|
||||||
|
|
||||||
const AdvancedSearchForm = {
|
const AdvancedSearchForm = {
|
||||||
data () {
|
data () {
|
||||||
|
|
|
@ -9,10 +9,49 @@ Use `setFieldsValue` to set other control's value programmaticly.
|
||||||
</us>
|
</us>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<template>
|
||||||
import { Form } from 'vue-antd-ui'
|
<a-form @submit="handleSubmit" :autoFormCreate="(form)=>{this.form = form}">
|
||||||
|
<a-form-item
|
||||||
|
label='Note'
|
||||||
|
:labelCol="{ span: 5 }"
|
||||||
|
:wrapperCol="{ span: 12 }"
|
||||||
|
fieldDecoratorId="note"
|
||||||
|
:fieldDecoratorOptions="{rules: [{ required: true, message: 'Please input your note!' }]}"
|
||||||
|
>
|
||||||
|
<a-input />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
label='Gender'
|
||||||
|
:labelCol="{ span: 5 }"
|
||||||
|
:wrapperCol="{ span: 12 }"
|
||||||
|
fieldDecoratorId="gender"
|
||||||
|
:fieldDecoratorOptions="{rules: [{ required: true, message: 'Please select your gender!' }]}"
|
||||||
|
>
|
||||||
|
<a-select
|
||||||
|
placeholder='Select a option and change input text above'
|
||||||
|
@change="this.handleSelectChange"
|
||||||
|
>
|
||||||
|
<a-select-option value='male'>male</a-select-option>
|
||||||
|
<a-select-option value='female'>female</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
:wrapperCol="{ span: 12, offset: 5 }"
|
||||||
|
>
|
||||||
|
<a-button type='primary' htmlType='submit'>
|
||||||
|
Submit
|
||||||
|
</a-button>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
const CoordinatedForm = {
|
<script>
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
formLayout: 'horizontal',
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleSubmit (e) {
|
handleSubmit (e) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
@ -29,54 +68,10 @@ const CoordinatedForm = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
render () {
|
|
||||||
const { getFieldDecorator } = this.form
|
|
||||||
return (
|
|
||||||
<a-form onSubmit={this.handleSubmit}>
|
|
||||||
<a-form-item
|
|
||||||
label='Note'
|
|
||||||
labelCol={{ span: 5 }}
|
|
||||||
wrapperCol={{ span: 12 }}
|
|
||||||
>
|
|
||||||
{getFieldDecorator('note', {
|
|
||||||
rules: [{ required: true, message: 'Please input your note!' }],
|
|
||||||
})(
|
|
||||||
<a-input />
|
|
||||||
)}
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item
|
|
||||||
label='Gender'
|
|
||||||
labelCol={{ span: 5 }}
|
|
||||||
wrapperCol={{ span: 12 }}
|
|
||||||
>
|
|
||||||
{getFieldDecorator('gender', {
|
|
||||||
rules: [{ required: true, message: 'Please select your gender!' }],
|
|
||||||
})(
|
|
||||||
<a-select
|
|
||||||
placeholder='Select a option and change input text above'
|
|
||||||
onChange={this.handleSelectChange}
|
|
||||||
>
|
|
||||||
<a-select-option value='male'>male</a-select-option>
|
|
||||||
<a-select-option value='female'>female</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
)}
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item
|
|
||||||
wrapperCol={{ span: 12, offset: 5 }}
|
|
||||||
>
|
|
||||||
<a-button type='primary' htmlType='submit'>
|
|
||||||
Submit
|
|
||||||
</a-button>
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Form.create()(CoordinatedForm)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,47 @@ Perform different check rules according to different situations.
|
||||||
</us>
|
</us>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<template>
|
||||||
import { Form } from 'vue-antd-ui'
|
<a-form :autoFormCreate="(form)=>{this.form = form}">
|
||||||
|
<a-form-item
|
||||||
|
:labelCol="formItemLayout.labelCol"
|
||||||
|
:wrapperCol="formItemLayout.wrapperCol"
|
||||||
|
label='Name'
|
||||||
|
fieldDecoratorId="username"
|
||||||
|
:fieldDecoratorOptions="{rules: [{ required: true, message: 'Please input your name' }]}"
|
||||||
|
>
|
||||||
|
<a-input placeholder='Please input your name' />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
:labelCol="formItemLayout.labelCol"
|
||||||
|
:wrapperCol="formItemLayout.wrapperCol"
|
||||||
|
label='Nickname'
|
||||||
|
fieldDecoratorId="nickname"
|
||||||
|
:fieldDecoratorOptions="{rules: [{ required: checkNick, message: 'Please input your nickname' }]}"
|
||||||
|
>
|
||||||
|
<a-input placeholder='Please input your nickname' />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
:labelCol="formTailLayout.labelCol"
|
||||||
|
:wrapperCol="formTailLayout.wrapperCol"
|
||||||
|
>
|
||||||
|
<a-checkbox
|
||||||
|
:checked="checkNick"
|
||||||
|
@change="handleChange"
|
||||||
|
>
|
||||||
|
Nickname is required
|
||||||
|
</a-checkbox>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
:labelCol="formTailLayout.labelCol"
|
||||||
|
:wrapperCol="formTailLayout.wrapperCol"
|
||||||
|
>
|
||||||
|
<a-button type='primary' @click="check">Check</a-button>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
const formItemLayout = {
|
const formItemLayout = {
|
||||||
labelCol: { span: 4 },
|
labelCol: { span: 4 },
|
||||||
wrapperCol: { span: 8 },
|
wrapperCol: { span: 8 },
|
||||||
|
@ -20,10 +58,12 @@ const formTailLayout = {
|
||||||
labelCol: { span: 4 },
|
labelCol: { span: 4 },
|
||||||
wrapperCol: { span: 8, offset: 4 },
|
wrapperCol: { span: 8, offset: 4 },
|
||||||
}
|
}
|
||||||
const DynamicRule = {
|
export default {
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
checkNick: false,
|
checkNick: false,
|
||||||
|
formItemLayout,
|
||||||
|
formTailLayout,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -43,52 +83,10 @@ const DynamicRule = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
render () {
|
|
||||||
const { getFieldDecorator } = this.form
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<a-form-item {...{ props: formItemLayout }} label='Name'>
|
|
||||||
{getFieldDecorator('username', {
|
|
||||||
rules: [{
|
|
||||||
required: true,
|
|
||||||
message: 'Please input your name',
|
|
||||||
}],
|
|
||||||
})(
|
|
||||||
<a-input placeholder='Please input your name' />
|
|
||||||
)}
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item {...{ props: formItemLayout }} label='Nickname'>
|
|
||||||
{getFieldDecorator('nickname', {
|
|
||||||
rules: [{
|
|
||||||
required: this.checkNick,
|
|
||||||
message: 'Please input your nickname',
|
|
||||||
}],
|
|
||||||
})(
|
|
||||||
<a-input placeholder='Please input your nickname' />
|
|
||||||
)}
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item {...{ props: formTailLayout }}>
|
|
||||||
<a-checkbox
|
|
||||||
value={this.checkNick}
|
|
||||||
onChange={this.handleChange}
|
|
||||||
>
|
|
||||||
Nickname is required
|
|
||||||
</a-checkbox>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item {...{ props: formTailLayout }}>
|
|
||||||
<a-button type='primary' onClick={this.check}>
|
|
||||||
Check
|
|
||||||
</a-button>
|
|
||||||
</a-form-item>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Form.create()(DynamicRule)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,19 +9,70 @@ Horizontal login form is often used in navigation bar.
|
||||||
</us>
|
</us>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<template>
|
||||||
import { Form } from 'vue-antd-ui'
|
<a-form layout='inline' @submit="handleSubmit" :autoFormCreate="(form)=>{this.form = form}">
|
||||||
|
<template v-if="form">
|
||||||
|
<a-form-item
|
||||||
|
:validateStatus="userNameError() ? 'error' : ''"
|
||||||
|
:help="userNameError() || ''"
|
||||||
|
fieldDecoratorId="userName"
|
||||||
|
:fieldDecoratorOptions="{rules: [{ required: true, message: 'Please input your username!' }]}"
|
||||||
|
>
|
||||||
|
<a-input placeholder='Username'>
|
||||||
|
<a-icon slot="prefix" type='user' style="color:rgba(0,0,0,.25)"/>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
:validateStatus="passwordError() ? 'error' : ''"
|
||||||
|
:help="passwordError() || ''"
|
||||||
|
fieldDecoratorId="password"
|
||||||
|
:fieldDecoratorOptions="{rules: [{ required: true, message: 'Please input your Password!' }]}"
|
||||||
|
>
|
||||||
|
<a-input type='password' placeholder='Password'>
|
||||||
|
<a-icon slot="prefix" type='lock' style="color:rgba(0,0,0,.25)"/>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item>
|
||||||
|
<a-button
|
||||||
|
type='primary'
|
||||||
|
htmlType='submit'
|
||||||
|
:disabled="hasErrors(form.getFieldsError())"
|
||||||
|
>
|
||||||
|
Log in
|
||||||
|
</a-button>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
</a-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
function hasErrors (fieldsError) {
|
function hasErrors (fieldsError) {
|
||||||
return Object.keys(fieldsError).some(field => fieldsError[field])
|
return Object.keys(fieldsError).some(field => fieldsError[field])
|
||||||
}
|
}
|
||||||
|
export default {
|
||||||
const HorizontalLoginForm = {
|
data () {
|
||||||
|
return {
|
||||||
|
hasErrors,
|
||||||
|
form: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
this.$nextTick(() => {
|
||||||
// To disabled submit button at the beginning.
|
// To disabled submit button at the beginning.
|
||||||
this.form.validateFields()
|
this.form.validateFields()
|
||||||
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// Only show error after a field is touched.
|
||||||
|
userNameError () {
|
||||||
|
const { getFieldError, isFieldTouched } = this.form
|
||||||
|
return isFieldTouched('userName') && getFieldError('userName')
|
||||||
|
},
|
||||||
|
// Only show error after a field is touched.
|
||||||
|
passwordError () {
|
||||||
|
const { getFieldError, isFieldTouched } = this.form
|
||||||
|
return isFieldTouched('password') && getFieldError('password')
|
||||||
|
},
|
||||||
handleSubmit (e) {
|
handleSubmit (e) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
this.form.validateFields((err, values) => {
|
this.form.validateFields((err, values) => {
|
||||||
|
@ -31,52 +82,10 @@ const HorizontalLoginForm = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
render () {
|
|
||||||
const { getFieldDecorator, getFieldsError, getFieldError, isFieldTouched } = this.form
|
|
||||||
|
|
||||||
// Only show error after a field is touched.
|
|
||||||
const userNameError = isFieldTouched('userName') && getFieldError('userName')
|
|
||||||
const passwordError = isFieldTouched('password') && getFieldError('password')
|
|
||||||
return (
|
|
||||||
<a-form layout='inline' onSubmit={this.handleSubmit}>
|
|
||||||
<a-form-item
|
|
||||||
validateStatus={userNameError ? 'error' : ''}
|
|
||||||
help={userNameError || ''}
|
|
||||||
>
|
|
||||||
{getFieldDecorator('userName', {
|
|
||||||
rules: [{ required: true, message: 'Please input your username!' }],
|
|
||||||
})(
|
|
||||||
<a-input prefix={<a-icon type='user' style={{ color: 'rgba(0,0,0,.25)' }} />} placeholder='Username' />
|
|
||||||
)}
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item
|
|
||||||
validateStatus={passwordError ? 'error' : ''}
|
|
||||||
help={passwordError || ''}
|
|
||||||
>
|
|
||||||
{getFieldDecorator('password', {
|
|
||||||
rules: [{ required: true, message: 'Please input your Password!' }],
|
|
||||||
})(
|
|
||||||
<a-input prefix={<a-icon type='lock' style={{ color: 'rgba(0,0,0,.25)' }} />} type='password' placeholder='Password' />
|
|
||||||
)}
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item>
|
|
||||||
<a-button
|
|
||||||
type='primary'
|
|
||||||
htmlType='submit'
|
|
||||||
disabled={hasErrors(getFieldsError())}
|
|
||||||
>
|
|
||||||
Log in
|
|
||||||
</a-button>
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Form.create()(HorizontalLoginForm)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -85,33 +85,40 @@ export default {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<md cn={md.cn} us={md.us} />
|
<md cn={md.cn} us={md.us} />
|
||||||
<demo-container code={AdvancedSearchString}>
|
|
||||||
<AdvancedSearch />
|
|
||||||
</demo-container>
|
|
||||||
<demo-container code={CoordinatedString}>
|
<demo-container code={CoordinatedString}>
|
||||||
<Coordinated />
|
<Coordinated />
|
||||||
</demo-container>
|
</demo-container>
|
||||||
|
<demo-container code={DynamicRuleString}>
|
||||||
|
<DynamicRule />
|
||||||
|
</demo-container>
|
||||||
|
<demo-container code={HorizontalLoginString}>
|
||||||
|
<HorizontalLogin />
|
||||||
|
</demo-container>
|
||||||
|
<demo-container code={LayoutString}>
|
||||||
|
<Layout />
|
||||||
|
</demo-container>
|
||||||
|
<demo-container code={ValidateStaticString}>
|
||||||
|
<ValidateStatic />
|
||||||
|
</demo-container>
|
||||||
|
<demo-container code={WithoutFormCreateString}>
|
||||||
|
<WithoutFormCreate />
|
||||||
|
</demo-container>
|
||||||
|
|
||||||
|
<demo-container code={AdvancedSearchString}>
|
||||||
|
<AdvancedSearch />
|
||||||
|
</demo-container>
|
||||||
<demo-container code={CustomizedFormControlsString}>
|
<demo-container code={CustomizedFormControlsString}>
|
||||||
<CustomizedFormControls />
|
<CustomizedFormControls />
|
||||||
</demo-container>
|
</demo-container>
|
||||||
<demo-container code={DynamicFormItemString}>
|
<demo-container code={DynamicFormItemString}>
|
||||||
<DynamicFormItem />
|
<DynamicFormItem />
|
||||||
</demo-container>
|
</demo-container>
|
||||||
<demo-container code={DynamicRuleString}>
|
|
||||||
<DynamicRule />
|
|
||||||
</demo-container>
|
|
||||||
<demo-container code={FormInModalString}>
|
<demo-container code={FormInModalString}>
|
||||||
<FormInModal />
|
<FormInModal />
|
||||||
</demo-container>
|
</demo-container>
|
||||||
<demo-container code={GlobalStateString}>
|
<demo-container code={GlobalStateString}>
|
||||||
<GlobalState />
|
<GlobalState />
|
||||||
</demo-container>
|
</demo-container>
|
||||||
<demo-container code={HorizontalLoginString}>
|
|
||||||
<HorizontalLogin />
|
|
||||||
</demo-container>
|
|
||||||
<demo-container code={LayoutString}>
|
|
||||||
<Layout />
|
|
||||||
</demo-container>
|
|
||||||
<demo-container code={NormalLoginString}>
|
<demo-container code={NormalLoginString}>
|
||||||
<NormalLogin />
|
<NormalLogin />
|
||||||
</demo-container>
|
</demo-container>
|
||||||
|
@ -121,12 +128,6 @@ export default {
|
||||||
<demo-container code={TimeRelatedControlsString}>
|
<demo-container code={TimeRelatedControlsString}>
|
||||||
<TimeRelatedControls />
|
<TimeRelatedControls />
|
||||||
</demo-container>
|
</demo-container>
|
||||||
<demo-container code={ValidateStaticString}>
|
|
||||||
<ValidateStatic />
|
|
||||||
</demo-container>
|
|
||||||
<demo-container code={WithoutFormCreateString}>
|
|
||||||
<WithoutFormCreate />
|
|
||||||
</demo-container>
|
|
||||||
<demo-container code={ValidateOtherString}>
|
<demo-container code={ValidateOtherString}>
|
||||||
<ValidateOther />
|
<ValidateOther />
|
||||||
</demo-container>
|
</demo-container>
|
||||||
|
|
|
@ -14,12 +14,31 @@
|
||||||
| form | Decorated by `Form.create()` will be automatically set `this.form` property, so just pass to form, you don't need to set it by yourself after 1.7.0. | object | n/a |
|
| form | Decorated by `Form.create()` will be automatically set `this.form` property, so just pass to form, you don't need to set it by yourself after 1.7.0. | object | n/a |
|
||||||
| hideRequiredMark | Hide required mark of all form items | Boolean | false |
|
| hideRequiredMark | Hide required mark of all form items | Boolean | false |
|
||||||
| layout | Define form layout(Support after 2.8) | 'horizontal'\|'vertical'\|'inline' | 'horizontal' |
|
| layout | Define form layout(Support after 2.8) | 'horizontal'\|'vertical'\|'inline' | 'horizontal' |
|
||||||
|
| autoFormCreate | Automate Form.create, Recommended for use under the `template` component, and cannot be used with `Form.create()` |Function(form)| |
|
||||||
|
| options | The `options` corresponding to `Form.create(options)` | Object | {} |
|
||||||
|
|
||||||
### Events
|
### Events
|
||||||
| Events Name | Description | Arguments |
|
| Events Name | Description | Arguments |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| submit | Defines a function will be called if form data validation is successful. | Function(e:Event) |
|
| submit | Defines a function will be called if form data validation is successful. | Function(e:Event) |
|
||||||
|
|
||||||
|
### autoFormCreate
|
||||||
|
|
||||||
|
````html
|
||||||
|
<a-form :autoFormCreate="(form)=>{this.form = form}">
|
||||||
|
...
|
||||||
|
</a-form>
|
||||||
|
````
|
||||||
|
If you use the `template` syntax, you can use ʻautoFormCreate` to turn on automatic validation and data collection, but each `Form.Item` only to `decorator` for its first child. More complex features suggest `JSX`.
|
||||||
|
|
||||||
|
Related examples are as follows:
|
||||||
|
|
||||||
|
[coordinated-controls](/ant-design/components/form/#components-form-demo-coordinated-controls)
|
||||||
|
|
||||||
|
[dynamic-rules](/ant-design/components/form/#components-form-demo-dynamic-rules)
|
||||||
|
|
||||||
|
[horizontal-login-form](/ant-design/components/form/#components-form-demo-horizontal-login-form)
|
||||||
|
|
||||||
### Form.create(options)
|
### Form.create(options)
|
||||||
|
|
||||||
How to use:
|
How to use:
|
||||||
|
@ -124,6 +143,8 @@ Note:
|
||||||
| required | Whether provided or not, it will be generated by the validation rule. | boolean | false |
|
| required | Whether provided or not, it will be generated by the validation rule. | boolean | false |
|
||||||
| validateStatus | The validation status. If not provided, it will be generated by validation rule. options: 'success' 'warning' 'error' 'validating' | string | |
|
| validateStatus | The validation status. If not provided, it will be generated by validation rule. options: 'success' 'warning' 'error' 'validating' | string | |
|
||||||
| wrapperCol | The layout for input controls, same as `labelCol` | [object](/ant-design/components/grid/#Col) | |
|
| wrapperCol | The layout for input controls, same as `labelCol` | [object](/ant-design/components/grid/#Col) | |
|
||||||
|
| fieldDecoratorId | Corresponds to the first parameter `id` of `getFieldDecorator(id, options)`. If you need to collect data, you need to set this field. | string | |
|
||||||
|
| fieldDecoratorOptions | Corresponds to the second parameter `options` of `getFieldDecorator(id, options)`. | object | {} |
|
||||||
|
|
||||||
### Validation Rules
|
### Validation Rules
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,31 @@
|
||||||
| form | 经 `Form.create()` 包装过的组件会自带 `this.form` 属性,直接传给 Form 即可。无需手动设置 | object | 无 |
|
| form | 经 `Form.create()` 包装过的组件会自带 `this.form` 属性,直接传给 Form 即可。无需手动设置 | object | 无 |
|
||||||
| hideRequiredMark | 隐藏所有表单项的必选标记 | Boolean | false |
|
| hideRequiredMark | 隐藏所有表单项的必选标记 | Boolean | false |
|
||||||
| layout | 表单布局 | 'horizontal'\|'vertical'\|'inline' | 'horizontal' |
|
| layout | 表单布局 | 'horizontal'\|'vertical'\|'inline' | 'horizontal' |
|
||||||
|
| autoFormCreate | 自动执行Form.create,建议在template组件下使用,并且不可以和`Form.create()`同时使用 |Function(form)| 无|
|
||||||
|
| options | 对应Form.create(options)的`options` | Object | {} |
|
||||||
|
|
||||||
### 事件
|
### 事件
|
||||||
| 事件名称 | 说明 | 回调参数 |
|
| 事件名称 | 说明 | 回调参数 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| submit | 数据验证成功后回调事件 | Function(e:Event) |
|
| submit | 数据验证成功后回调事件 | Function(e:Event) |
|
||||||
|
|
||||||
|
### autoFormCreate
|
||||||
|
|
||||||
|
````html
|
||||||
|
<a-form :autoFormCreate="(form)=>{this.form = form}">
|
||||||
|
...
|
||||||
|
</a-form>
|
||||||
|
````
|
||||||
|
如果使用`template`语法,可以使用`autoFormCreate`开启自动校验和数据收集功能,但每一个`Form.Item`仅仅对其第一个子组件进行`decorator`。更加复杂的功能建议使用`JSX`。
|
||||||
|
|
||||||
|
相关示例如下:
|
||||||
|
|
||||||
|
[coordinated-controls](/ant-design/components/form-cn/#components-form-demo-coordinated-controls)
|
||||||
|
|
||||||
|
[dynamic-rules](/ant-design/components/form-cn/#components-form-demo-dynamic-rules)
|
||||||
|
|
||||||
|
[horizontal-login-form](/ant-design/components/form-cn/#components-form-demo-horizontal-login-form)
|
||||||
|
|
||||||
### Form.create(options)
|
### Form.create(options)
|
||||||
|
|
||||||
使用方式如下:
|
使用方式如下:
|
||||||
|
@ -123,6 +142,8 @@ CustomizedForm = Form.create({})(CustomizedForm);
|
||||||
| required | 是否必填,如不设置,则会根据校验规则自动生成 | boolean | false |
|
| required | 是否必填,如不设置,则会根据校验规则自动生成 | boolean | false |
|
||||||
| validateStatus | 校验状态,如不设置,则会根据校验规则自动生成,可选:'success' 'warning' 'error' 'validating' | string | |
|
| validateStatus | 校验状态,如不设置,则会根据校验规则自动生成,可选:'success' 'warning' 'error' 'validating' | string | |
|
||||||
| wrapperCol | 需要为输入控件设置布局样式时,使用该属性,用法同 labelCol | [object](/ant-design/components/grid-cn/#Col) | |
|
| wrapperCol | 需要为输入控件设置布局样式时,使用该属性,用法同 labelCol | [object](/ant-design/components/grid-cn/#Col) | |
|
||||||
|
| fieldDecoratorId | 对应`getFieldDecorator(id, options)`的第一个参数`id`,如需收集数据需要设置该字段 | string | 无 |
|
||||||
|
| fieldDecoratorOptions | 对应`getFieldDecorator(id, options)`的第二个参数`options` | object | {} |
|
||||||
|
|
||||||
### 校验规则
|
### 校验规则
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ function createBaseForm (option = {}, mixins = []) {
|
||||||
fieldDataProp,
|
fieldDataProp,
|
||||||
formPropName = 'form',
|
formPropName = 'form',
|
||||||
props = {},
|
props = {},
|
||||||
|
templateContext,
|
||||||
} = option
|
} = option
|
||||||
|
|
||||||
return function decorate (WrappedComponent) {
|
return function decorate (WrappedComponent) {
|
||||||
|
@ -177,7 +178,7 @@ function createBaseForm (option = {}, mixins = []) {
|
||||||
warning(
|
warning(
|
||||||
!(valuePropName in originalProps),
|
!(valuePropName in originalProps),
|
||||||
`\`getFieldDecorator\` will override \`${valuePropName}\`, ` +
|
`\`getFieldDecorator\` will override \`${valuePropName}\`, ` +
|
||||||
`so please don't set \`${valuePropName}\` directly ` +
|
`so please don't set \`${valuePropName} and v-model\` directly ` +
|
||||||
`and use \`setFieldsValue\` to set it.`
|
`and use \`setFieldsValue\` to set it.`
|
||||||
)
|
)
|
||||||
const defaultValuePropName =
|
const defaultValuePropName =
|
||||||
|
@ -327,7 +328,11 @@ function createBaseForm (option = {}, mixins = []) {
|
||||||
.reduce((acc, name) => set(acc, name, this.fieldsStore.getField(name)), {})
|
.reduce((acc, name) => set(acc, name, this.fieldsStore.getField(name)), {})
|
||||||
onFieldsChange(this, changedFields, this.fieldsStore.getNestedAllFields())
|
onFieldsChange(this, changedFields, this.fieldsStore.getNestedAllFields())
|
||||||
}
|
}
|
||||||
|
if (templateContext) {
|
||||||
|
templateContext.$forceUpdate()
|
||||||
|
} else {
|
||||||
this.$forceUpdate()
|
this.$forceUpdate()
|
||||||
|
}
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
callback && callback()
|
callback && callback()
|
||||||
})
|
})
|
||||||
|
|
|
@ -10,7 +10,7 @@ import Api from './components/api'
|
||||||
import './components'
|
import './components'
|
||||||
import demoBox from './components/demoBox'
|
import demoBox from './components/demoBox'
|
||||||
import demoContainer from './components/demoContainer'
|
import demoContainer from './components/demoContainer'
|
||||||
import Test from '../components/list/demo/test'
|
import Test from '../components/form/demo/index'
|
||||||
|
|
||||||
Vue.use(VueClipboard)
|
Vue.use(VueClipboard)
|
||||||
Vue.use(VueRouter)
|
Vue.use(VueRouter)
|
||||||
|
|
Loading…
Reference in New Issue