Skip to content

Commit fdce1ce

Browse files
committed
feat: update form
1 parent 868ee1e commit fdce1ce

File tree

12 files changed

+148
-176
lines changed

12 files changed

+148
-176
lines changed

components/form/Form.jsx

+2-5
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,6 @@ export default {
173173
[`${prefixCls}-hide-required-mark`]: hideRequiredMark,
174174
})
175175
if (autoFormCreate) {
176-
const saveFormRef = (ref) => {
177-
this.domForm = ref
178-
}
179176
const DomForm = this.DomForm || createDOMForm({
180177
fieldNameProp: 'id',
181178
...options,
@@ -195,7 +192,7 @@ export default {
195192
submit: onSubmit,
196193
}
197194
},
198-
mounted () {
195+
created () {
199196
autoFormCreate(this.form)
200197
},
201198
render () {
@@ -210,7 +207,7 @@ export default {
210207
}
211208
this.DomForm = DomForm
212209

213-
return <DomForm wrappedComponentRef={(inst) => saveFormRef(inst)}/>
210+
return <DomForm wrappedComponentRef={(inst) => { this.domForm = inst }}/>
214211
}
215212

216213
return <form onSubmit={onSubmit} class={formClassName}>{$slots.default}</form>

components/form/FormItem.jsx

+6-14
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Row from '../grid/Row'
55
import Col, { ColProps } from '../grid/Col'
66
import warning from '../_util/warning'
77
import { FIELD_META_PROP, FIELD_DATA_PROP } from './constants'
8-
import { initDefaultProps, getComponentFromProp, filterEmpty, getSlotOptions, getSlots, isEmptyElement } from '../_util/props-util'
8+
import { initDefaultProps, getComponentFromProp, filterEmpty, getSlotOptions, getSlots } from '../_util/props-util'
99
import getTransitionProps from '../_util/getTransitionProps'
1010
import BaseMixin from '../_util/BaseMixin'
1111
export const FormItemProps = {
@@ -47,10 +47,6 @@ export default {
4747
'while there are more than one `getFieldDecorator` in it.',
4848
)
4949
},
50-
51-
// shouldComponentUpdate(...args: any[]) {
52-
// return PureRenderMixin.shouldComponentUpdate.apply(this, args);
53-
// }
5450
methods: {
5551
getHelpMsg () {
5652
const help = getComponentFromProp(this, 'help')
@@ -306,15 +302,6 @@ export default {
306302
) : null
307303
},
308304
renderChildren () {
309-
// const { $slots, FormProps, decoratorFormProps, prop } = this
310-
// const child = filterEmpty($slots.default || [])
311-
// if (decoratorFormProps.form && prop && child.length) {
312-
// const getFieldDecorator = decoratorFormProps.form.getFieldDecorator
313-
// const rules = FormProps.rules[prop] || []
314-
// child[0] = getFieldDecorator(prop, {
315-
// rules,
316-
// })(child[0])
317-
// }
318305
return [
319306
this.renderLabel(),
320307
this.renderWrapper(
@@ -349,7 +336,12 @@ export default {
349336
if (decoratorFormProps.form && fieldDecoratorId && child.length) {
350337
const getFieldDecorator = decoratorFormProps.form.getFieldDecorator
351338
child[0] = getFieldDecorator(fieldDecoratorId, fieldDecoratorOptions)(child[0])
339+
warning(
340+
!(child.length > 1),
341+
'`autoFormCreate` just `decorator` then first children. but you can use JSX to support multiple children',
342+
)
352343
}
344+
353345
this.slotDefault = child
354346
const children = this.renderChildren()
355347
return this.renderFormItem(children)

components/form/__tests__/__snapshots__/demo.test.js.snap

+6-4
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ exports[`renders ./components/form/demo/dynamic-form-item.vue correctly 1`] = `
221221
`;
222222
223223
exports[`renders ./components/form/demo/dynamic-rule.vue correctly 1`] = `
224-
<div>
224+
<form class="ant-form ant-form-horizontal">
225225
<div class="ant-row ant-form-item">
226226
<div class="ant-col-4 ant-form-item-label">
227227
<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`] = `
244244
</div>
245245
<div class="ant-row ant-form-item">
246246
<div class="ant-col-8 ant-col-offset-4 ant-form-item-control-wrapper">
247-
<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>
247+
<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>
248+
Nickname is required
249+
</span></label>
248250
</span>
249251
<!---->
250252
</div>
@@ -258,7 +260,7 @@ exports[`renders ./components/form/demo/dynamic-rule.vue correctly 1`] = `
258260
</div>
259261
</div>
260262
</div>
261-
</div>
263+
</form>
262264
`;
263265
264266
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`] = `
314316
</div>
315317
<div class="ant-row ant-form-item">
316318
<div class="ant-form-item-control-wrapper">
317-
<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>
319+
<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>
318320
</span>
319321
<!---->
320322
</div>

components/form/demo/advanced-search.vue

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Because the width of label is not fixed, you may need to adjust it by customizin
1313

1414
<script>
1515
import { Form } from 'vue-antd-ui'
16+
import { setTimeout } from 'timers'
1617
1718
const AdvancedSearchForm = {
1819
data () {

components/form/demo/dynamic-rule.vue

+12-4
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,38 @@ Perform different check rules according to different situations.
1212
<template>
1313
<a-form :autoFormCreate="(form)=>{this.form = form}">
1414
<a-form-item
15-
:formItemLayout="formItemLayout"
15+
:labelCol="formItemLayout.labelCol"
16+
:wrapperCol="formItemLayout.wrapperCol"
1617
label='Name'
1718
fieldDecoratorId="username"
1819
:fieldDecoratorOptions="{rules: [{ required: true, message: 'Please input your name' }]}"
1920
>
2021
<a-input placeholder='Please input your name' />
2122
</a-form-item>
2223
<a-form-item
23-
:formItemLayout="formItemLayout"
24+
:labelCol="formItemLayout.labelCol"
25+
:wrapperCol="formItemLayout.wrapperCol"
2426
label='Nickname'
2527
fieldDecoratorId="nickname"
2628
:fieldDecoratorOptions="{rules: [{ required: checkNick, message: 'Please input your nickname' }]}"
2729
>
2830
<a-input placeholder='Please input your nickname' />
2931
</a-form-item>
30-
<a-form-item :formTailLayout="formTailLayout">
32+
<a-form-item
33+
:labelCol="formTailLayout.labelCol"
34+
:wrapperCol="formTailLayout.wrapperCol"
35+
>
3136
<a-checkbox
3237
:checked="checkNick"
3338
@change="handleChange"
3439
>
3540
Nickname is required
3641
</a-checkbox>
3742
</a-form-item>
38-
<a-form-item :formTailLayout="formTailLayout">
43+
<a-form-item
44+
:labelCol="formTailLayout.labelCol"
45+
:wrapperCol="formTailLayout.wrapperCol"
46+
>
3947
<a-button type='primary' @click="check">Check</a-button>
4048
</a-form-item>
4149
</a-form>

components/form/demo/horizontal-login.vue

+58-49
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,70 @@ Horizontal login form is often used in navigation bar.
99
</us>
1010

1111

12-
<script>
13-
import { Form } from 'vue-antd-ui'
12+
<template>
13+
<a-form layout='inline' @submit="handleSubmit" :autoFormCreate="(form)=>{this.form = form}">
14+
<template v-if="form">
15+
<a-form-item
16+
:validateStatus="userNameError() ? 'error' : ''"
17+
:help="userNameError() || ''"
18+
fieldDecoratorId="userName"
19+
:fieldDecoratorOptions="{rules: [{ required: true, message: 'Please input your username!' }]}"
20+
>
21+
<a-input placeholder='Username'>
22+
<a-icon slot="prefix" type='user' style="color:rgba(0,0,0,.25)"/>
23+
</a-input>
24+
</a-form-item>
25+
<a-form-item
26+
:validateStatus="passwordError() ? 'error' : ''"
27+
:help="passwordError() || ''"
28+
fieldDecoratorId="password"
29+
:fieldDecoratorOptions="{rules: [{ required: true, message: 'Please input your Password!' }]}"
30+
>
31+
<a-input type='password' placeholder='Password'>
32+
<a-icon slot="prefix" type='lock' style="color:rgba(0,0,0,.25)"/>
33+
</a-input>
34+
</a-form-item>
35+
<a-form-item>
36+
<a-button
37+
type='primary'
38+
htmlType='submit'
39+
:disabled="hasErrors(form.getFieldsError())"
40+
>
41+
Log in
42+
</a-button>
43+
</a-form-item>
44+
</template>
45+
</a-form>
46+
</template>
1447

48+
<script>
1549
function hasErrors (fieldsError) {
1650
return Object.keys(fieldsError).some(field => fieldsError[field])
1751
}
18-
19-
const HorizontalLoginForm = {
52+
export default {
53+
data () {
54+
return {
55+
hasErrors,
56+
form: null,
57+
}
58+
},
2059
mounted () {
21-
// To disabled submit button at the beginning.
22-
this.form.validateFields()
60+
this.$nextTick(() => {
61+
// To disabled submit button at the beginning.
62+
this.form.validateFields()
63+
})
2364
},
2465
methods: {
66+
// Only show error after a field is touched.
67+
userNameError () {
68+
const { getFieldError, isFieldTouched } = this.form
69+
return isFieldTouched('userName') && getFieldError('userName')
70+
},
71+
// Only show error after a field is touched.
72+
passwordError () {
73+
const { getFieldError, isFieldTouched } = this.form
74+
return isFieldTouched('password') && getFieldError('password')
75+
},
2576
handleSubmit (e) {
2677
e.preventDefault()
2778
this.form.validateFields((err, values) => {
@@ -31,52 +82,10 @@ const HorizontalLoginForm = {
3182
})
3283
},
3384
},
34-
35-
render () {
36-
const { getFieldDecorator, getFieldsError, getFieldError, isFieldTouched } = this.form
37-
38-
// Only show error after a field is touched.
39-
const userNameError = isFieldTouched('userName') && getFieldError('userName')
40-
const passwordError = isFieldTouched('password') && getFieldError('password')
41-
return (
42-
<a-form layout='inline' onSubmit={this.handleSubmit}>
43-
<a-form-item
44-
validateStatus={userNameError ? 'error' : ''}
45-
help={userNameError || ''}
46-
>
47-
{getFieldDecorator('userName', {
48-
rules: [{ required: true, message: 'Please input your username!' }],
49-
})(
50-
<a-input prefix={<a-icon type='user' style={{ color: 'rgba(0,0,0,.25)' }} />} placeholder='Username' />
51-
)}
52-
</a-form-item>
53-
<a-form-item
54-
validateStatus={passwordError ? 'error' : ''}
55-
help={passwordError || ''}
56-
>
57-
{getFieldDecorator('password', {
58-
rules: [{ required: true, message: 'Please input your Password!' }],
59-
})(
60-
<a-input prefix={<a-icon type='lock' style={{ color: 'rgba(0,0,0,.25)' }} />} type='password' placeholder='Password' />
61-
)}
62-
</a-form-item>
63-
<a-form-item>
64-
<a-button
65-
type='primary'
66-
htmlType='submit'
67-
disabled={hasErrors(getFieldsError())}
68-
>
69-
Log in
70-
</a-button>
71-
</a-form-item>
72-
</a-form>
73-
)
74-
},
7585
}
76-
77-
export default Form.create()(HorizontalLoginForm)
7886
</script>
7987

8088

8189

8290

91+

components/form/demo/index.vue

+19-18
Original file line numberDiff line numberDiff line change
@@ -85,33 +85,40 @@ export default {
8585
return (
8686
<div>
8787
<md cn={md.cn} us={md.us} />
88-
<demo-container code={AdvancedSearchString}>
89-
<AdvancedSearch />
90-
</demo-container>
9188
<demo-container code={CoordinatedString}>
9289
<Coordinated />
9390
</demo-container>
91+
<demo-container code={DynamicRuleString}>
92+
<DynamicRule />
93+
</demo-container>
94+
<demo-container code={HorizontalLoginString}>
95+
<HorizontalLogin />
96+
</demo-container>
97+
<demo-container code={LayoutString}>
98+
<Layout />
99+
</demo-container>
100+
<demo-container code={ValidateStaticString}>
101+
<ValidateStatic />
102+
</demo-container>
103+
<demo-container code={WithoutFormCreateString}>
104+
<WithoutFormCreate />
105+
</demo-container>
106+
107+
<demo-container code={AdvancedSearchString}>
108+
<AdvancedSearch />
109+
</demo-container>
94110
<demo-container code={CustomizedFormControlsString}>
95111
<CustomizedFormControls />
96112
</demo-container>
97113
<demo-container code={DynamicFormItemString}>
98114
<DynamicFormItem />
99115
</demo-container>
100-
<demo-container code={DynamicRuleString}>
101-
<DynamicRule />
102-
</demo-container>
103116
<demo-container code={FormInModalString}>
104117
<FormInModal />
105118
</demo-container>
106119
<demo-container code={GlobalStateString}>
107120
<GlobalState />
108121
</demo-container>
109-
<demo-container code={HorizontalLoginString}>
110-
<HorizontalLogin />
111-
</demo-container>
112-
<demo-container code={LayoutString}>
113-
<Layout />
114-
</demo-container>
115122
<demo-container code={NormalLoginString}>
116123
<NormalLogin />
117124
</demo-container>
@@ -121,12 +128,6 @@ export default {
121128
<demo-container code={TimeRelatedControlsString}>
122129
<TimeRelatedControls />
123130
</demo-container>
124-
<demo-container code={ValidateStaticString}>
125-
<ValidateStatic />
126-
</demo-container>
127-
<demo-container code={WithoutFormCreateString}>
128-
<WithoutFormCreate />
129-
</demo-container>
130131
<demo-container code={ValidateOtherString}>
131132
<ValidateOther />
132133
</demo-container>

0 commit comments

Comments
 (0)