Ant Design-表單相關元件

表單看似簡單,卻充滿各種細節。

基本結構

基本結構會由 FormForm.itemInput(表單相關元件) 來組成。

這邊會用一個登入表單來做講解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import React from 'react';
import { Row, Col, Form, Input ,Button, Checkbox, Space, notification} from "antd";
import { UserOutlined } from "@ant-design/icons";

function Main() {

// 通過驗證才會 trigger
const onFinish = (values: any) => {
notification.success({
message: 'Success!',
description: `
username: ${values.username},
password: ${values.passowrd},
remember: ${values.remember}
`
})
}

// 沒通過驗證時 trigger
const onFinishFailed = (errorInfo: any) => {
notification.error({
message: 'Failed',
description: `
Please cofirm your content are vaild.
`
})
}

return (
<>
<Row>
<Col offset={6} span={12}>
<h2><Space><UserOutlined />Log in</Space></h2>
<Form
name="basic"
{/* input 的格線 */}
wrapperCol={{span: 24}}
{/* label 文字的格線 */}
labelCol={{span: 24}}
{/* 初始值 */}
initialValues={{
remember: true
}}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
>
<Form.Item
{/* 要顯示的文字 */}
label="Username"
// datakey
name="username"
rules={[
{
{/* 是否必填 */}
required: true,
{/* 錯誤訊息文字 */}
message: 'Please input your username'
}
]}
>
<Input />
</Form.Item>
<Form.Item
{/* 要顯示的文字 */}
label="Password"
{/* datakey */}
name="passowrd"
rules={[
{
{/* 是否必填 */}
required: true,
{/* 錯誤訊息文字 */}
message: 'Please input your password'
}
]}
>
{/* 提醒一下,密碼要寫成這樣 */}
<Input.Password />
</Form.Item>
<Form.Item
name="remember"
{/* 不太懂文件意思,總之加上去後資料跟畫面才會是同步的 */}
valuePropName='checked'
>
<Checkbox>Remember me</Checkbox>
</Form.Item>
<Form.Item>
<Row justify='end'>
<Col><Button type='primary' htmlType='submit'>Submit</Button></Col>
</Row>
</Form.Item>
</Form>
</Col>
</Row>
</>
);
}

export default Main;

這個範例有用到的東西:

  • onFinish 通過驗證的 handler
  • onFinishFailed 沒通過驗證的 handler
  • <Form wrapperCol /> 對底下的所有 <input /> 做佈局設定
  • <Form labelCol /> 對底下的所有 label 文字做佈局設定
  • <Form initialValues /> 欄位的初始值
  • <Form.Item label /> label 文字
  • <Form.Item name /> 資料的 key 值
  • <Form.Item rules /> 跟驗證相關的東西 & 提示訊息
  • <Form.Item valuePropName /> 會用到 check 的話要記得設定這個

Radio

會由 Radio.GroupGroup 來組成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import React, { useState } from 'react'
import { Form, Input, Button, Radio } from 'antd'
import { UserOutlined } from '@ant-design/icons'

function Main() {
const [value, setValue] = useState(1)
const onChange = (e: any) => setValue(e.target.value)

return (
<>
<Radio.Group name='type' onChange={onChange} value={value}>
<Radio value={1}>A</Radio>
<Radio value={2}>B</Radio>
<Radio value={3}>C</Radio>
<Radio value={4}>D</Radio>
</Radio.Group>
</>
)
}

export default Main

也可以改用 options 的方式來設定:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import React, { useState } from 'react';
import { Form, Input ,Button, Radio } from "antd";
import { UserOutlined } from "@ant-design/icons";

function Main() {
const options = [
{
label: 'A',
value: 1,
disabled: false
},
{
label: 'B',
value: 2,
disabled: false
},
{
label: 'C',
value: 3,
disabled: false
},
{
label: 'D',
value: 4,
disabled: false
},
{
label: 'E',
value: 5,
disabled: true
}
]
const [value, setValue] = useState(1);
const onChange = (e: any) => setValue(e.target.value);

return <Radio.Group name="type" onChange={onChange} value={value} options={options} />
);
}

export default Main;

Checkbox

基本用法,跟 Radio 差不多。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import React, { useState } from 'react'
import { Form, Input, Button, Checkbox } from 'antd'
import { UserOutlined } from '@ant-design/icons'

function Main() {
const [value, setValue] = useState(1)
const onChange = (e: any) => setValue(e.target.value)

return (
<Checkbox.Group name='options'>
<Checkbox value={1}>Option1</Checkbox>
<Checkbox value={2}>Option2</Checkbox>
<Checkbox value={3}>Option3</Checkbox>
</Checkbox.Group>
)
}

export default Main

一次全選

直接看 code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import React, { useState } from 'react'
import { Checkbox } from 'antd'

const plainOptions = ['Apple', 'Orange', 'Pear']
const defaultCheckList = ['Apple', 'Orange']

function Main() {
// 是否有選擇一個以上
const [indeterminate, setIndeterminate] = useState(true)
// 是否全選
const [checkAll, setCheckAll] = useState(false)
// 預設選項
const [checkList, setCheckList] = useState(defaultCheckList)

const onCheckAllChange = (e: any) => {
setCheckList(e.target.checked ? plainOptions : [])
setIndeterminate(false)
setCheckAll(e.target.checked)
}

const onChnage = (list: any) => {
setCheckList(list)
// !! 的用途是只要是 falsy 就回傳 false
// 這邊是要確認目前長度 < 所有選項長度
// 只是利用短路運算先判斷 list.length 是否為 0,藉此省掉後面的比對。
setIndeterminate(!!list.length && list.length < plainOptions.length)
// 用長度來判斷全選
setCheckAll(list.length === plainOptions.length)
}

return (
<>
<Checkbox indeterminate={indeterminate} onChange={onCheckAllChange} checked={checkAll}>
Check All
</Checkbox>
{/* 改用 options 渲染 */}
<Checkbox.Group name='options' options={plainOptions} value={checkList} onChange={onChnage} />
</>
)
}

export default Main

下拉選單

會由 SelectOptnio 來組成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import React, { useState } from 'react'
import { Select } from 'antd'

const { Option } = Select

function Main() {
const handleChange = (value: string) => console.log(value)

return (
<Select defaultValue='peanu' onChange={handleChange}>
<Option value='peanu'>PeaNU</Option>
<Option value='ppb'>PPB</Option>
<Option value='et'>ET</Option>
<Option value='garry'>Garry</Option>
</Select>
)
}

export default Main

改用 optnios 屬性來渲染(據說效能比較好):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import React, { useState } from 'react'
import { Select } from 'antd'

const options = [
{
label: 'PeaNu',
value: 'peanu'
},
{
label: 'PPB',
value: 'ppb'
},
{
label: 'ET',
value: 'et'
},
{
label: 'Garry',
value: 'garry'
}
]

function Main() {
const handleChange = (value: string) => console.log(value)

return (
<>
<Select options={options} defaultValue='peanu' onChange={handleChange} />
</>
)
}

export default Main

介紹幾個 Input 的 props

1
2
3
4
5
6
<Input readOnly={true} /> // 看起來可以輸入,但不行
<Input disabled={true} /> // 禁用
<Input maxLength={20} /> // 最大長度
<Input showCount={true} /> // 顯示長度
<Input prefix={<UserOutlined />} /> // 在前面插入 icon
<Input suffix={<UserOutlined />}/> // 在後面插入 icon

改變 password 的 icon:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React, { useState } from 'react'
import { Input } from 'antd'
import { EyeFilled, EyeInvisibleFilled } from '@ant-design/icons'

function Main() {
return (
<>
<Input.Password
iconRender={(visible: boolean) => {
return visible ? <EyeFilled /> : <EyeInvisibleFilled />
}}
/>
</>
)
}

export default Main

和 Form 相關的屬性

initialValues 設定欄位的初始值

附註:提醒一下,key 會對應到 Form.Itemname 屬性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import React, { useState } from 'react'
import { Input, Form, Radio } from 'antd'
import { EyeFilled, EyeInvisibleFilled } from '@ant-design/icons'

const initialValues = {
username: 'PeaNu',
password: '123456789',
gender: 'man'
}

function Main() {
return (
<>
<Form autoComplete='off' initialValues={initialValues}>
<Form.Item label='Username' name='username'>
<Input />
</Form.Item>
<Form.Item label='Passowrd' name='password'>
<Input.Password />
</Form.Item>
<Form.Item name='gender'>
<Radio.Group>
<Radio value='man'>Man</Radio>
<Radio value='female'>Female</Radio>
</Radio.Group>
</Form.Item>
</Form>
</>
)
}

export default Main

validateTrigger

如名,設定什麼時候觸發驗證的 handler,預設是 onChange

如果我想讓 onBlur 時也觸發,可以這樣做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import React from 'react'
import { Input, Form, Radio } from 'antd'

function Main() {
return (
<>
{/* 加上 validateTrigger */}
<Form autoComplete='off' validateTrigger={['onBlur', 'onChnage']}>
<Form.Item
label='Username'
name='username'
rules={[
{
required: true,
message: 'Please input the username'
}
]}
>
<Input />
</Form.Item>
<Form.Item
label='Passowrd'
name='password'
rules={[
{
required: true,
message: 'Please input the password'
}
]}
>
<Input.Password />
</Form.Item>
<Form.Item name='gender'>
<Radio.Group>
<Radio value='man'>Man</Radio>
<Radio value='female'>Female</Radio>
</Radio.Group>
</Form.Item>
</Form>
</>
)
}

export default Main

form

這個要搭配 useForm() 來使用,它會回傳一個 instance,可以拿這個 instance 做一些事情。例如:當你想一次設定很多個欄位的預設值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import React from 'react'
import { Form, Input, Button } from 'antd'

function Main() {
// get instance
const [form] = Form.useForm()

// 設定預設值
form.setFieldsValue({
username: 'PeaNu',
password: '123456789'
})

return (
<>
{/* 記得要放到 form 屬性裡 */}
<Form form={form} autoComplete='off'>
<Form.Item label='Username' name='username'>
<Input />
<Input.Search />
</Form.Item>
<Form.Item label='Password' name='password'>
<Input.Password />
</Form.Item>
</Form>
{/* 點擊時顯示所有欄位的資料 */}
<Button onClick={() => console.log(form.getFieldsValue())}>Check data</Button>
</>
)
}

export default Main

因為可以用的東西很多就不一一列出,有需要的話參考這裡

用實作的方式來重新學習 Redux Ant Design-Breadcrumb
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×