---
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);
			}
		},
		[id]
	);

	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);
```
