WEBVTT

0
00:00.720 --> 00:02.010
Did you give it a go?

1
00:02.280 --> 00:02.970
I hope so.

2
00:02.970 --> 00:03.510
I hope so.

3
00:03.510 --> 00:05.490
But don't worry if you couldn't quite figure it out.

4
00:05.520 --> 00:11.360
It is a bit tricky and there is a very tricky nuance when working with the Constraint Validation API.

5
00:11.400 --> 00:14.670
So I'm going to show you how we resolve it. Before we do,

6
00:14.700 --> 00:15.740
here's our HTML.

7
00:15.750 --> 00:20.370
We've got a label which is just asking for the username and of course we've got our input type of text.

8
00:20.400 --> 00:24.660
We've got our required attribute on there and there is the pattern -

9
00:25.770 --> 00:29.310
the regex that we spoke about in the introduction video.

10
00:30.520 --> 00:31.180
Very, very simple.

11
00:31.180 --> 00:33.730
And if we go to the browser, this is what it looks like.

12
00:33.730 --> 00:38.080
But right now the user can, or obviously the user will be prevented from submitting the form.

13
00:38.080 --> 00:43.180
We've got a default error message which we want to change and the user can just type anything.

14
00:43.660 --> 00:48.970
Oh, of course it has to match the regex, smaller case uppercase, then the user can submit.

15
00:49.090 --> 00:52.090
But we want our own custom error messages.

16
00:52.090 --> 00:53.170
How does that work?

17
00:53.170 --> 00:56.050
Well, as you know, we have to wrap everything in ....

18
00:58.550 --> 00:59.300
that's right,

19
00:59.300 --> 01:00.420
script tags.

20
01:00.440 --> 01:04.770
The first thing we want to do is we want to access this Constraint Validation API.

21
01:04.830 --> 01:08.120
In order to do that, we have to work with some interface.

22
01:08.120 --> 01:10.970
The one we're going to work with here is this input element.

23
01:10.970 --> 01:12.140
So let's grab it.

24
01:12.170 --> 01:18.680
Let's define a variable called nameInput and we can access our document, querySelector(), and we

25
01:18.680 --> 01:21.500
want to query select our input element.

26
01:21.530 --> 01:22.940
It really, really is that simple.

27
01:22.940 --> 01:25.760
That's the first step. 
(sound effect: mission completed)

28
01:25.790 --> 01:33.200
Now, what I want to do is I want to access this variable, aka the element of input, and we want to

29
01:33.200 --> 01:35.990
add our own event listener. And I gave you a clue, didn't I?

30
01:36.260 --> 01:43.370
I want to listen for the invalid event. And the invalid event is going to be fired every time the value

31
01:43.370 --> 01:45.920
of the input does not meet that pattern

32
01:45.920 --> 01:46.790
regex,

33
01:46.800 --> 01:47.270
right.

34
01:47.270 --> 01:51.830
Also, we're going to get this invalid event when the required value is specified, but of course there

35
01:51.830 --> 01:53.900
is no value associated with that input.

36
01:53.900 --> 01:56.990
So when this event is fired, what do we want to happen?

37
01:57.230 --> 02:00.300
Well, we want to execute our callback function.

38
02:37.380 --> 02:38.640
Well, let's tackle the first issue.

39
02:38.640 --> 02:41.940
And the first issue is if nothing is entered into that input box.

40
02:42.060 --> 02:48.330
Well, in that case, we know that our name input is going to have a value and that value is going to

41
02:48.330 --> 02:49.770
be an empty string.

42
02:49.770 --> 02:49.960
Right?

43
02:49.960 --> 02:50.730
There's going to be nothing.

44
02:50.730 --> 02:57.030
And if that occurs, if this is true, then we want to define our own custom error message.

45
02:57.600 --> 02:58.950
We already know how to do this.

46
02:58.980 --> 03:06.540
We can access our element, and now we're using the Constraint Validation API because we can access the

47
03:06.540 --> 03:09.870
setCustomValidity() message directly.

48
03:09.900 --> 03:15.270
We can just say "Silly billy, you have not typed anything."

49
03:16.850 --> 03:18.230
Right, and we can save this.

50
03:18.230 --> 03:20.960
Let's go to the browser and test it. Go to the browser. 

51
03:21.320 --> 03:22.400
Try and submit.

52
03:22.400 --> 03:23.150
And there we go.

53
03:23.150 --> 03:25.100
We've got our own custom error message.

54
03:25.100 --> 03:31.340
But you'll notice if now the user types characters and tries to submit, we keep getting this error

55
03:31.340 --> 03:32.000
message.

56
03:32.000 --> 03:37.760
Because remember I said once we use the setCustomValidity() method, we're telling the browser that

57
03:37.760 --> 03:42.980
that element is invalid regardless of whether it's actually not invalid anymore.

58
03:42.980 --> 03:45.650
And that's the slight nuance that I was telling you about earlier.

59
03:45.650 --> 03:47.840
But anyway, we're going to solve that shortly.

60
03:48.110 --> 03:55.820
We've dealt with the first issue where we get an invalid event and the name input does not have a value.

61
03:55.820 --> 03:57.470
So we've dealt with that scenario.

62
03:58.190 --> 04:00.110
Now we're going to deal with the next scenario.

63
04:00.110 --> 04:06.710
So when we reach this ELSE block, we know that, (a) we've got an invalid event and (b), we know the

64
04:06.710 --> 04:08.930
user has typed some characters.

65
04:09.320 --> 04:12.320
So again, let's set our own custom error message here,

66
04:12.440 --> 04:23.990
setCustomValidity() method, and here we can say "Usernames need to contain at least one uppercase

67
04:25.640 --> 04:28.190
and one lowercase

68
04:29.400 --> 04:29.850
letter. 

69
04:30.420 --> 04:31.530
Try again."

70
04:32.570 --> 04:33.830
So let's save this.

71
04:33.860 --> 04:34.370
All right.

72
04:34.370 --> 04:35.600
Let's go to the browser and test this.

73
04:35.600 --> 04:35.870
Right.

74
04:35.870 --> 04:41.390
If the user starts typing, clicks submit, we get our own custom error message.

75
04:41.570 --> 04:42.580
Very, very cool.

76
04:42.590 --> 04:47.600
But you'll notice now we have a problem because if the user then types a capital letter, so we've got

77
04:47.630 --> 04:48.830
one uppercase, one lowercase,

78
04:48.830 --> 04:54.730
if the user submits, we're going to be in this perpetual state where we are always having an error.

79
04:54.740 --> 04:59.960
Remember, it's because we've used the setCustomValidity() method which tells the browser that this

80
04:59.960 --> 05:03.480
input box is always going to be invalid.

81
05:03.500 --> 05:04.790
How do we stop it?

82
05:04.910 --> 05:10.580
Well, remember, we have to set the custom validity message to an empty string, and when it's an empty

83
05:10.610 --> 05:12.340
string it will be valid.

84
05:12.350 --> 05:13.100
Remember that.

85
05:13.100 --> 05:14.440
But we can't set it ...

86
05:14.810 --> 05:19.880
if we look at our code, we can't set the setCustomValidity message to an empty string here because

87
05:19.880 --> 05:23.180
this is when we're dealing with an invalid error.

88
05:23.690 --> 05:27.830
So what we have to actually do, and this is the slight nuance I was telling you about, right,

89
05:27.830 --> 05:32.790
we have to access our nameInput, add another event listener and this event listener is just going

90
05:32.790 --> 05:35.430
to be listening for the input event,

91
05:38.370 --> 05:38.610
right.

92
05:38.610 --> 05:43.650
So every time a character is typed, I want to listen for this event and we want to access our 

93
05:43.650 --> 05:44.400
nameInput.

94
05:44.610 --> 05:49.110
And this time I want to set the custom validity to an empty string.

95
05:49.290 --> 05:49.700
Right.

96
05:49.710 --> 05:51.660
That's all I want to do.

97
05:51.660 --> 05:54.120
And to prove that this works, let's go to the browser.

98
05:54.300 --> 05:55.170
If the user types

99
05:55.170 --> 05:56.760
nothing, gets an error

100
05:56.760 --> 05:58.560
message. Starts typing,

101
05:59.670 --> 06:02.730
uh, let's do a capital "D", tries to submit, 

102
06:02.760 --> 06:06.750
now we are allowed to do so. If the user just types lowercase and clicks submit

103
06:06.780 --> 06:08.450
we get a custom error message.

104
06:08.460 --> 06:11.460
But did you notice there's a problem, my dear students.

105
06:11.460 --> 06:12.480
Did you notice it?

106
06:12.500 --> 06:14.430
It was very, very slight.

107
06:14.430 --> 06:15.890
But you may have picked it up.

108
06:15.900 --> 06:17.130
We know the first step works.

109
06:17.130 --> 06:18.450
"Silly billy, you've not typed anything."

110
06:18.450 --> 06:20.070
But if now the user types the character 

111
06:20.070 --> 06:21.780
"a", look at that.

112
06:21.780 --> 06:24.000
We're getting the error message displayed by the browser.

113
06:24.000 --> 06:26.570
We're not getting our custom error message.

114
06:26.580 --> 06:33.570
In fact, we only going to get our custom error message when the user hits submit because only when

115
06:33.570 --> 06:34.830
submit is issued,

116
06:35.560 --> 06:43.120
is this invalid error message emitted, and only then do our custom error messages apply.

117
06:43.770 --> 06:45.150
We don't want that to happen.

118
06:45.150 --> 06:47.910
So every time a character is pressed, right,

119
06:47.910 --> 06:54.960
in other words, every time an input event is fired, we want to fire off another method on our constraint

120
06:54.960 --> 06:56.310
validation API.

121
06:56.340 --> 07:03.270
We want to execute the checkValidity() method because if that is false, the invalid event is going to

122
07:03.270 --> 07:05.370
be fired and our code will execute.

123
07:05.400 --> 07:09.350
So if we do that on every single iteration, that should solve our problem.

124
07:09.360 --> 07:10.950
So let's refresh the browser.

125
07:11.280 --> 07:11.580
Okay.

126
07:11.580 --> 07:17.790
We can submit - "Silly billy, you have not typed anything". But if now the user types the character "a" boom, how

127
07:17.790 --> 07:18.510
awesome is that?

128
07:18.510 --> 07:24.090
We get our own custom error message. And of course it's going to happen until you know we can hit submit

129
07:24.090 --> 07:24.630
again.

130
07:24.630 --> 07:28.020
It's going to happen until we have a capital letter.

131
07:28.050 --> 07:28.740
There we go.

132
07:28.740 --> 07:31.140
And if we now submit, we are allowed to do so.

133
07:31.820 --> 07:33.560
The user can just do a capital D.

134
07:33.590 --> 07:35.570
Let's just do capitals submit.

135
07:35.600 --> 07:36.380
It's not working.

136
07:36.380 --> 07:37.740
It's not working.

137
07:37.760 --> 07:41.090
But as soon as the user then goes to lowercase.

138
07:42.130 --> 07:43.840
We can now submit.

139
07:44.560 --> 07:48.340
I know, I know this can be quite confusing, but let's just jump to the code.

140
07:48.340 --> 07:51.340
It really is quite intuitive once you understand what's going on.

141
07:51.670 --> 07:59.020
If we use the setCustomValidity() method and we write our own custom message, we are basically in a perpetual

142
07:59.020 --> 08:05.590
state of an error - we're telling the browser the input is in an invalid state and our custom error

143
08:05.590 --> 08:06.430
message should be shown.

144
08:06.430 --> 08:09.820
That's why we couldn't just rely on our one block of code here

145
08:09.820 --> 08:15.400
by listening for the invalid event. We had to create another type of event we listen for, and that

146
08:15.400 --> 08:17.920
is every time the user types a character.

147
08:18.070 --> 08:20.020
So let's start there.

148
08:20.110 --> 08:23.530
We know that we do two things when that input event is fired.

149
08:23.560 --> 08:24.790
Let me say it another way.

150
08:24.790 --> 08:28.020
Every time the user types a character, we do two things.

151
08:28.030 --> 08:35.160
One, we start off by saying, Hey, let's set the custom validity method's value to an empty string.

152
08:35.170 --> 08:39.670
In other words, let's start off by saying that we are in a valid state.

153
08:39.790 --> 08:42.710
I know it sounds strange, but hear me out.

154
08:42.740 --> 08:47.690
The next thing we do is we fire off this checkValidity() method.

155
08:47.690 --> 08:50.060
And remember in the lecture we discussed this.

156
08:50.810 --> 08:56.060
If everything is fine on that input, true gets returned and nothing else happens.

157
08:56.210 --> 08:59.180
So therefore the browser will submit the form.

158
08:59.360 --> 09:00.350
But.

159
09:01.990 --> 09:11.080
If there is an error, then we know that this checkValidity() method is going to fire an invalid event.

160
09:11.900 --> 09:18.530
And in that case, our next block of entire code will capture the entire process.

161
09:18.530 --> 09:22.310
And that's why it either shows the error message to the user, 

162
09:22.310 --> 09:25.160
"Silly billy, you've not typed anything" when it's an empty string.

163
09:25.310 --> 09:29.690
Alternatively, in the ELSE statement if the user has typed characters but we're still getting this

164
09:29.720 --> 09:32.150
invalid error, we've got another message.

165
09:32.150 --> 09:35.510
"Usernames need to contain at least one uppercase and one lowercase letter.

166
09:35.510 --> 09:37.690
Try again." And then we start again.

167
09:37.700 --> 09:40.730
So say the user types a lowercase and an uppercase.

168
09:40.760 --> 09:46.340
In that case, when that user types that uppercase, this first block of code is going to apply because

169
09:46.340 --> 09:51.890
it's an input event, we're going to set it to valid and then the checkValidity() method is going to

170
09:51.890 --> 09:52.520
return

171
09:52.520 --> 09:53.270
true.

172
09:53.270 --> 09:55.670
And that's why we are allowed to submit the form.

173
09:56.060 --> 10:00.650
I know it can be quite complex, but really go through it again, go through this lecture a few times,

174
10:00.650 --> 10:01.670
make sure you understand it.

175
10:01.670 --> 10:03.470
It really will help you down the track.

176
10:03.470 --> 10:06.280
And once you get it, it really, really is intuitive.

177
10:06.290 --> 10:08.600
So anyway, I hope you had a lot of fun in this lecture.

178
10:08.600 --> 10:09.590
I know I did.

179
10:09.590 --> 10:11.460
But let's continue.

180
10:11.490 --> 10:13.020
See you in the next lecture.