zarm-web
Version:
基于 React 的桌面端UI库
442 lines (411 loc) • 13.5 kB
Markdown
## Form 表单
表单组件,用于包裹表单元素组件。
### 基础用法
:::demo 使用`Fomr.Item`包裹`Input`,`Button`等表单元素组件。
```js
render() {
return (
<div>
<Form>
<Form.Item label="账号">
<Input placeholder="请输入..." />
</Form.Item>
<Form.Item label="密码">
<Input placeholder="请输入..." />
</Form.Item>
<Form.Item>
<Button theme="primary">登录</Button>
</Form.Item>
</Form>
</div>
)
}
```
:::
### 表单验证
:::demo
rules支持外部和Form.Item的内联形式, 回调支持promise和callback两种形式,
如果需要重置表单值 需要如下面例子<font color=red size=2 >手动调用forceUpdate</font>的更新一次组件,
否则只会重置组件的验证和内部数据, 页面不会更新
更多关于验证的方法请参考 <br/> <a href="https://github.com/yiminghe/async-validator" target="_blank">async-validator</a>
```js
constructor (props) {
super(props)
this.state = {
params: {
account: '',
password: '',
sex: '',
habits: [],
birthday: '',
size: '',
},
rules: {
account: [
{ required: true, message: '请输入账号', trigger: 'blur' },
{ type: 'string', min: 6, max: 10, message: '必须在6到10个字符', trigger: 'blur,change' },
],
sex: [
{ required: true, message: '请选择性别', trigger: 'change' }
],
habits: [
{ type: 'array', required: true, message: '至少选择一种动物', trigger: 'change' }
],
birthday: [
{ required: true, message: '请选择出生日期', trigger: 'change' }
],
size: [
{ required: true, message: '请选择尺寸', trigger: 'change' }
]
}
}
}
handleSubmit (e) {
this.form.validate().then(res => {
if (res) {
Notification.success({ title: '成功', message: '表单验证通过' })
} else {
Notification.danger({ title: '失败', message: '表单验证失败' })
}
})
}
handleReset () {
this.form.resetField();
console.log(this.state)
this.forceUpdate();
}
render() {
const { params } = this.state
return (
<div>
<Form type="inline" scrollToError onSubmit={this.handleSubmit.bind(this)} labelWidth="90" labelPosition="left" ref={el => this.form = el} model={this.state.params} rules={this.state.rules} onSubmit={this.handleSubmit.bind(this)}>
<Form.Item className="col-xs-24" label="账号" prop="account">
<Input
placeholder="请输入..."
value={params.account}
onChange={(e) => {
params.account = e.target.value
this.setState({ params })
}}
/>
</Form.Item>
<Form.Item
className="col-xs-24"
label="密码"
prop="password"
rules={
[
{ required: true, message: '请输入密码', trigger: 'blur' },
{ type: 'string', min: 8, max: 16, message: '密码必须大于等于八位小于等于16位', trigger: 'change, blur' }
]
}
>
<Input
value={params.password}
placeholder="请输入..."
onChange={(e) => {
params.password = e.target.value
this.setState({ params })
}}
/>
</Form.Item>
<Form.Item className="col-xs-24" label="性别" prop="sex">
<Select
searchPlaceholder="请选择性别"
value={params.sex}
onChange={(data) => {
params.sex = data.value
this.setState({ params })
}}>
<Select.Option key="boy" value="boy">boy</Select.Option>
<Select.Option key="girl" value="girl">girl</Select.Option>
</Select>
</Form.Item>
<Form.Item className="col-xs-24" label="出生日期" prop="birthday">
<DatePicker
radius
allowInput
style={{ width: 200 }}
value={params.birthday}
placeholder="请选择日期"
onChange={(date) => {
params.birthday = date
this.setState({ params })
}}
/>
</Form.Item>
<Form.Item className="col-xs-24" label="爱好" prop="habits">
<Checkbox.Group
value={params.habits}
onChange={(values) => {
params.habits = values
this.setState({ params })
}}
>
<Checkbox value="养猪">养猪</Checkbox>
<Checkbox value="养牛">养牛</Checkbox>
<Checkbox value="养狗">养狗</Checkbox>
<Checkbox value="养猫">养猫</Checkbox>
</Checkbox.Group>
</Form.Item>
<Form.Item className="col-xs-24" prop="size" label="尺寸">
<Radio.Group
value={params.size}
onChange={(e) => {
params.size = e.target.value
this.setState({ params })
}}
>
<Radio value="a">A</Radio>
<Radio value="b">B</Radio>
</Radio.Group>
</Form.Item>
<Form.Item className="col-xs-24">
<Button theme="primary" htmlType="submit">登录</Button>
<Button theme="default" onClick={this.handleReset.bind(this)}>重置</Button>
</Form.Item>
</Form>
</div>
)
}
```
:::
### 自定义验证
:::demo 自定义表单项的验证
```js
constructor(props) {
super(props)
this.state = {
params: {
password: '',
confirmPassword: '',
money: ''
},
rules: {
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{
validator: (rule, value, callback) => {
if (value === '') {
callback(new Error('请输入密码'));
} else {
if (this.state.params.confirmPassword !== '') {
this.formRef.validateField('confirmPassword');
}
callback();
}
},
trigger: 'blur'
}
],
confirmPassword: [
{ require: true, message: '请输入确认密码', trigger: 'blur' },
{
validator: (rule, value, callback) => {
const val = Number(value)
if (val !== Number(this.state.params.password)) {
callback(new Error('两次输入密码必须一致哦!'))
} else {
callback()
}
},
trigger: 'blur'
}
],
money: [
{ required: true, message: '请输入重置金额', trigger: 'blur' },
{
validator: (rule, value, callback) => {
const val = Number(value)
if (!Number.isInteger(val)) {
callback(new Error('重置金额必须为数字'))
} else if (Number(val) > 1000) {
callback(new Error('重置金额必须小于1000 !!'))
} else {
callback()
}
},
trigger: 'change,blur'
},
],
}
}
}
handleSubmit() {
this.formRef.validate(result => {
if (result) {
Message.success('validate success')
} else {
Message.danger('validate fail')
}
})
}
render() {
const { params, rules } = this.state;
return (
<Form model={params} rules={rules} ref={el => this.formRef = el}>
<Form.Item
label="密码"
prop="password"
>
<Input
placeholder="请输入密码"
value={params.password}
onChange={e => {
params.password = e.target.value
this.setState({ params })
}}
/>
</Form.Item>
<Form.Item
label="确认密码"
prop="confirmPassword"
required
>
<Input
placeholder="请再次输入密码"
value={params.confirmPassword}
onChange={e => {
params.confirmPassword = e.target.value
this.setState({ params })
}}
/>
</Form.Item>
<Form.Item
label="重置金额"
prop="money"
>
<Input
placeholder="请输入重置金额"
value={params.money}
onChange={e => {
params.money = e.target.value
this.setState({ params })
}}
/>
</Form.Item>
<Form.Item>
<Button theme="primary" onClick={this.handleSubmit.bind(this)}>确认</Button>
</Form.Item>
</Form>
)
}
```
:::
### 动态表单验证
:::demo 动态表单表单项的验证
```js
constructor(props) {
super(props)
this.state = {
family: {
people: [
{ name: '' }
]
}
}
}
handleAdd() {
const people = this.state.family.people
people.push({ name: '' })
this.setState({
family: {
people
}
})
}
handleDel(index) {
const people = this.state.family.people
people.splice(index, 1)
this.setState({
family: {
people
}
})
}
handleSubmit() {
this.formRef.validate(result => {
if (result) {
Message.success('congratulation! validate success')
} else {
Message.danger('sorry, validate failed')
}
})
}
render() {
const { people } = this.state.family
return (
<Form type="inline" model={this.state.family} ref={el => this.formRef = el} labelWidth={90}>
{
people.map((person, index) => (
<Form.Item
className="col-xs-24"
key={person+index}
label={`家人${index + 1}`}
prop={`people.${index}`}
rules={
{
type: 'object',
required: true,
fields: {
name: [
{ required: true, message: '姓名不能为空', trigger: 'blur' },
{ type: 'string', min:3, max: 6, message: '姓名必须在3到6个字符', trigger: 'change' }
]
}
}
}
>
<Input
placeholder="请输入家人姓名"
style={{ width: 300 }}
value={person.name}
onChange={e => {
people[index].name = e.target.value
this.setState({
family: {
people
}
})
}}
/>
<Button shape="circle" style={{ borderColor: 'transparent' }} onClick={this.handleDel.bind(this, index)}>
<Icon type="minus-round" style={{ fontSize: 20, color: '#909090' }} />
</Button>
</Form.Item>
))
}
<Form.Item className="col-xs-24" label={''}>
<Button style={{ width: 300, background: '#e6e6e6'}} onClick={this.handleAdd.bind(this)}>
<Icon type="add" style={{ marginRight: 12 }} />添加
</Button>
</Form.Item>
<Form.Item className="col-xs-24" label={''}>
<Button theme="primary" onClick={this.handleSubmit.bind(this)}>Submit</Button>
</Form.Item>
</Form>
)
}
```
:::
### Form Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- |
| type | 类型 | string | inline/horizontal | horizontal |
| model | 表单数据对象 | object | - | - |
| rules | 表单校验规则 | object | - | - |
| scrollToError | 提交表单时是否滚动到第一个错误位置 | boolean | - | false |
### Form Method
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- |
| validate | 表单验证方法 | func | - | - |
| validateField | 对表单单项进行验证 | func | - | - |
| resetField | 对表单数据model重置 | func | - | - |
### Form.Item Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- |
| required | 是否必填 | boolean | - | false |
| rules | 校验规则(优先级高级外部rules) | object/array | - | - |
| label | label文案 | string | - | - |
| labelWidth | label栅格宽度 | string/number | - | - |
| labelPosition | label对其位置 | left/right | - | - |