zent
Version:
一套前端设计语言和基于React的实现
282 lines (263 loc) • 5.74 kB
Markdown
---
order: 8
zh-CN:
title: FieldArray 基本使用
addHobby: 添加兴趣爱好
delHobby: 删除该爱好
hobby: 兴趣爱好
hobbyValidation: 请填写兴趣爱好
hobbyLimit: 最多添加 3 项兴趣
addMember: 添加一个成员
addTwoMembers: 添加两个成员
delMember: 删除该成员
member: 成员
name: 名字
sex: 性别
nameValidationError: 请填写成员名字
sexValidationError: 请选择性别
male: 男
female: 女
totalNumber: 总人数
totalNumberError: 请填写总人数
submit: 获取表单值
submitValue: 获取表单提交值
setArray: 设置 FieldArray 值
en-US:
title: Basic usage of FieldArray
addHobby: Add hobby
delHobby: Delete hobby
hobby: Hobby
hobbyValidation: Please enter the hobby
hobbyLimit: Too many hobbies, at most 3
addMember: Add one member
addTwoMembers: Add two members
delMember: Delete member
member: Member
name: Name
sex: Sex
nameValidationError: Please enter the name of member.
sexValidationError: Please select the sex of member.
male: male
female: female
totalNumber: Total number
totalNumberError: Please enter the total number of the family.
submit: Get Form Value
submitValue: Get Submit Value
setArray: Set FieldArray
---
```jsx
import {
Form,
FormError,
Icon,
Pop,
Notify,
FieldModel,
FieldSetModel,
FieldSet,
Validators,
ValidatorOption,
FormStrategy,
FormNumberInputField,
} from 'zent';
function Hobbies({ name }) {
const model = Form.useFieldArray(name, [
Validators.maxLength(3, '{i18n.hobbyLimit}'),
]);
const addHobby = useCallback(() => {
model.push('');
model.validate(ValidateOption.IncludeUntouched);
}, []);
return (
<>
<Button onClick={addHobby} className="add-btn">
{i18n.addHobby}
</Button>
<ul>
{model.children.map((child, index) => (
<li key={child.id} className="hobby">
<FormInputField
model={child}
label={`{i18n.hobby}${index + 1}:`}
validators={[Validators.required('{i18n.hobbyValidation}')]}
props={{
width: 120,
}}
/>
<span
className="del-btn"
onClick={() => {
model.splice(index, 1);
model.validate();
}}
>
{i18n.delHobby}
</span>
</li>
))}
</ul>
<FormError style={{ marginLeft: 128 }}>{model.error?.message}</FormError>
</>
);
}
function MemberInfo({ remove, index }) {
const onRemoveClick = useCallback(() => {
remove(index);
}, [index, remove]);
return (
<li className="members">
<div className="member-title">
<span>
{i18n.member}
{index + 1}
</span>
<Pop centerArrow trigger="hover" content="{i18n.delMember}">
<Icon
className="del-btn"
type="close-circle"
onClick={onRemoveClick}
/>
</Pop>
</div>
<FormInputField
name="name"
label="{i18n.name}:"
required
validators={[Validators.required('{i18n.nameValidationError}')]}
normalizeBeforeSubmit={name => name.toUpperCase()}
/>
<FormRadioGroupField
name="sex"
label="{i18n.sex}:"
defaultValue="1"
required
validators={[Validators.required('{i18n.sexValidationError}')]}
>
<Radio value="1">{i18n.male}</Radio>
<Radio value="2">{i18n.female}</Radio>
</FormRadioGroupField>
<Hobbies name="hobbies" />
</li>
);
}
function Members({ name }) {
const model = Form.useFieldArray(name);
const addOne = useCallback(() => {
model.push({});
}, [model]);
const addTwo = useCallback(() => {
model.push({}, {});
}, [model]);
const remove = useCallback(
index => {
model.splice(index, 1);
},
[model]
);
return (
<>
{model.children.length < 3 && (
<Button onClick={addOne} className="add-btn">
{i18n.addMember}
</Button>
)}
{model.children.length < 2 && (
<Button onClick={addTwo} className="add-btn">
{i18n.addTwoMembers}
</Button>
)}
<ul>
{model.children.map((child, index) => (
<FieldSet key={child.id} model={child}>
<MemberInfo index={index} remove={remove} />
</FieldSet>
))}
</ul>
</>
);
}
function App() {
const form = Form.useForm(FormStrategy.View);
const setArray = useCallback(() => {
form.patchValue({
number: 42,
members: [
{
name: 'john',
sex: '1',
hobbies: ['H1'],
},
],
});
}, [form]);
const getFormValue = useCallback(() => {
console.log(form.getValue());
}, [form]);
const getSubmitValue = useCallback(() => {
console.log(form.getSubmitValue());
}, [form]);
return (
<Form className="demo-form" layout="horizontal" form={form}>
<FormNumberInputField
name="number"
label="{i18n.totalNumber}:"
required
validators={[Validators.required('{i18n.totalNumberError}')]}
/>
<Members name="members" />
<div style={{ marginTop: 16 }}>
<Button type="primary" htmlType="submit" onClick={getFormValue}>
{i18n.submit}
</Button>
<Button type="primary" htmlType="submit" onClick={getSubmitValue}>
{i18n.submitValue}
</Button>
<Button onClick={setArray}>{i18n.setArray}</Button>
</div>
</Form>
);
}
ReactDOM.render(<App />, mountNode);
```
<style>
.add-btn {
margin-left: 130px;
}
.demo-form {
.members {
border: 1px dashed #ccc;
margin: 20px 0;
padding: 10px 0;
position: relative;
.del-btn {
color: #666;
cursor: pointer;
position: absolute;
right: -8px;
top: -8px;
}
}
.member-title{
margin: 0 10px;
}
.hobby {
margin-top: 20px;
position: relative;
.del-btn {
color: #155bd4;
cursor: pointer;
font-size: 12px;
position: absolute;
top: 6px;
left: 300px;
width: 100px;
}
}
.hobby-title {
margin: 10px 0 5px;
}
.zenticon {
margin-left: 10px;
}
}
</style>