feat: form

pull/165/head
tangjinzhou 2018-05-07 18:40:25 +08:00
parent fb22422d8e
commit 787d51f375
9 changed files with 354 additions and 51 deletions

View File

@ -0,0 +1,98 @@
<script>
import AdvancedSearch from './advanced-search'
// import Coordinated from './coordinated'
// import CustomizedFormControls from './customized-form-controls'
// import DynamicFormItem from './dynamic-form-item'
// import DynamicRule from './dynamic-rule'
// import FormInModal from './form-in-modal'
// import GlobalState from './global-state'
// import HorizontalLogin from './horizontal-login'
// import Layout from './layout'
// import NormalLogin from './normal-login'
// import Register from './register'
// import TimeRelatedControls from './time-related-controls'
// import ValidateOther from './validate-other'
// import ValidateStatic from './validate-static'
// import WithoutFormCreate from './without-form-create'
import CN from './../index.zh-CN'
import US from './../index.en-US'
const md = {
cn: `# Form 表单
具有数据收集校验和提交功能的表单包含复选框单选框输入框下拉选择框等元素
## 表单
我们为 \`form\` 提供了以下三种排列方式:
- 水平排列标签和表单控件水平排列默认
- 垂直排列标签和表单控件上下垂直排列
- 行内排列表单项水平行内排列
## 表单域
表单一定会包含表单域表单域可以是输入控件标准表单域标签下拉菜单文本域等
这里我们封装了表单域 \`<Form.Item />\`
**注意** 如果使用 \`Form.create\` 处理表单使其具有自动收集数据并校验的功能,建议使用\`jsx\`
## 代码演示
`,
us: `# Form
Form is used to collect, validate, and submit the user input, usually contains various form items including checkbox, radio, input, select, and etc.
## Form
You can align the controls of a \`form\` using the \`layout\` prop
- \`horizontal\`to horizontally align the \`label\`s and controls of the fields. (Default)
- \`vertical\`to vertically align the \`label\`s and controls of the fields.
- \`inline\`to render form fields in one line.
## Form fields
A form consists of one or more form fields whose type includes input, textarea, checkbox, radio, select, tag, and more.
A form field is defined using \`<Form.Item />\`.
**Note:** If you use \`Form.create\` to process forms with automatic data collection and validation, we recommend using \`jsx\`
## Examples
`,
}
export default {
category: 'Components',
subtitle: '表单',
type: 'Data Entry',
cols: 1,
title: 'Form',
render () {
return (
<div>
<md cn={md.cn} us={md.us} />
<AdvancedSearch />
{/* <Coordinated />
<CustomizedFormControls />
<DynamicFormItem />
<DynamicRule />
<FormInModal />
<GlobalState />
<HorizontalLogin />
<Layout />
<NormalLogin />
<Register />
<TimeRelatedControls />
<ValidateStatic />
<WithoutFormCreate />
<ValidateOther />
*/}
<api>
<CN slot='cn' />
<US />
</api>
</div>
)
},
}
</script>

View File

@ -0,0 +1,178 @@
<cn>
#### 自定义校验
我们提供了 `validateStatus` `help` `hasFeedback` 等属性,你可以不需要使用 `Form.create``getFieldDecorator`,自己定义校验的时机和内容。
1. `validateStatus`: 校验状态,可选 'success', 'warning', 'error', 'validating'。
2. `hasFeedback`:用于给输入框添加反馈图标。
3. `help`:设置校验文案。
</cn>
<us>
#### Customized Validation
We provide properties like `validateStatus` `help` `hasFeedback` to customize your own validate status and message, without using `Form.create` and `getFieldDecorator`.
1. `validateStatus`: validate status of form components which could be 'success', 'warning', 'error', 'validating'.
2. `hasFeedback`: display feed icon of input control
3. `help`: display validate message.
</us>
```html
<template>
<a-form>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label='Fail'
validateStatus='error'
help='Should be combination of numbers & alphabets'
>
<a-input placeholder='unavailable choice' id='error' />
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label='Warning'
validateStatus='warning'
>
<a-input placeholder='Warning' id='warning' />
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label='Validating'
hasFeedback
validateStatus='validating'
help='The information is being validated...'
>
<a-input placeholder="I'm the content is being validated" id='validating' />
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label='Success'
hasFeedback
validateStatus='success'
>
<a-input placeholder="I'm the content" id='success' />
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label='Warning'
hasFeedback
validateStatus='warning'
>
<a-input placeholder='Warning' id='warning' />
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label='Fail'
hasFeedback
validateStatus='error'
help='Should be combination of numbers & alphabets'
>
<a-input placeholder='unavailable choice' id='error' />
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label='Success'
hasFeedback
validateStatus='success'
>
<a-date-picker style="width: 100%" />
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label='Warning'
hasFeedback
validateStatus='warning'
>
<a-time-picker style="width: 100%" />
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label='Error'
hasFeedback
validateStatus='error'
>
<a-select defaultValue='1'>
<a-select-option value='1'>Option 1</a-select-option>
<a-select-option value='2'>Option 2</a-select-option>
<a-select-option value='3'>Option 3</a-select-option>
</a-select>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label='Validating'
hasFeedback
validateStatus='validating'
help='The information is being validated...'
>
<a-cascader :defaultValue="['1']" :options="[]" />
</a-form-item>
<a-form-item
label='inline'
:labelCol="labelCol"
:wrapperCol="wrapperCol"
>
<a-col :span="11">
<a-form-item validateStatus='error' help='Please select the correct date'>
<a-date-picker style="width: 100%"/>
</a-form-item>
</a-col>
<a-col :span="2">
<span :style="{ display: 'inline-block', width: '100%', textAlign: 'center' }">
-
</span>
</a-col>
<a-col :span="11">
<a-form-item>
<a-date-picker style="width: 100%"/>
</a-form-item>
</a-col>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label='Success'
hasFeedback
validateStatus='success'
>
<a-input-number style="width: 100%" />
</a-form-item>
</a-form>
</template>
<script>
export default {
data () {
return {
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 12 },
},
}
},
}
</script>
```

View File

@ -0,0 +1,67 @@
<cn>
#### 自行处理表单数据
使用 `Form.create` 处理后的表单具有自动收集数据并校验的功能,但如果您不需要这个功能,或者默认的行为无法满足业务需求,可以选择不使用 `Form.create` 并自行处理数据。
</cn>
<us>
#### Handle Form Data Manually
`Form.create` will collect and validate form data automatically. But if you don't need this feature or the default behaviour cannot satisfy your business, you can drop `Form.create` and handle form data manually.
</us>
```html
<template>
<a-form>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="Prime between 8 & 12"
:validateStatus="number.validateStatus"
:help="number.errorMsg || tips"
>
<a-input-number
:min="8"
:max="12"
:value="number.value"
@change="handleNumberChange"
/>
</a-form-item>
</a-form>
</template>
<script>
function validatePrimeNumber (number) {
if (number === 11) {
return {
validateStatus: 'success',
errorMsg: null,
}
}
return {
validateStatus: 'error',
errorMsg: 'The prime between 8 and 12 is 11!',
}
}
export default {
data () {
return {
labelCol: { span: 7 },
wrapperCol: { span: 12 },
number: {
value: 11,
},
tips: 'A prime is a natural number greater than 1 that has no positive divisors other than 1 and itself.',
}
},
methods: {
handleNumberChange (value) {
this.number = {
...validatePrimeNumber(value),
value,
}
},
},
}
</script>
```

View File

@ -1,24 +1,3 @@
---
category: Components
type: Data Entry
cols: 1
title: Form
---
Form is used to collect, validate, and submit the user input, usually contains various form items including checkbox, radio, input, select, and etc.
## Form
You can align the controls of a `form` using the `layout` prop
- `horizontal`to horizontally align the `label`s and controls of the fields. (Default)
- `vertical`to vertically align the `label`s and controls of the fields.
- `inline`to render form fields in one line.
## Form fields
A form consists of one or more form fields whose type includes input, textarea, checkbox, radio, select, tag, and more.
A form field is defined using `<Form.Item />`.
```jsx
<Form.Item {...props}>

View File

@ -1,26 +1,3 @@
---
category: Components
subtitle: 表单
type: Data Entry
cols: 1
title: Form
---
具有数据收集、校验和提交功能的表单,包含复选框、单选框、输入框、下拉选择框等元素。
## 表单
我们为 `form` 提供了以下三种排列方式:
- 水平排列:标签和表单控件水平排列;(默认)
- 垂直排列:标签和表单控件上下垂直排列;
- 行内排列:表单项水平行内排列。
## 表单域
表单一定会包含表单域,表单域可以是输入控件,标准表单域,标签,下拉菜单,文本域等。
这里我们封装了表单域 `<Form.Item />`
```jsx
<Form.Item {...props}>
@ -36,7 +13,7 @@ title: Form
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| form | 经 `Form.create()` 包装过的组件会自带 `this.props.form` 属性,直接传给 Form 即可。1.7.0 之后无需设置 | object | 无 |
| form | 经 `Form.create()` 包装过的组件会自带 `this.form` 属性,直接传给 Form 即可。无需手动设置 | object | 无 |
| hideRequiredMark | 隐藏所有表单项的必选标记 | Boolean | false |
| layout | 表单布局(2.8 之后支持) | 'horizontal'\|'vertical'\|'inline' | 'horizontal' |
| onSubmit | 数据验证成功后回调事件 | Function(e:Event) | |

View File

@ -7,7 +7,10 @@ export const InputNumberProps = {
prefixCls: PropTypes.string,
min: PropTypes.number,
max: PropTypes.number,
value: PropTypes.number,
value: PropTypes.oneOfType([
PropTypes.number,
PropTypes.string,
]),
step: PropTypes.oneOfType([
PropTypes.number,
PropTypes.string,

View File

@ -553,7 +553,7 @@ function createBaseForm (option = {}, mixins = []) {
},
render () {
const { $listeners } = this
const { $listeners, $slots } = this
const formProps = {
[formPropName]: this.getForm(),
}
@ -566,7 +566,7 @@ function createBaseForm (option = {}, mixins = []) {
on: $listeners,
ref: 'WrappedComponent',
}
return <WrappedComponent {...wrappedComponentProps}/>
return <WrappedComponent {...wrappedComponentProps}>{$slots.default}</WrappedComponent>
},
}
if (Array.isArray(WrappedComponent.props)) {

View File

@ -491,8 +491,9 @@ export default {
const inputDisplayValueFormat = this.formatWrapper(inputDisplayValue)
const isUpDisabled = !!upDisabledClass || disabled || readOnly
const isDownDisabled = !!downDisabledClass || disabled || readOnly
const { mouseenter = noop, mouseleave = noop, mouseover = noop, mouseout = noop } = this.$listeners
const contentProps = {
on: this.$listeners,
on: { mouseenter, mouseleave, mouseover, mouseout },
class: classes,
}
const upHandlerProps = {
@ -578,7 +579,7 @@ export default {
step={this.step}
name={this.name}
id={this.id}
onChange={this.onChange}
onInput={this.onChange}
ref='inputRef'
value={inputDisplayValueFormat}
pattern={this.pattern}

View File

@ -4,7 +4,7 @@ import Iframe from './components/iframe.vue'
const AsyncTestComp = () => {
const d = window.location.hash.replace('#', '')
return {
component: import(`../components/form/demo/${d}`),
component: import(`../components/form/demo/test.vue`),
}
}