Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
French
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranรฎ)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
1 1
So, as I just said, 2
2
let's now start with the feature of uploading a new recipe 3
3
and start with the ability of opening the model window, 4
4
which contains the form to add the new recipe. 5
5
So in the demo version, this is what it looks like. 6
6
So here we click add recipe, 7
7
and then it opens up this form like this, 8
8
and then when we click this button, 9
9
or click outside of the form, 10
10
then that window will again close. 11
11
Alright, so let's do that, 12
12
and let's create a new bookmark's view. 13
13
And actually not a bookmark's view, 14
14
but a addRecipeView.js 15
15
And now let's go to one of these views, 16
16
and copy the code from there. 17
17
Because this code is always very similar, 18
18
so let's delete this one here, 19
19
let's empty out this method. 20
20
And then here, let's call it AddRecipeView. 21
21
Now this view here is actually gonna be quite different 22
22
from the other views because we already have 23
23
actually the view in the HTML. 24
24
So if we come here to our HTML code, 25
25
then you see that the form that we want to display 26
26
is actually already here in the code, all right? 27
27
So, here we have this element for the overlay 28
28
and this element for the window 29
29
and they both have the hidden class. 30
30
And so showing the window and the overlay 31
31
is gonna be as simple as removing this hidden class 32
32
from both these elements. 33
33
Now, the main element that we are actually 34
34
really interested in is this upload element. 35
35
And so let's actually make this upload element, 36
36
the parent element of the AddRecipeView. 37
37
So upload here, but then we will also have 38
38
to select some other elements. 39
39
So for example, the window and the overlay, 40
40
so to start at least. 41
41
So the window element is going to be document.querySelector 42
42
and then let's see what we have here. 43
43
Here we can close all of these for now. 44
44
So that's add recipe window. 45
45
And then the overlay has simply the overlay class. 46
46
And so here, overlay and here as well. 47
47
And here we are missing the dot on both selectors. 48
48
And now we also need to select a button 49
49
that will be clicked to open the window 50
50
and also the button to close the window. 51
51
So that button is somewhere here in the top navigation bar. 52
52
So this is for the bookmarks and here it is. 53
53
So this is the button for adding the recipe as you see. 54
54
So let's call that the btnOpen 55
55
and then also the button to close the form. 56
56
And so that's back here somewhere in the window. 57
57
So that's btn-close-model. 58
58
Okay, and here. 59
59
Okay and so now, let's listen for the events, 60
60
so of clicking the open button and the close button. 61
61
Okay, and as always, we will do that in a method called 62
62
addHandler and then something, 63
63
just to make it more consistent. 64
64
So addHandlerShowWindow, let's say, 65
65
and so here we will want to select the button. 66
66
So btnOpen.addEventListener of a click. 67
67
And so when that happens, what do we want to do? 68
68
Well, we want to take the overlay into window 69
69
and remove the hidden class. 70
70
So that's this.overlay.classList.rem. 71
71
Now, instead of remove, we can actually also use toggle. 72
72
So remember that toggle will add to class if it's not there 73
73
and it will remove the class when it is already there. 74
74
And so this will make it a lot easier 75
75
to then reuse this class. 76
76
So the overlay and also the window. 77
77
Okay, now, when do we actually want 78
78
this function here to be called? 79
79
Well, we want this to be called as soon as the page loads. 80
80
Now, in this case, this has nothing to do 81
81
with any controller because there is nothing special 82
82
happening here that the controller needs to tell us, right? 83
83
So when this click happens on the button open, 84
84
all that will happen is really for the window to show. 85
85
So the controller, it doesn't need to interfere 86
86
in any of this and so therefore we can simply run 87
87
this function here as soon as this object is created. 88
88
And so what I'm gonna do is 89
89
to this time add a constructor method, 90
90
then since this is a child class, 91
91
we need to start by calling super. 92
92
And so only after that, we can use the this keywords. 93
93
And then let's say, this.addHandlerShowWindow. 94
94
And so this one here is now only gonna be 95
95
used inside of this class. 96
96
And so let's add an underscore to mark it as protected. 97
97
And so again, in order to show this window, 98
98
the controller does not interfere at all, all right? 99
99
Now what we will have to do in the controller still 100
100
is to import this object here 101
101
because otherwise, our main script sort of controller 102
102
will never execute this file. 103
103
And so then this object here will never be created. 104
104
And so the event listener here will never be added. 105
105
And so we need to, again, import this 106
106
so that the code that is in the module 107
107
is actually being run. 108
108
So here let's call that the AddRecipeView. 109
109
And now let's check out our code 110
110
just to make sure we reload it. 111
111
And we got a class list of undefined. 112
112
So some small bug here, and again, 113
113
you see how common that is. 114
114
So let's again, see which line that actually was. 115
115
So line 19. 116
116
So with the overlay. 117
117
So let's see if the class is correct. 118
118
Well, it looks so. 119
119
No, but I can see the error now. 120
120
So here we are using the this keyword 121
121
inside of a handler, right? 122
122
But you already know that the this keyword 123
123
inside of a handler function points to the element 124
124
on which that listener is attached to. 125
125
So in this case, that is this button here. 126
126
And so let's actually export this entire function 127
127
into another method and then call that method 128
128
with the correct this keyword bound to it. 129
129
So here is what I mean, toggleWindow, let's say, 130
130
will do this and then here, 131
131
we want to call this.toggleWindow. 132
132
And now here we can use our bind method as always, 133
133
and then bind the correct this keyword. 134
134
So we have done this many times before, 135
135
so basically manually setting the this keyword 136
136
inside of this function here, 137
137
now to the this keyword that we actually want it to be. 138
138
And so right here, this of course, 139
139
points to the current object 140
140
because otherwise, again, the this keywords 141
141
inside of this function would be the button 142
142
on which the event listener is attached to. 143
143
And so with this, it should now work and yeah, 144
144
there is our form. 145
145
And now, all we have to do is to close that form 146
146
when we click this button or click outside here. 147
147
So addHandlerHeightWindow. 148
148
And so that's actually very similar to this one, 149
149
that's just duplicated actually. 150
150
So btnClose and then the same also on the overlay. 151
151
And so that's why this toggle here 152
152
is now very useful because here at this point, 153
153
when we want to hide the window, 154
154
then the hidden class is no longer there, 155
155
but it will then automatically add it back on. 156
156
Now, and before we actually try it, 157
157
we first of course, need to call this method here as well. 158
158
Okay, and it's gone. 159
159
Great, so that works. 160
160
And so next up, let's take care of handling this button here 161
161
and for now what we want to do 162
162
when we click this button is to get all the data here 163
163
out of this form. 164
164
And you see that I already have like, 165
165
pre-filled this data here. 166
166
And so that comes from the HTML here 167
167
because the value is basically already set. 168
168
But then of course, by the end, we will remove this. 169
169
So this is just for development purposes. 170
170
But anyway, let's now create another method here, 171
171
which is going to handle the click on that button. 172
172
So basically the form submission. 173
173
So addHandlerUpload. 174
174
And so here we will now actually listen for an event 175
175
right on the parent element. 176
176
So that is the upload form itself. 177
177
So parentElement.addEventListener 178
178
for submit and then inner function as always, 179
179
the first thing is to prevent default. 180
180
So here we need access to the event, prevent default. 181
181
And now how do we get access to all of these values? 182
182
Well, we could go ahead and select 183
183
all of these form elements one by one, 184
184
and then read the value property of all of them. 185
185
However, there is actually an easier way 186
186
because we can use something called form data. 187
187
So that's a pretty modern browser API 188
188
that we can now make use of. 189
189
So let's say data equals 190
190
and then we can create a new form data 191
191
and into the form data constructor, 192
192
we have to pass in an element that is a form. 193
193
And so that form in this case is the this keyword, right? 194
194
Because we are inside of a handler function. 195
195
And so this points to this.parentElement, 196
196
which is of course the upload form. 197
197
Now this here will then return a weird object 198
198
that we cannot really use, 199
199
but we can actually spread that object 200
200
into an array, like this, all right? 201
201
And so this will then basically give us an array, 202
202
which contains all the fields with all the values in there. 203
203
So let's then lock that data to the console. 204
204
Now let's think what we actually want to do 205
205
with this data eventually. 206
206
So this data right here is the data 207
207
that we eventually will want to use to upload 208
208
to the API, right? 209
209
And that action of uploading the data is going 210
210
to be just another API call, right? 211
211
And where do API calls happen? 212
212
Well, they happen in the model. 213
213
And so therefore we will need a way of getting 214
214
this data to the model. 215
215
So just like we did many times before, 216
216
we now need to create a controller function, 217
217
which will then be the handler of this event, okay? 218
218
So let's come down here and create controlAddRecipe. 219
219
And so this function here will then actually 220
220
receive the new recipe data. 221
221
And let's actually have this one here 222
222
lock the data to the console. 223
223
So newRecipe, okay? 224
224
And now all we have to do is to say, 225
225
addRecipeView.addHandlerUpload 226
226
and then controlAddRecipe. 227
227
So this is the publisher subscriber pattern 228
228
that we have used many times before. 229
229
And so eventually here we will have some function 230
230
to then upload the new recipe data, okay? 231
231
And so here we now need to accept 232
232
this handler function and then we need to call it. 233
233
So instead of logging it to the console right here, 234
234
we will simply call the handler function 235
235
and so this handler function will then for now log it 236
236
to the console because again, that handler is now 237
237
this controlAddRecipe. 238
238
All right, so let's see what happens. 239
239
And so that's why I have all of these prefilled data now, 240
240
so that we can simply click the upload button 241
241
and then get our data down here immediately. 242
242
So let's now take a look at the data. 243
243
And so since we got that data, it means that everything 244
244
is correctly set up, which is great. 245
245
And so here we get the array of multiple erase in there. 246
246
So basically the entries of this form, 247
247
where the first element is always the name of the field 248
248
and the second one is the value. 249
249
All right, so title, source URL, 250
250
and you see all of them here, okay? 251
251
Now usually, our recipe data is always an object 252
252
and not an array of entries like this. 253
253
And so in JavaScript, since IES 2019, 254
254
there is now a new and very handy method that 255
255
we can use to convert entries to an object. 256
256
So let's actually call this one here, dataArray. 257
257
And then the data itself is gonna be object.fromEntries 258
258
and then the data array. 259
259
And so this fromEntries method here 260
260
is basically the opposite of the entries method 261
261
that is available on erase, right? 262
262
So this one takes an array of entries 263
263
and converts it to an object. 264
264
So let's see what that looks like in practice 265
265
and beautiful, so this looks already a lot more 266
266
like our original recipe object, 267
267
like this one here for example, 268
268
it is of course still missing some formatting 269
269
and it is still missing some data like the ID, 270
270
but that we will take care of in the model. 271
271
And so let's go do that in the next video.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.