mobx typescript form control validation
npm install mobx-form-control-kittypescript
const App = observer(() => {
const [firstName] = React.useState(
() =>
new FormControl("VA", {
validators: [requiredValidator()],
})
);
return (
{firstName.value}
value={firstName.value}
onChange={(event) => (firstName.value = event.target.value)}
onFocus={() => (firstName.focused = true)}
onBlur={() => (firstName.focused = false)}
/>
{firstName.touched &&
firstName.errors.map((err) => (
{err.message}
))}
onClick={async () => {
await firstName.wait();
if (firstName.invalid) {
firstName.touched = true;
return;
}
// Отправка данных
}}
>
Отправить
);
});
`
Типы контролов
Контролы разделены на два вида:
* FormControl - используется для хранения одного значения. Рекомендуется использовать примитивные типы, такие как: string, number, date, boolean и т.д. И избегать объектов. Хранение объектов допустимо, но нарушает концепцию формы.
* FormGroup - используется для объединения FormControl и FormGroup в группы.
Оба типа являются наследниками абстрактного класса AbstractControl. AbstractControl реализует интерфейс IAbstractControl, что позволяет гибко настроить структуру данных и передачу объектов данных типов.
Чтобы узнать к какому типу принадлежит объект IAbstractControl, можно воспользоваться полем type содержащие значение из enum.
`typescript
enum ControlTypes {
Control,
Group,
}
`
Рекомендуемая организация кода выглядит следующим образом:
`typescript
interface IFormPerson extends ControlsCollection {
firstName: FormControl;
lastName: FormControl;
middleName: FormControl;
age: FormControl;
}
interface IFormPassport extends ControlsCollection {
number: FormControl;
serias: FormControl;
issuedИy: FormControl;
}
interface IFormDriverLicense extends ControlsCollection {
number: FormControl;
serias: FormControl;
toDate: FormControl;
}
enum DocumentType {
Passport,
DriverLicense,
}
interface IFormDocument extends ControlsCollection {
type: FormControl;
passport: FormGroup;
driverLicense: FormGroup;
}
interface IFormChild extends ControlsCollection {
name: FormControl;
age: FormControl;
}
interface IForm extends ControlsCollection {
person: FormGroup;
document: FormGroup;
children: FormGroup[];
}
class Questionnaire {
public form: FormGroup;
constructor() {
this.form = new FormGroup({
person: new FormGroup({
firstName: new FormControl(""),
lastName: new FormControl(""),
middleName: new FormControl(""),
age: new FormControl(undefined),
}),
document: new FormGroup({
type: new FormControl(undefined),
passport: new FormGroup({
number: new FormControl(undefined),
serias: new FormControl(undefined),
issuedИy: new FormControl(""),
}),
driverLicense: new FormGroup({
number: new FormControl(undefined),
serias: new FormControl(undefined),
toDate: new FormControl(undefined),
}),
}),
children: [],
});
}
}
``