Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:02,080 --> 00:00:03,719
Were are you successful?
2
00:00:03,719 --> 00:00:05,910
I really recommend that you have a look
3
00:00:05,910 --> 00:00:07,960
at those last lectures again
4
00:00:07,960 --> 00:00:12,960
to fully understand how you manage entered values, validity
5
00:00:13,160 --> 00:00:14,800
and touched state,
6
00:00:14,800 --> 00:00:18,600
and combine that all with different event handlers,
7
00:00:18,600 --> 00:00:21,450
to make sure that you deliver the user experience
8
00:00:21,450 --> 00:00:23,540
you wanna deliver.
9
00:00:23,540 --> 00:00:25,490
Now, here in this case,
10
00:00:25,490 --> 00:00:28,100
I will continue with that finished custom hook,
11
00:00:28,100 --> 00:00:29,560
which we built already.
12
00:00:29,560 --> 00:00:33,800
I will not build up that entire logic again from scratch
13
00:00:33,800 --> 00:00:36,030
because I feel like I would basically
14
00:00:36,030 --> 00:00:38,760
just be wasting your time if I did that
15
00:00:38,760 --> 00:00:41,560
because it's just what we did in the previous lectures
16
00:00:41,560 --> 00:00:45,260
but I do want to apply to custom hook here one more time
17
00:00:45,260 --> 00:00:47,390
to really show you how you could do that
18
00:00:47,390 --> 00:00:49,373
in a brand new empty form.
19
00:00:50,520 --> 00:00:54,250
And therefore, if we start by importing user input from
20
00:00:54,250 --> 00:00:56,927
going up one level hooks/use-input
21
00:00:56,927 --> 00:01:01,003
and we then of course call useInput here.
22
00:01:02,000 --> 00:01:06,790
And we call it free times because we have free inputs here.
23
00:01:06,790 --> 00:01:10,110
Now, the validation logic for these free inputs
24
00:01:10,110 --> 00:01:11,300
is up to you.
25
00:01:11,300 --> 00:01:15,570
I didn't give you any restrictions or guidance there
26
00:01:15,570 --> 00:01:19,200
but it makes sense to ensure that these inputs aren't empty
27
00:01:19,200 --> 00:01:22,460
and that the email address is an email address.
28
00:01:22,460 --> 00:01:25,000
So for that, for the first two inputs,
29
00:01:25,000 --> 00:01:28,120
I'll check if the value we're getting is not empty,
30
00:01:28,120 --> 00:01:29,113
if we trim it.
31
00:01:30,510 --> 00:01:32,970
And since I'll use the same function here,
32
00:01:32,970 --> 00:01:35,480
wrap it and copy and pasting it like this,
33
00:01:35,480 --> 00:01:37,330
I will create a new function
34
00:01:37,330 --> 00:01:39,450
outside of the component function
35
00:01:39,450 --> 00:01:42,640
because that's not a function that needs to be rebuilt
36
00:01:42,640 --> 00:01:44,870
if the component is rebuilt
37
00:01:44,870 --> 00:01:47,380
and I will name it isNotEmpty,
38
00:01:49,410 --> 00:01:51,630
store my function in this constant
39
00:01:51,630 --> 00:01:54,540
and then just pass this constant here
40
00:01:54,540 --> 00:01:56,700
which holds this function in the end.
41
00:01:56,700 --> 00:01:59,210
So this is really just the function outsourced
42
00:01:59,210 --> 00:02:01,170
into a separate constant
43
00:02:01,170 --> 00:02:04,163
and I can do something similar for the email
44
00:02:04,163 --> 00:02:07,490
isEmail and here I get a value
45
00:02:07,490 --> 00:02:11,280
and check that this includes an @ symbol.
46
00:02:11,280 --> 00:02:15,233
And then I pass his email to the third user input call.
47
00:02:16,170 --> 00:02:19,120
Now the custom hook returns an object as we learned
48
00:02:19,120 --> 00:02:23,160
and that object is full of data which we can use.
49
00:02:23,160 --> 00:02:26,210
For example, it contains the value
50
00:02:26,210 --> 00:02:28,500
and we might wanna use the value here
51
00:02:28,500 --> 00:02:31,790
to be able to reset it once the form is submitted.
52
00:02:31,790 --> 00:02:33,890
So here, this is for my first input,
53
00:02:33,890 --> 00:02:35,803
I'll have the first name value,
54
00:02:36,960 --> 00:02:38,470
then we get IsValid.
55
00:02:38,470 --> 00:02:40,890
So this is firstNameIsValid
56
00:02:40,890 --> 00:02:43,340
and I'm assigning these aliases here
57
00:02:43,340 --> 00:02:47,650
because I'm going to extract the same keys two more times.
58
00:02:47,650 --> 00:02:50,643
So we need aliases to avoid name clashes.
59
00:02:51,720 --> 00:02:55,250
And here we also get to the value change handler
60
00:02:55,250 --> 00:02:59,360
which I'll alias with firstNameChangeHandler.
61
00:03:01,050 --> 00:03:04,670
I get the inputBlurHandler, which I pulled out
62
00:03:04,670 --> 00:03:07,650
which I alias with firstNameBlurHandler
63
00:03:09,230 --> 00:03:10,630
and the reset function,
64
00:03:10,630 --> 00:03:14,217
which I'll alias with resetFirstName like this.
65
00:03:18,440 --> 00:03:22,370
And then I'll copy this here this code
66
00:03:22,370 --> 00:03:25,630
and repeats these here for the second user input call.
67
00:03:25,630 --> 00:03:28,860
But of course here it's the last name value
68
00:03:28,860 --> 00:03:32,550
and the last name is valid
69
00:03:32,550 --> 00:03:35,776
and here it's there for all his lastNameChangeHandler
70
00:03:35,776 --> 00:03:37,510
and lastNameBlurHandler and resetlastName
71
00:03:41,070 --> 00:03:43,300
and then copy and paste it one more time
72
00:03:43,300 --> 00:03:48,300
for the last input and that's the email value
73
00:03:48,540 --> 00:03:49,540
and the emailIsValid
74
00:03:53,220 --> 00:03:56,510
and here it's the emailChangeHandler
75
00:03:56,510 --> 00:04:01,510
and the emailBlurHandler and here is resetEmail.
76
00:04:04,600 --> 00:04:06,250
And now with that all done,
77
00:04:06,250 --> 00:04:08,500
we can go down to the JSX code
78
00:04:08,500 --> 00:04:09,740
and on the first input,
79
00:04:09,740 --> 00:04:12,873
for example bind our firstNameValue,
80
00:04:15,457 --> 00:04:19,124
for onChange we bind firstNameChangeHandler,
81
00:04:20,628 --> 00:04:25,628
and for on blur, we bind the firstNameBlurHandler like this.
82
00:04:29,400 --> 00:04:32,690
Then for the second input,
83
00:04:32,690 --> 00:04:36,387
we bind value to lastNameValue onChange
84
00:04:38,850 --> 00:04:40,520
to lastNameChangeHandler
85
00:04:42,720 --> 00:04:46,733
and on blur unsurprisingly to lastNameBlurHandler.
86
00:04:47,940 --> 00:04:50,210
And then here for this input,
87
00:04:50,210 --> 00:04:53,770
I bind my value to emailValue onChange
88
00:04:55,247 --> 00:04:59,490
to the emailChangeHandler
89
00:04:59,490 --> 00:05:04,403
and onBlur to the emailBlurHandler.
90
00:05:06,220 --> 00:05:10,610
Now, I also wanna show error messages if appropriate
91
00:05:10,610 --> 00:05:13,050
and I wanna show different class names
92
00:05:13,050 --> 00:05:15,170
or add different class names.
93
00:05:15,170 --> 00:05:18,270
And I also want to disable the submit button
94
00:05:18,270 --> 00:05:20,763
if the form is invalid.
95
00:05:21,890 --> 00:05:25,360
So let's start with the class names and the error texts.
96
00:05:25,360 --> 00:05:27,790
For this there's one other field we can extract
97
00:05:27,790 --> 00:05:29,930
and that's the hasError field,
98
00:05:29,930 --> 00:05:34,653
which I'll store in firstNameHasError alias,
99
00:05:35,790 --> 00:05:39,130
and here on the second use input called
100
00:05:39,130 --> 00:05:41,530
its last name has error
101
00:05:41,530 --> 00:05:45,580
and here on the third custom hook you search
102
00:05:45,580 --> 00:05:48,130
it's emailHasError.
103
00:05:48,130 --> 00:05:52,050
And it's this HasError field, which we can now use
104
00:05:52,050 --> 00:05:56,190
because now we can infer those class names for example.
105
00:05:56,190 --> 00:05:58,567
Here I have my firstNameClasses
106
00:06:00,347 --> 00:06:03,980
and for that I'll take my firstNameHasError key.
107
00:06:03,980 --> 00:06:05,380
And if I have an error,
108
00:06:05,380 --> 00:06:08,810
I'll add a class of form-control invalid,
109
00:06:08,810 --> 00:06:12,100
otherwise just form-control
110
00:06:12,100 --> 00:06:17,100
and all I will repeat this error for lastNameClasses
111
00:06:17,331 --> 00:06:18,748
and emailClasses.
112
00:06:20,930 --> 00:06:24,134
And here we then have to lastNameHasError
113
00:06:24,134 --> 00:06:25,634
and emailHasError.
114
00:06:30,330 --> 00:06:34,647
And then here we bind our firstNameClasses
115
00:06:36,060 --> 00:06:40,093
and we'll the second div, we bind the lastNameClasses
116
00:06:41,980 --> 00:06:46,050
and on that last div we bind the emailClasses.
117
00:06:49,490 --> 00:06:51,780
Now for the error messages,
118
00:06:51,780 --> 00:06:53,840
we simply go to the first input
119
00:06:53,840 --> 00:06:56,560
where we might need an error message like,
120
00:06:56,560 --> 00:06:59,863
Please enter first name.
121
00:07:00,760 --> 00:07:03,640
And here we check if firstNameHasError
122
00:07:03,640 --> 00:07:07,053
and if that's the case we showed as paragraph otherwise not.
123
00:07:07,980 --> 00:07:10,980
And I then copied that logic to the second input
124
00:07:10,980 --> 00:07:13,520
where I say, Please enter a last name
125
00:07:13,520 --> 00:07:15,907
and I checked for lastNameHasError
126
00:07:17,260 --> 00:07:19,950
and we copied one more time to the email address
127
00:07:19,950 --> 00:07:22,290
where I check for emailHasError
128
00:07:22,290 --> 00:07:26,203
and I said, Please enter a valid email address.
129
00:07:27,100 --> 00:07:28,733
So now that's all wired up.
130
00:07:29,770 --> 00:07:32,040
Now for the overall foreign validity,
131
00:07:32,040 --> 00:07:34,330
we can again derive that state,
132
00:07:34,330 --> 00:07:38,610
we can add a formIsValid state, which initially is false.
133
00:07:38,610 --> 00:07:42,327
And then we check if the firstNameIsValid
134
00:07:43,512 --> 00:07:45,429
and the lastNameIsValid
135
00:07:46,331 --> 00:07:50,540
and the emailIsValid and all three have to be valid.
136
00:07:50,540 --> 00:07:54,210
And only if they are all free valid,
137
00:07:54,210 --> 00:07:56,410
I'll set formIsValid to true.
138
00:07:56,410 --> 00:07:58,690
If at least one of them is not valid,
139
00:07:58,690 --> 00:08:00,853
the form will stay invalid.
140
00:08:03,160 --> 00:08:05,870
So now we have the formIsValid state
141
00:08:05,870 --> 00:08:08,840
we can use that to disable the button for example,
142
00:08:08,840 --> 00:08:13,110
to set disabled to not formIsValid.
143
00:08:13,110 --> 00:08:16,053
If the form is not valid, the button is disabled.
144
00:08:18,380 --> 00:08:20,660
Last but not least for the form submission
145
00:08:20,660 --> 00:08:22,230
which I also wanna add here,
146
00:08:22,230 --> 00:08:24,679
I'll add the onSubmitHandler
147
00:08:24,679 --> 00:08:27,343
and then simply add a new function here,
148
00:08:28,262 --> 00:08:32,909
submitHandler could be the name where I get an event.
149
00:08:32,909 --> 00:08:36,669
And as you learned, we call event.preventDefault here
150
00:08:36,669 --> 00:08:40,549
to prevent that browser default of sending a request.
151
00:08:40,549 --> 00:08:45,330
And then I check if the form is not valid
152
00:08:46,580 --> 00:08:48,360
and if it's not valid, I return
153
00:08:49,380 --> 00:08:50,940
and that's by the way new,
154
00:08:50,940 --> 00:08:53,500
in simple input I didn't do that,
155
00:08:53,500 --> 00:08:55,140
in the form submission handler
156
00:08:55,140 --> 00:08:58,980
there I was still checking for the entered name only
157
00:08:58,980 --> 00:09:01,460
and that was an oversight from my side
158
00:09:01,460 --> 00:09:03,870
but of course we can't even reach that handler
159
00:09:03,870 --> 00:09:06,140
since the button is disabled anyways.
160
00:09:06,140 --> 00:09:09,640
Nonetheless, adding that extra check here might make sense
161
00:09:09,640 --> 00:09:12,680
because the user could theoretically enable the button
162
00:09:12,680 --> 00:09:14,270
with the def tools,
163
00:09:14,270 --> 00:09:17,130
which of course is not really what the user should do,
164
00:09:17,130 --> 00:09:18,410
but it could be done.
165
00:09:18,410 --> 00:09:20,760
So having the extra validation step in here
166
00:09:20,760 --> 00:09:23,270
still also could make sense.
167
00:09:23,270 --> 00:09:26,980
And then they're after if the form is valid
168
00:09:26,980 --> 00:09:29,250
and we made it past to this check,
169
00:09:29,250 --> 00:09:33,050
I will console.log Submitted
170
00:09:34,890 --> 00:09:37,260
and then all the console.log my values.
171
00:09:37,260 --> 00:09:39,780
So the firstNameValue
172
00:09:39,780 --> 00:09:43,373
the lastNameValue and the emailValue.
173
00:09:45,550 --> 00:09:49,701
And then I will call resetFirstName,
174
00:09:49,701 --> 00:09:53,100
resetLastName and resetEmail.
175
00:09:55,330 --> 00:09:57,510
Now we can wire up the submit handler here
176
00:09:59,080 --> 00:10:01,530
and we should be good to go.
177
00:10:01,530 --> 00:10:04,440
If we save everything and go back here,
178
00:10:04,440 --> 00:10:06,570
the button is grayed out by default.
179
00:10:06,570 --> 00:10:08,680
If I click in there, I get this error
180
00:10:08,680 --> 00:10:11,540
and this error and this error
181
00:10:11,540 --> 00:10:13,440
and the errors are not red
182
00:10:13,440 --> 00:10:18,000
because I forgot to assign the right CSS class here.
183
00:10:18,000 --> 00:10:22,070
On these paragraphs we should add a CSS class of error-text.
184
00:10:24,850 --> 00:10:28,300
So make sure you add this on the firstNameError paragraph
185
00:10:28,300 --> 00:10:33,300
and the lastName paragraph and the emailError paragraph.
186
00:10:34,060 --> 00:10:35,163
Now they are red.
187
00:10:36,020 --> 00:10:40,390
And of course if I enter valid values here,
188
00:10:40,390 --> 00:10:44,020
then this becomes submittable
189
00:10:44,020 --> 00:10:46,690
and if you open the def tools and I click Submit
190
00:10:46,690 --> 00:10:50,343
I see Submitted, I see the entered values and its reset.
191
00:10:51,210 --> 00:10:55,240
And again, it's working as before now.
192
00:10:55,240 --> 00:10:57,140
So this is looking good now
193
00:10:57,140 --> 00:10:59,270
and now we applied our custom hook
194
00:10:59,270 --> 00:11:03,393
and what we learned to this new form as well.
15141
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.