Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
1
00:00:01,390 --> 00:00:03,390
So, as I just said,
2
2
00:00:03,390 --> 00:00:07,670
let's now start with the feature of uploading a new recipe
3
3
00:00:07,670 --> 00:00:11,870
and start with the ability of opening the model window,
4
4
00:00:11,870 --> 00:00:15,173
which contains the form to add the new recipe.
5
5
00:00:16,690 --> 00:00:21,040
So in the demo version, this is what it looks like.
6
6
00:00:21,040 --> 00:00:23,150
So here we click add recipe,
7
7
00:00:23,150 --> 00:00:26,160
and then it opens up this form like this,
8
8
00:00:26,160 --> 00:00:27,980
and then when we click this button,
9
9
00:00:27,980 --> 00:00:30,170
or click outside of the form,
10
10
00:00:30,170 --> 00:00:32,743
then that window will again close.
11
11
00:00:34,160 --> 00:00:36,709
Alright, so let's do that,
12
12
00:00:36,709 --> 00:00:39,913
and let's create a new bookmark's view.
13
13
00:00:42,290 --> 00:00:45,220
And actually not a bookmark's view,
14
14
00:00:45,220 --> 00:00:47,427
but a addRecipeView.js
15
15
00:00:52,550 --> 00:00:55,510
And now let's go to one of these views,
16
16
00:00:55,510 --> 00:00:57,233
and copy the code from there.
17
17
00:01:00,360 --> 00:01:03,533
Because this code is always very similar,
18
18
00:01:05,420 --> 00:01:08,520
so let's delete this one here,
19
19
00:01:08,520 --> 00:01:10,733
let's empty out this method.
20
20
00:01:13,903 --> 00:01:17,270
And then here, let's call it AddRecipeView.
21
21
00:01:22,220 --> 00:01:26,080
Now this view here is actually gonna be quite different
22
22
00:01:26,080 --> 00:01:29,126
from the other views because we already have
23
23
00:01:29,126 --> 00:01:31,963
actually the view in the HTML.
24
24
00:01:33,530 --> 00:01:36,280
So if we come here to our HTML code,
25
25
00:01:36,280 --> 00:01:39,609
then you see that the form that we want to display
26
26
00:01:39,609 --> 00:01:44,609
is actually already here in the code, all right?
27
27
00:01:45,000 --> 00:01:48,270
So, here we have this element for the overlay
28
28
00:01:48,270 --> 00:01:50,411
and this element for the window
29
29
00:01:50,411 --> 00:01:53,540
and they both have the hidden class.
30
30
00:01:53,540 --> 00:01:56,170
And so showing the window and the overlay
31
31
00:01:56,170 --> 00:01:59,380
is gonna be as simple as removing this hidden class
32
32
00:01:59,380 --> 00:02:01,093
from both these elements.
33
33
00:02:02,140 --> 00:02:04,680
Now, the main element that we are actually
34
34
00:02:04,680 --> 00:02:08,500
really interested in is this upload element.
35
35
00:02:08,500 --> 00:02:11,200
And so let's actually make this upload element,
36
36
00:02:11,200 --> 00:02:14,563
the parent element of the AddRecipeView.
37
37
00:02:16,330 --> 00:02:19,520
So upload here, but then we will also have
38
38
00:02:19,520 --> 00:02:23,470
to select some other elements.
39
39
00:02:23,470 --> 00:02:26,260
So for example, the window and the overlay,
40
40
00:02:26,260 --> 00:02:28,310
so to start at least.
41
41
00:02:28,310 --> 00:02:33,257
So the window element is going to be document.querySelector
42
42
00:02:35,100 --> 00:02:36,950
and then let's see what we have here.
43
43
00:02:38,040 --> 00:02:40,343
Here we can close all of these for now.
44
44
00:02:41,400 --> 00:02:44,160
So that's add recipe window.
45
45
00:02:44,160 --> 00:02:47,193
And then the overlay has simply the overlay class.
46
46
00:02:50,570 --> 00:02:55,570
And so here, overlay and here as well.
47
47
00:02:57,090 --> 00:03:01,787
And here we are missing the dot on both selectors.
48
48
00:03:01,787 --> 00:03:04,530
And now we also need to select a button
49
49
00:03:04,530 --> 00:03:06,840
that will be clicked to open the window
50
50
00:03:06,840 --> 00:03:10,493
and also the button to close the window.
51
51
00:03:11,510 --> 00:03:15,353
So that button is somewhere here in the top navigation bar.
52
52
00:03:16,940 --> 00:03:21,940
So this is for the bookmarks and here it is.
53
53
00:03:23,810 --> 00:03:27,083
So this is the button for adding the recipe as you see.
54
54
00:03:28,500 --> 00:03:30,590
So let's call that the btnOpen
55
55
00:03:37,179 --> 00:03:40,014
and then also the button to close the form.
56
56
00:03:40,014 --> 00:03:43,295
And so that's back here somewhere in the window.
57
57
00:03:43,295 --> 00:03:45,462
So that's btn-close-model.
58
58
00:03:48,987 --> 00:03:50,237
Okay, and here.
59
59
00:03:55,594 --> 00:03:59,523
Okay and so now, let's listen for the events,
60
60
00:03:59,523 --> 00:04:03,856
so of clicking the open button and the close button.
61
61
00:04:04,970 --> 00:04:08,500
Okay, and as always, we will do that in a method called
62
62
00:04:08,500 --> 00:04:11,280
addHandler and then something,
63
63
00:04:11,280 --> 00:04:13,043
just to make it more consistent.
64
64
00:04:13,920 --> 00:04:18,713
So addHandlerShowWindow, let's say,
65
65
00:04:21,270 --> 00:04:23,913
and so here we will want to select the button.
66
66
00:04:25,240 --> 00:04:30,240
So btnOpen.addEventListener of a click.
67
67
00:04:33,380 --> 00:04:36,883
And so when that happens, what do we want to do?
68
68
00:04:37,870 --> 00:04:41,560
Well, we want to take the overlay into window
69
69
00:04:41,560 --> 00:04:44,470
and remove the hidden class.
70
70
00:04:44,470 --> 00:04:49,470
So that's this.overlay.classList.rem.
71
71
00:04:55,750 --> 00:04:59,960
Now, instead of remove, we can actually also use toggle.
72
72
00:04:59,960 --> 00:05:04,010
So remember that toggle will add to class if it's not there
73
73
00:05:04,010 --> 00:05:06,680
and it will remove the class when it is already there.
74
74
00:05:06,680 --> 00:05:09,174
And so this will make it a lot easier
75
75
00:05:09,174 --> 00:05:11,663
to then reuse this class.
76
76
00:05:12,880 --> 00:05:16,623
So the overlay and also the window.
77
77
00:05:18,950 --> 00:05:22,090
Okay, now, when do we actually want
78
78
00:05:22,090 --> 00:05:24,283
this function here to be called?
79
79
00:05:26,010 --> 00:05:30,540
Well, we want this to be called as soon as the page loads.
80
80
00:05:30,540 --> 00:05:32,600
Now, in this case, this has nothing to do
81
81
00:05:32,600 --> 00:05:36,080
with any controller because there is nothing special
82
82
00:05:36,080 --> 00:05:40,620
happening here that the controller needs to tell us, right?
83
83
00:05:40,620 --> 00:05:44,020
So when this click happens on the button open,
84
84
00:05:44,020 --> 00:05:47,885
all that will happen is really for the window to show.
85
85
00:05:47,885 --> 00:05:50,600
So the controller, it doesn't need to interfere
86
86
00:05:50,600 --> 00:05:54,010
in any of this and so therefore we can simply run
87
87
00:05:54,010 --> 00:05:58,123
this function here as soon as this object is created.
88
88
00:05:59,980 --> 00:06:01,820
And so what I'm gonna do is
89
89
00:06:01,820 --> 00:06:04,263
to this time add a constructor method,
90
90
00:06:07,100 --> 00:06:09,220
then since this is a child class,
91
91
00:06:09,220 --> 00:06:12,133
we need to start by calling super.
92
92
00:06:13,230 --> 00:06:16,450
And so only after that, we can use the this keywords.
93
93
00:06:16,450 --> 00:06:18,750
And then let's say, this.addHandlerShowWindow.
94
94
00:06:22,446 --> 00:06:25,780
And so this one here is now only gonna be
95
95
00:06:25,780 --> 00:06:28,240
used inside of this class.
96
96
00:06:28,240 --> 00:06:33,240
And so let's add an underscore to mark it as protected.
97
97
00:06:34,340 --> 00:06:37,790
And so again, in order to show this window,
98
98
00:06:37,790 --> 00:06:42,110
the controller does not interfere at all, all right?
99
99
00:06:42,110 --> 00:06:44,805
Now what we will have to do in the controller still
100
100
00:06:44,805 --> 00:06:48,360
is to import this object here
101
101
00:06:48,360 --> 00:06:52,430
because otherwise, our main script sort of controller
102
102
00:06:52,430 --> 00:06:54,490
will never execute this file.
103
103
00:06:54,490 --> 00:06:58,000
And so then this object here will never be created.
104
104
00:06:58,000 --> 00:07:01,593
And so the event listener here will never be added.
105
105
00:07:02,550 --> 00:07:05,060
And so we need to, again, import this
106
106
00:07:05,060 --> 00:07:07,010
so that the code that is in the module
107
107
00:07:07,010 --> 00:07:08,563
is actually being run.
108
108
00:07:11,620 --> 00:07:16,620
So here let's call that the AddRecipeView.
109
109
00:07:21,360 --> 00:07:23,830
And now let's check out our code
110
110
00:07:23,830 --> 00:07:25,893
just to make sure we reload it.
111
111
00:07:27,230 --> 00:07:30,653
And we got a class list of undefined.
112
112
00:07:31,760 --> 00:07:34,690
So some small bug here, and again,
113
113
00:07:34,690 --> 00:07:36,643
you see how common that is.
114
114
00:07:38,130 --> 00:07:41,350
So let's again, see which line that actually was.
115
115
00:07:41,350 --> 00:07:42,653
So line 19.
116
116
00:07:43,660 --> 00:07:45,633
So with the overlay.
117
117
00:07:46,890 --> 00:07:48,943
So let's see if the class is correct.
118
118
00:07:51,320 --> 00:07:52,663
Well, it looks so.
119
119
00:07:56,010 --> 00:07:58,730
No, but I can see the error now.
120
120
00:07:58,730 --> 00:08:00,860
So here we are using the this keyword
121
121
00:08:00,860 --> 00:08:03,390
inside of a handler, right?
122
122
00:08:03,390 --> 00:08:05,840
But you already know that the this keyword
123
123
00:08:05,840 --> 00:08:08,717
inside of a handler function points to the element
124
124
00:08:08,717 --> 00:08:12,320
on which that listener is attached to.
125
125
00:08:12,320 --> 00:08:15,023
So in this case, that is this button here.
126
126
00:08:15,900 --> 00:08:19,490
And so let's actually export this entire function
127
127
00:08:19,490 --> 00:08:22,283
into another method and then call that method
128
128
00:08:22,283 --> 00:08:25,963
with the correct this keyword bound to it.
129
129
00:08:28,000 --> 00:08:31,937
So here is what I mean, toggleWindow, let's say,
130
130
00:08:36,770 --> 00:08:38,810
will do this and then here,
131
131
00:08:38,810 --> 00:08:43,597
we want to call this.toggleWindow.
132
132
00:08:44,610 --> 00:08:48,980
And now here we can use our bind method as always,
133
133
00:08:48,980 --> 00:08:51,930
and then bind the correct this keyword.
134
134
00:08:51,930 --> 00:08:54,075
So we have done this many times before,
135
135
00:08:54,075 --> 00:08:57,230
so basically manually setting the this keyword
136
136
00:08:57,230 --> 00:08:59,770
inside of this function here,
137
137
00:08:59,770 --> 00:09:03,232
now to the this keyword that we actually want it to be.
138
138
00:09:03,232 --> 00:09:06,210
And so right here, this of course,
139
139
00:09:06,210 --> 00:09:08,660
points to the current object
140
140
00:09:08,660 --> 00:09:11,630
because otherwise, again, the this keywords
141
141
00:09:11,630 --> 00:09:15,810
inside of this function would be the button
142
142
00:09:15,810 --> 00:09:17,973
on which the event listener is attached to.
143
143
00:09:19,050 --> 00:09:22,803
And so with this, it should now work and yeah,
144
144
00:09:23,740 --> 00:09:25,373
there is our form.
145
145
00:09:26,470 --> 00:09:29,140
And now, all we have to do is to close that form
146
146
00:09:29,140 --> 00:09:32,453
when we click this button or click outside here.
147
147
00:09:36,600 --> 00:09:37,900
So addHandlerHeightWindow.
148
148
00:09:44,540 --> 00:09:48,160
And so that's actually very similar to this one,
149
149
00:09:48,160 --> 00:09:50,653
that's just duplicated actually.
150
150
00:09:53,400 --> 00:09:58,400
So btnClose and then the same also on the overlay.
151
151
00:10:00,900 --> 00:10:02,750
And so that's why this toggle here
152
152
00:10:02,750 --> 00:10:06,050
is now very useful because here at this point,
153
153
00:10:06,050 --> 00:10:08,259
when we want to hide the window,
154
154
00:10:08,259 --> 00:10:11,040
then the hidden class is no longer there,
155
155
00:10:11,040 --> 00:10:13,823
but it will then automatically add it back on.
156
156
00:10:16,040 --> 00:10:18,837
Now, and before we actually try it,
157
157
00:10:18,837 --> 00:10:23,003
we first of course, need to call this method here as well.
158
158
00:10:28,500 --> 00:10:31,303
Okay, and it's gone.
159
159
00:10:32,670 --> 00:10:35,800
Great, so that works.
160
160
00:10:35,800 --> 00:10:40,390
And so next up, let's take care of handling this button here
161
161
00:10:40,390 --> 00:10:42,020
and for now what we want to do
162
162
00:10:42,020 --> 00:10:45,330
when we click this button is to get all the data here
163
163
00:10:45,330 --> 00:10:46,653
out of this form.
164
164
00:10:47,510 --> 00:10:49,610
And you see that I already have like,
165
165
00:10:49,610 --> 00:10:51,570
pre-filled this data here.
166
166
00:10:51,570 --> 00:10:56,090
And so that comes from the HTML here
167
167
00:10:56,090 --> 00:10:58,927
because the value is basically already set.
168
168
00:10:58,927 --> 00:11:02,780
But then of course, by the end, we will remove this.
169
169
00:11:02,780 --> 00:11:05,163
So this is just for development purposes.
170
170
00:11:07,550 --> 00:11:11,680
But anyway, let's now create another method here,
171
171
00:11:11,680 --> 00:11:16,620
which is going to handle the click on that button.
172
172
00:11:16,620 --> 00:11:19,053
So basically the form submission.
173
173
00:11:23,440 --> 00:11:25,290
So addHandlerUpload.
174
174
00:11:28,990 --> 00:11:32,970
And so here we will now actually listen for an event
175
175
00:11:32,970 --> 00:11:35,240
right on the parent element.
176
176
00:11:35,240 --> 00:11:37,423
So that is the upload form itself.
177
177
00:11:38,790 --> 00:11:42,865
So parentElement.addEventListener
178
178
00:11:42,865 --> 00:11:47,547
for submit and then inner function as always,
179
179
00:11:49,350 --> 00:11:52,640
the first thing is to prevent default.
180
180
00:11:52,640 --> 00:11:57,640
So here we need access to the event, prevent default.
181
181
00:11:59,140 --> 00:12:03,653
And now how do we get access to all of these values?
182
182
00:12:04,550 --> 00:12:07,010
Well, we could go ahead and select
183
183
00:12:07,010 --> 00:12:09,337
all of these form elements one by one,
184
184
00:12:09,337 --> 00:12:13,750
and then read the value property of all of them.
185
185
00:12:13,750 --> 00:12:17,000
However, there is actually an easier way
186
186
00:12:17,000 --> 00:12:20,173
because we can use something called form data.
187
187
00:12:22,450 --> 00:12:25,720
So that's a pretty modern browser API
188
188
00:12:25,720 --> 00:12:27,763
that we can now make use of.
189
189
00:12:29,300 --> 00:12:31,260
So let's say data equals
190
190
00:12:31,260 --> 00:12:34,970
and then we can create a new form data
191
191
00:12:35,870 --> 00:12:38,370
and into the form data constructor,
192
192
00:12:38,370 --> 00:12:41,960
we have to pass in an element that is a form.
193
193
00:12:41,960 --> 00:12:46,960
And so that form in this case is the this keyword, right?
194
194
00:12:47,130 --> 00:12:50,190
Because we are inside of a handler function.
195
195
00:12:50,190 --> 00:12:52,463
And so this points to this.parentElement,
196
196
00:12:53,550 --> 00:12:56,770
which is of course the upload form.
197
197
00:12:56,770 --> 00:13:00,230
Now this here will then return a weird object
198
198
00:13:00,230 --> 00:13:02,160
that we cannot really use,
199
199
00:13:02,160 --> 00:13:04,980
but we can actually spread that object
200
200
00:13:04,980 --> 00:13:09,670
into an array, like this, all right?
201
201
00:13:09,670 --> 00:13:13,330
And so this will then basically give us an array,
202
202
00:13:13,330 --> 00:13:17,073
which contains all the fields with all the values in there.
203
203
00:13:18,250 --> 00:13:21,223
So let's then lock that data to the console.
204
204
00:13:22,140 --> 00:13:25,110
Now let's think what we actually want to do
205
205
00:13:25,110 --> 00:13:27,340
with this data eventually.
206
206
00:13:27,340 --> 00:13:30,230
So this data right here is the data
207
207
00:13:30,230 --> 00:13:33,430
that we eventually will want to use to upload
208
208
00:13:33,430 --> 00:13:36,470
to the API, right?
209
209
00:13:36,470 --> 00:13:39,750
And that action of uploading the data is going
210
210
00:13:39,750 --> 00:13:43,640
to be just another API call, right?
211
211
00:13:43,640 --> 00:13:46,820
And where do API calls happen?
212
212
00:13:46,820 --> 00:13:48,912
Well, they happen in the model.
213
213
00:13:48,912 --> 00:13:51,880
And so therefore we will need a way of getting
214
214
00:13:51,880 --> 00:13:53,950
this data to the model.
215
215
00:13:53,950 --> 00:13:56,197
So just like we did many times before,
216
216
00:13:56,197 --> 00:13:59,028
we now need to create a controller function,
217
217
00:13:59,028 --> 00:14:04,028
which will then be the handler of this event, okay?
218
218
00:14:05,460 --> 00:14:10,460
So let's come down here and create controlAddRecipe.
219
219
00:14:17,290 --> 00:14:20,770
And so this function here will then actually
220
220
00:14:20,770 --> 00:14:23,003
receive the new recipe data.
221
221
00:14:26,340 --> 00:14:29,080
And let's actually have this one here
222
222
00:14:29,080 --> 00:14:30,923
lock the data to the console.
223
223
00:14:32,230 --> 00:14:36,410
So newRecipe, okay?
224
224
00:14:36,410 --> 00:14:39,349
And now all we have to do is to say,
225
225
00:14:39,349 --> 00:14:44,349
addRecipeView.addHandlerUpload
226
226
00:14:44,963 --> 00:14:47,280
and then controlAddRecipe.
227
227
00:14:50,840 --> 00:14:53,815
So this is the publisher subscriber pattern
228
228
00:14:53,815 --> 00:14:57,000
that we have used many times before.
229
229
00:14:57,000 --> 00:14:59,696
And so eventually here we will have some function
230
230
00:14:59,696 --> 00:15:04,696
to then upload the new recipe data, okay?
231
231
00:15:09,150 --> 00:15:10,870
And so here we now need to accept
232
232
00:15:10,870 --> 00:15:15,030
this handler function and then we need to call it.
233
233
00:15:15,030 --> 00:15:17,575
So instead of logging it to the console right here,
234
234
00:15:17,575 --> 00:15:19,897
we will simply call the handler function
235
235
00:15:19,897 --> 00:15:24,000
and so this handler function will then for now log it
236
236
00:15:24,000 --> 00:15:27,890
to the console because again, that handler is now
237
237
00:15:27,890 --> 00:15:29,800
this controlAddRecipe.
238
238
00:15:32,580 --> 00:15:36,313
All right, so let's see what happens.
239
239
00:15:37,580 --> 00:15:41,740
And so that's why I have all of these prefilled data now,
240
240
00:15:41,740 --> 00:15:43,928
so that we can simply click the upload button
241
241
00:15:43,928 --> 00:15:47,653
and then get our data down here immediately.
242
242
00:15:49,100 --> 00:15:51,820
So let's now take a look at the data.
243
243
00:15:51,820 --> 00:15:56,030
And so since we got that data, it means that everything
244
244
00:15:56,030 --> 00:15:58,683
is correctly set up, which is great.
245
245
00:15:59,700 --> 00:16:04,700
And so here we get the array of multiple erase in there.
246
246
00:16:05,620 --> 00:16:07,722
So basically the entries of this form,
247
247
00:16:07,722 --> 00:16:12,060
where the first element is always the name of the field
248
248
00:16:12,060 --> 00:16:14,343
and the second one is the value.
249
249
00:16:16,410 --> 00:16:20,500
All right, so title, source URL,
250
250
00:16:20,500 --> 00:16:25,290
and you see all of them here, okay?
251
251
00:16:25,290 --> 00:16:29,320
Now usually, our recipe data is always an object
252
252
00:16:29,320 --> 00:16:32,380
and not an array of entries like this.
253
253
00:16:32,380 --> 00:16:36,430
And so in JavaScript, since IES 2019,
254
254
00:16:36,430 --> 00:16:39,890
there is now a new and very handy method that
255
255
00:16:39,890 --> 00:16:43,283
we can use to convert entries to an object.
256
256
00:16:44,430 --> 00:16:47,200
So let's actually call this one here, dataArray.
257
257
00:16:49,422 --> 00:16:53,333
And then the data itself is gonna be object.fromEntries
258
258
00:16:57,990 --> 00:16:59,963
and then the data array.
259
259
00:17:00,840 --> 00:17:03,129
And so this fromEntries method here
260
260
00:17:03,129 --> 00:17:06,634
is basically the opposite of the entries method
261
261
00:17:06,634 --> 00:17:10,020
that is available on erase, right?
262
262
00:17:10,020 --> 00:17:12,930
So this one takes an array of entries
263
263
00:17:12,930 --> 00:17:15,610
and converts it to an object.
264
264
00:17:15,610 --> 00:17:18,169
So let's see what that looks like in practice
265
265
00:17:18,169 --> 00:17:22,924
and beautiful, so this looks already a lot more
266
266
00:17:22,924 --> 00:17:25,940
like our original recipe object,
267
267
00:17:25,940 --> 00:17:28,280
like this one here for example,
268
268
00:17:28,280 --> 00:17:31,359
it is of course still missing some formatting
269
269
00:17:31,359 --> 00:17:34,950
and it is still missing some data like the ID,
270
270
00:17:34,950 --> 00:17:37,344
but that we will take care of in the model.
271
271
00:17:37,344 --> 00:17:40,923
And so let's go do that in the next video.
23842
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.