-
Notifications
You must be signed in to change notification settings - Fork 3
/
Form.ts
96 lines (86 loc) · 2.31 KB
/
Form.ts
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
import * as oak from 'oak';
type Field<VALUE> = {
value: VALUE;
errors: string[];
touched: boolean;
dirty: boolean;
};
export type Form = {
age: Field<string>;
username: Field<string>;
isValid: boolean;
success?: string;
submitCount: number;
};
function initialField<VALUE>(value: VALUE): Field<VALUE> {
return {
value,
errors: [],
touched: false,
dirty: false,
};
}
export function initialForm() {
return {
age: initialField(''),
username: initialField(''),
isValid: true,
submitCount: 0,
};
}
export async function submitForm(form: Form): Promise<Form> {
await new Promise((res) => setTimeout(res, 50 + 100 * Math.random()));
return {
...form,
isValid: true,
submitCount: form.submitCount + 1,
success: 'successfully submitted',
};
}
export function validateAge(age: Form['age']): Form['age'] {
const errors = [];
const ageAsNumber = Number(age.value);
if (isNaN(ageAsNumber)) {
errors.push('Age must be a number');
}
if (ageAsNumber < 18) {
errors.push('Age must be greater than 18');
}
return { ...age, errors };
}
export function validateUsername(username: Form['username']): Form['username'] {
const errors = [];
if (username.value.length < 3) {
errors.push('Username is too short (min 3 characters)');
}
if (username.value.length > 10) {
errors.push('Username is too long (max 15 characters)');
}
return { ...username, errors };
}
export function validateForm(form: Form): Form {
const validatedAge = validateAge(form.age);
const validatedUsername = validateUsername(form.username);
return {
...form,
isValid: validatedAge.errors.length === 0 &&
validatedUsername.errors.length === 0,
age: validatedAge,
username: validatedUsername,
};
}
export function fromFormData(formDataBody: oak.FormDataBody): Form {
return {
...initialForm(),
age: {
...initialField(formDataBody.fields.age ?? ''),
touched: true,
dirty: true,
},
username: {
...initialField(formDataBody.fields.username ?? ''),
touched: true,
dirty: true,
},
};
}