feat: add form demo

pull/22/head
tjz 2018-05-06 21:53:00 +08:00
parent d959c04a0c
commit 72b9d175ba
4 changed files with 773 additions and 59 deletions

View File

@ -0,0 +1,260 @@
<cn>
#### 注册新用户
用户填写必须的信息以注册新用户。
</cn>
<us>
#### Registration
Fill in this form to create a new account for you.
</us>
```html
<script>
import { Form } from 'vue-antd-ui'
const residences = [{
value: 'zhejiang',
label: 'Zhejiang',
children: [{
value: 'hangzhou',
label: 'Hangzhou',
children: [{
value: 'xihu',
label: 'West Lake',
}],
}],
}, {
value: 'jiangsu',
label: 'Jiangsu',
children: [{
value: 'nanjing',
label: 'Nanjing',
children: [{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
}],
}],
}]
const RegistrationForm = {
data () {
return {
confirmDirty: false,
autoCompleteResult: [],
}
},
methods: {
handleSubmit (e) {
e.preventDefault()
this.form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values)
}
})
},
handleConfirmBlur (e) {
const value = e.target.value
this.confirmDirty = this.confirmDirty || !!value
},
compareToFirstPassword (rule, value, callback) {
const form = this.form
if (value && value !== form.getFieldValue('password')) {
callback('Two passwords that you enter is inconsistent!')
} else {
callback()
}
},
validateToNextPassword (rule, value, callback) {
const form = this.form
if (value && this.confirmDirty) {
form.validateFields(['confirm'], { force: true })
}
callback()
},
handleWebsiteChange (value) {
let autoCompleteResult
if (!value) {
autoCompleteResult = []
} else {
autoCompleteResult = ['.com', '.org', '.net'].map(domain => `${value}${domain}`)
}
this.autoCompleteResult = autoCompleteResult
},
},
render () {
const { getFieldDecorator } = this.form
const { autoCompleteResult } = this
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 8 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
}
const tailFormItemLayout = {
wrapperCol: {
xs: {
span: 24,
offset: 0,
},
sm: {
span: 16,
offset: 8,
},
},
}
const prefixSelector = getFieldDecorator('prefix', {
initialValue: '86',
})(
<a-select style={{ width: '70px' }}>
<a-select-option value='86'>+86</a-select-option>
<a-select-option value='87'>+87</a-select-option>
</a-select>
)
const websiteOptions = autoCompleteResult.map(website => (
<a-select-option key={website}>{website}</a-select-option>
))
return (
<a-form onSubmit={this.handleSubmit}>
<a-form-item
{...{ props: formItemLayout }}
label='E-mail'
>
{getFieldDecorator('email', {
rules: [{
type: 'email', message: 'The input is not valid E-mail!',
}, {
required: true, message: 'Please input your E-mail!',
}],
})(
<a-input />
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Password'
>
{getFieldDecorator('password', {
rules: [{
required: true, message: 'Please input your password!',
}, {
validator: this.validateToNextPassword,
}],
})(
<a-input type='password' />
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Confirm Password'
>
{getFieldDecorator('confirm', {
rules: [{
required: true, message: 'Please confirm your password!',
}, {
validator: this.compareToFirstPassword,
}],
})(
<a-input type='password' onBlur={this.handleConfirmBlur} />
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label={(
<span>
Nickname&nbsp;
<a-tooltip title='What do you want others to call you?'>
<a-icon type='question-circle-o' />
</a-tooltip>
</span>
)}
>
{getFieldDecorator('nickname', {
rules: [{ required: true, message: 'Please input your nickname!', whitespace: true }],
})(
<a-input />
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Habitual Residence'
>
{getFieldDecorator('residence', {
initialValue: ['zhejiang', 'hangzhou', 'xihu'],
rules: [{ type: 'array', required: true, message: 'Please select your habitual residence!' }],
})(
<a-cascader options={residences} />
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Phone Number'
>
{getFieldDecorator('phone', {
rules: [{ required: true, message: 'Please input your phone number!' }],
})(
<a-input addonBefore={prefixSelector} style={{ width: '100%' }} />
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Website'
>
{getFieldDecorator('website', {
rules: [{ required: true, message: 'Please input website!' }],
})(
<a-auto-complete
dataSource={websiteOptions}
onChange={this.handleWebsiteChange}
placeholder='website'
>
<a-input />
</a-auto-complete>
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Captcha'
extra='We must make sure that your are a human.'
>
<a-row gutter={8}>
<a-col span={12}>
{getFieldDecorator('captcha', {
rules: [{ required: true, message: 'Please input the captcha you got!' }],
})(
<a-input />
)}
</a-col>
<a-col span={12}>
<a-button>Get captcha</a-button>
</a-col>
</a-row>
</a-form-item>
<a-form-item {...{ props: tailFormItemLayout }}>
{getFieldDecorator('agreement', {
valuePropName: 'checked',
})(
<a-checkbox>I have read the <a href=''>agreement</a></a-checkbox>
)}
</a-form-item>
<a-form-item {...{ props: tailFormItemLayout }}>
<a-button type='primary' htmlType='submit'>Register</a-button>
</a-form-item>
</a-form>
)
},
}
export default Form.create()(RegistrationForm)
</script>
```

View File

@ -1,67 +1,185 @@
<template>
<div>
<a-form :layout="formLayout">
<a-form-item
label='Form Layout'
:labelCol="formItemLayout.labelCol"
:wrapperCol="formItemLayout.wrapperCol"
>
<a-radio-group defaultValue='horizontal' @change="handleFormLayoutChange">
<a-radio-button value='horizontal'>Horizontal</a-radio-button>
<a-radio-button value='vertical'>Vertical</a-radio-button>
<a-radio-button value='inline'>Inline</a-radio-button>
</a-radio-group>
</a-form-item>
<a-form-item
label='Field A'
:labelCol="formItemLayout.labelCol"
:wrapperCol="formItemLayout.wrapperCol"
>
<a-input placeholder='input placeholder' />
</a-form-item>
<a-form-item
label='Field B'
:labelCol="formItemLayout.labelCol"
:wrapperCol="formItemLayout.wrapperCol"
>
<a-input placeholder='input placeholder' />
</a-form-item>
<a-form-item
:wrapperCol="buttonItemLayout.wrapperCol"
>
<a-button type='primary'>Submit</a-button>
</a-form-item>
</a-form>
</div>
</template>
<script> <script>
export default { import { Form } from 'vue-antd-ui'
data () {
return { const Demo = {
formLayout: 'horizontal',
}
},
methods: { methods: {
handleFormLayoutChange (e) { handleSubmit (e) {
this.formLayout = e.target.value e.preventDefault()
this.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values)
}
})
},
normFile (e) {
console.log('Upload event:', e)
if (Array.isArray(e)) {
return e
}
return e && e.fileList
}, },
}, },
computed: {
formItemLayout () { render () {
const { formLayout } = this const { getFieldDecorator } = this.form
return formLayout === 'horizontal' ? { const formItemLayout = {
labelCol: { span: 4 }, labelCol: { span: 6 },
wrapperCol: { span: 14 }, wrapperCol: { span: 14 },
} : {} }
}, return (
buttonItemLayout () { <a-form onSubmit={this.handleSubmit}>
const { formLayout } = this <a-form-item
return formLayout === 'horizontal' ? { {...{ props: formItemLayout }}
wrapperCol: { span: 14, offset: 4 }, label='Plain Text'
} : {} >
}, <span class='ant-form-text'>China</span>
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Select'
hasFeedback
>
{getFieldDecorator('select', {
rules: [
{ required: true, message: 'Please select your country!' },
],
})(
<a-select placeholder='Please select a country'>
<a-select-option value='china'>China</a-select-option>
<a-select-option value='use'>U.S.A</a-select-option>
</a-select>
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Select[multiple]'
>
{getFieldDecorator('select-multiple', {
rules: [
{ required: true, message: 'Please select your favourite colors!', type: 'array' },
],
})(
<a-select mode='multiple' placeholder='Please select favourite colors'>
<a-select-option value='red'>Red</a-select-option>
<a-select-option value='green'>Green</a-select-option>
<a-select-option value='blue'>Blue</a-select-option>
</a-select>
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='InputNumber'
>
{getFieldDecorator('input-number', { initialValue: 3 })(
<a-input-number min={1} max={10} />
)}
<span class='ant-form-text'> machines</span>
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Switch'
>
{getFieldDecorator('switch', { valuePropName: 'checked' })(
<a-switch />
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Slider'
>
{getFieldDecorator('slider')(
<a-slider marks={{ 0: 'A', 20: 'B', 40: 'C', 60: 'D', 80: 'E', 100: 'F' }} />
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Radio.Group'
>
{getFieldDecorator('radio-group')(
<a-radio-group>
<a-radio value='a'>item 1</a-radio>
<a-radio value='b'>item 2</a-radio>
<a-radio value='c'>item 3</a-radio>
</a-radio-group>
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Radio.Button'
>
{getFieldDecorator('radio-button')(
<a-radio-group>
<a-radio-button value='a'>item 1</a-radio-button>
<a-radio-button value='b'>item 2</a-radio-button>
<a-radio-button value='c'>item 3</a-radio-button>
</a-radio-group>
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Rate'
>
{getFieldDecorator('rate', {
initialValue: 3.5,
})(
<a-rate allowHalf/>
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Upload'
extra='longgggggggggggggggggggggggggggggggggg'
>
{getFieldDecorator('upload', {
valuePropName: 'fileList',
getValueFromEvent: this.normFile,
})(
<a-upload name='logo' action='/upload.do' listType='picture'>
<a-button>
<a-icon type='upload' /> Click to upload
</a-button>
</a-upload>
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Dragger'
>
<div class='dropbox'>
{getFieldDecorator('dragger', {
valuePropName: 'fileList',
getValueFromEvent: this.normFile,
})(
<a-upload-dragger name='files' action='/upload.do'>
<p class='ant-upload-drag-icon'>
<a-icon type='inbox' />
</p>
<p class='ant-upload-text'>Click or drag file to this area to upload</p>
<p class='ant-upload-hint'>Support for a single or bulk upload.</p>
</a-upload-dragger>
)}
</div>
</a-form-item>
<a-form-item
wrapperCol={{ span: 12, offset: 6 }}
>
<a-button type='primary' htmlType='submit'>Submit</a-button>
</a-form-item>
</a-form>
)
}, },
} }
export default Form.create()(Demo)
</script> </script>

View File

@ -0,0 +1,131 @@
<cn>
#### 时间类控件
时间类组件的 `value``moment` 类型,所以在提交前需要预处理。
</cn>
<us>
#### Time-related Controls
the `value` of time-related components is `moment`. So, we need to pre-process those values.
</us>
```html
<script>
import { Form } from 'vue-antd-ui'
const TimeRelatedForm = {
methods: {
handleSubmit (e) {
e.preventDefault()
this.form.validateFields((err, fieldsValue) => {
if (err) {
return
}
// Should format date value before submit.
const rangeValue = fieldsValue['range-picker']
const rangeTimeValue = fieldsValue['range-time-picker']
const values = {
...fieldsValue,
'date-picker': fieldsValue['date-picker'].format('YYYY-MM-DD'),
'date-time-picker': fieldsValue['date-time-picker'].format('YYYY-MM-DD HH:mm:ss'),
'month-picker': fieldsValue['month-picker'].format('YYYY-MM'),
'range-picker': [rangeValue[0].format('YYYY-MM-DD'), rangeValue[1].format('YYYY-MM-DD')],
'range-time-picker': [
rangeTimeValue[0].format('YYYY-MM-DD HH:mm:ss'),
rangeTimeValue[1].format('YYYY-MM-DD HH:mm:ss'),
],
'time-picker': fieldsValue['time-picker'].format('HH:mm:ss'),
}
console.log('Received values of form: ', values)
})
},
},
render () {
const { getFieldDecorator } = this.form
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 8 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
}
const config = {
rules: [{ type: 'object', required: true, message: 'Please select time!' }],
}
const rangeConfig = {
rules: [{ type: 'array', required: true, message: 'Please select time!' }],
}
return (
<a-form onSubmit={this.handleSubmit}>
<a-form-item
{...{ props: formItemLayout }}
label='DatePicker'
>
{getFieldDecorator('date-picker', config)(
<a-date-picker />
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='DatePicker[showTime]'
>
{getFieldDecorator('date-time-picker', config)(
<a-date-picker showTime format='YYYY-MM-DD HH:mm:ss' />
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='MonthPicker'
>
{getFieldDecorator('month-picker', config)(
<a-monthPicker />
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='RangePicker'
>
{getFieldDecorator('range-picker', rangeConfig)(
<a-range-picker />
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='RangePicker[showTime]'
>
{getFieldDecorator('range-time-picker', rangeConfig)(
<a-range-picker showTime format='YYYY-MM-DD HH:mm:ss' />
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='TimePicker'
>
{getFieldDecorator('time-picker', config)(
<a-time-picker />
)}
</a-form-item>
<a-form-item
wrapperCol={{
xs: { span: 24, offset: 0 },
sm: { span: 16, offset: 8 },
}}
>
<a-button type='primary' htmlType='submit'>Submit</a-button>
</a-form-item>
</a-form>
)
},
}
export default Form.create()(TimeRelatedForm)
</script>
```

View File

@ -0,0 +1,205 @@
<cn>
#### 校验其他组件
以上演示没有出现的表单控件对应的校验演示。
</cn>
<us>
#### Other Form Controls
Demostration for validataion configuration for form controls which are not show in the above demos.
</us>
```html
<script>
import { Form } from 'vue-antd-ui'
const Demo = {
methods: {
handleSubmit (e) {
e.preventDefault()
this.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values)
}
})
},
normFile (e) {
console.log('Upload event:', e)
if (Array.isArray(e)) {
return e
}
return e && e.fileList
},
},
render () {
const { getFieldDecorator } = this.form
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 14 },
}
return (
<a-form id="components-form-demo-validate-other" onSubmit={this.handleSubmit}>
<a-form-item
{...{ props: formItemLayout }}
label='Plain Text'
>
<span class='ant-form-text'>China</span>
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Select'
hasFeedback
>
{getFieldDecorator('select', {
rules: [
{ required: true, message: 'Please select your country!' },
],
})(
<a-select placeholder='Please select a country'>
<a-select-option value='china'>China</a-select-option>
<a-select-option value='use'>U.S.A</a-select-option>
</a-select>
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Select[multiple]'
>
{getFieldDecorator('select-multiple', {
rules: [
{ required: true, message: 'Please select your favourite colors!', type: 'array' },
],
})(
<a-select mode='multiple' placeholder='Please select favourite colors'>
<a-select-option value='red'>Red</a-select-option>
<a-select-option value='green'>Green</a-select-option>
<a-select-option value='blue'>Blue</a-select-option>
</a-select>
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='InputNumber'
>
{getFieldDecorator('input-number', { initialValue: 3 })(
<a-input-number min={1} max={10} />
)}
<span class='ant-form-text'> machines</span>
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Switch'
>
{getFieldDecorator('switch', { valuePropName: 'checked' })(
<a-switch />
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Slider'
>
{getFieldDecorator('slider')(
<a-slider marks={{ 0: 'A', 20: 'B', 40: 'C', 60: 'D', 80: 'E', 100: 'F' }} />
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Radio.Group'
>
{getFieldDecorator('radio-group')(
<a-radio-group>
<a-radio value='a'>item 1</a-radio>
<a-radio value='b'>item 2</a-radio>
<a-radio value='c'>item 3</a-radio>
</a-radio-group>
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Radio.Button'
>
{getFieldDecorator('radio-button')(
<a-radio-group>
<a-radio-button value='a'>item 1</a-radio-button>
<a-radio-button value='b'>item 2</a-radio-button>
<a-radio-button value='c'>item 3</a-radio-button>
</a-radio-group>
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Rate'
>
{getFieldDecorator('rate', {
initialValue: 3.5,
})(
<a-rate allowHalf/>
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Upload'
extra='longgggggggggggggggggggggggggggggggggg'
>
{getFieldDecorator('upload', {
valuePropName: 'fileList',
getValueFromEvent: this.normFile,
})(
<a-upload name='logo' action='/upload.do' listType='picture'>
<a-button>
<a-icon type='upload' /> Click to upload
</a-button>
</a-upload>
)}
</a-form-item>
<a-form-item
{...{ props: formItemLayout }}
label='Dragger'
>
<div class='dropbox'>
{getFieldDecorator('dragger', {
valuePropName: 'fileList',
getValueFromEvent: this.normFile,
})(
<a-upload-dragger name='files' action='/upload.do'>
<p class='ant-upload-drag-icon'>
<a-icon type='inbox' />
</p>
<p class='ant-upload-text'>Click or drag file to this area to upload</p>
<p class='ant-upload-hint'>Support for a single or bulk upload.</p>
</a-upload-dragger>
)}
</div>
</a-form-item>
<a-form-item
wrapperCol={{ span: 12, offset: 6 }}
>
<a-button type='primary' htmlType='submit'>Submit</a-button>
</a-form-item>
</a-form>
)
},
}
export default Form.create()(Demo)
</script>
<style>
#components-form-demo-validate-other .dropbox {
height: 180px;
line-height: 1.5;
}
</style>
```