zent
Version:
一套前端设计语言和基于React的实现
121 lines (110 loc) • 2.36 kB
Markdown
---
order: 18
zh-CN:
title: 自定义表单组件
label: 身份证号
validatorMessage: 请输入合法的身份证号
requiredMessage: 请输入身份证号
en-US:
title: Custom Field
label: ID
validatorMessage: Invalid ID
requiredMessage: Require ID
---
```jsx
import {
Form,
FormError,
FormStrategy,
FormControl,
Input,
Validators,
useFormChild
} from 'zent';
const { form, field } = Form;
const formBuilder = form({
id: field('').validators(Validators.pattern(/^[\d]{17}[\dXY]$/, '{i18n.validatorMessage}')),
});
function FormIDField({
name,
model,
defaultValue = '',
validators = [],
label,
required,
withoutLabel,
style,
className,
}) {
if (name && model) {
throw new Error('Cannot use name and model together.');
}
const id = Form.useField(name || model, defaultValue, [
...validators,
Validators.pattern(/^[\d]{17}[\dXY]$/, '{i18n.validatorMessage}'),
]);
const anchorRef = React.useRef();
useFormChild(model, anchorRef);
const onChange = React.useCallback(
e => {
id.isTouched = true;
const value = e.target.value.replace(/\s/g, '');
if (value.length <= 18) {
id.patchValue(value);
}
},
[ ]
);
return (
<FormControl
ref={anchorRef}
style={style}
className={className}
label={label}
required={required}
withoutLabel={withoutLabel}
>
<Input
value={formatId(id.value)}
width={220}
onChange={onChange}
onBlur={React.useCallback(() => id.validate(), [id])}
/>
<FormError>{id.error?.message}</FormError>
</FormControl>
);
}
function formatId(value) {
const segment = [6, 10, 12, 14, 18];
let { length } = value;
let result = '';
let i = 0;
while (i < length) {
if (segment.includes(i)) {
result += ' ';
}
result += value[i];
i++;
}
return result;
}
function App() {
const form = Form.useForm(formBuilder);
return (
<Form onSubmit={() => {}} form={form} scrollToError={true} layout="horizontal">
<FormIDField
model={form.model.children.id}
label="{i18n.label}:"
required
validators={[Validators.required('{i18n.requiredMessage}')]}
/>
<div style={{marginTop: '120px'}} className="zent-form-actions">
<Button type="primary" htmlType="submit">
获取表单值,点击可以滚到到错误位置
</Button>
</div>
</Form>
);
}
ReactDOM.render(<App />, mountNode);
```