Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:00,690 --> 00:00:08,910
So in the last lesson we looked at how we are able to add new items into our ToDo list by switching
2
00:00:08,940 --> 00:00:11,620
our database from an array over to MongoDB.
3
00:00:11,620 --> 00:00:17,400
In this lesson I want to look at the other functionality that we promise people which is that when
4
00:00:17,420 --> 00:00:22,950
we click on one of these text boxes it should be able to delete an item. At the moment
5
00:00:22,980 --> 00:00:24,140
it doesn't really do that.
6
00:00:24,150 --> 00:00:25,730
It just crosses it out.
7
00:00:26,010 --> 00:00:33,540
But say if we had a really long todo list and we had a whole bunch of stuff then it kind of clutters
8
00:00:33,540 --> 00:00:35,640
the page and we just click on that
9
00:00:35,640 --> 00:00:35,990
right?
10
00:00:36,000 --> 00:00:39,260
It doesn't really need to be there anymore after I've checked it off.
11
00:00:39,270 --> 00:00:41,280
I want to clear out my list.
12
00:00:41,490 --> 00:00:48,030
So I want to be able to delete the item when I click the check box next to it. And to do that we have
13
00:00:48,030 --> 00:00:55,800
to remove that particular document from items collection. Inside our list.
14
00:00:55,840 --> 00:00:56,290
ejs
15
00:00:56,320 --> 00:00:57,720
you can see that
16
00:00:57,740 --> 00:01:05,570
currently we have this input called checkbox and next to it we have the item name in a paragraph.
17
00:01:05,740 --> 00:01:13,720
If we wanted to send some data when that checkbox gets clicked then we need again a form and a post
18
00:01:13,720 --> 00:01:14,490
route.
19
00:01:14,500 --> 00:01:25,010
So let's go ahead and create a new form and we're going to wrap that form around our items div. Once
20
00:01:25,020 --> 00:01:30,460
we've grouped our input and a paragraph into this new form
21
00:01:30,480 --> 00:01:37,560
the first thing that you notice when you hit save and you go back over to our todo list is when you
22
00:01:37,560 --> 00:01:41,160
refresh the styling looks a bit different
23
00:01:41,160 --> 00:01:41,390
right?
24
00:01:41,400 --> 00:01:42,940
It looks a bit off.
25
00:01:43,140 --> 00:01:46,290
And the reason for this is because in our stylesheet,
26
00:01:46,380 --> 00:01:53,490
so if you go into public, css, styles.css, you can see that we have the CSS rule which is targeting
27
00:01:53,940 --> 00:02:02,520
our HTML form elements and this will apply the text-align center and margin-left to all of our form elements
28
00:02:02,850 --> 00:02:04,230
which is not what we want.
29
00:02:05,010 --> 00:02:08,860
We only want it for this form and not this one.
30
00:02:09,000 --> 00:02:11,090
So what's the difference here?
31
00:02:11,430 --> 00:02:14,990
Well this one has a class of item.
32
00:02:15,240 --> 00:02:18,500
So it's got a class and it's also a form element.
33
00:02:18,750 --> 00:02:25,320
So if we wanted our CSS to be more specific then we could say for this rule it should only apply
34
00:02:25,320 --> 00:02:32,320
to all of the HTML forms which also have the class item.
35
00:02:32,340 --> 00:02:38,970
Now if we hit save and we go back to our To-Do list and hit refresh then you can see that our previous
36
00:02:38,970 --> 00:02:41,380
styles are restored.
37
00:02:41,430 --> 00:02:49,410
So now that we fixed the CSS and styling, the next thing to address is where is this form going to post
38
00:02:49,410 --> 00:02:56,640
to? Well in order to specify that we need an action and a method right?
39
00:02:56,890 --> 00:03:03,340
So if we just go ahead and copy those into this form element then the part that we're going to keep
40
00:03:03,340 --> 00:03:10,450
the same is this form is also going to make a post request but the route is now going to be separate
41
00:03:10,570 --> 00:03:12,860
from what we had down here.
42
00:03:13,270 --> 00:03:16,240
This route was responsible for adding new items,
43
00:03:16,240 --> 00:03:20,600
so this route has to be responsible for deleting checked items.
44
00:03:20,620 --> 00:03:26,540
Let's add a route called /delete and hit save.
45
00:03:26,620 --> 00:03:35,860
Now inside our app.js just below our other posts route we can add this new route. So we can say
46
00:03:35,950 --> 00:03:45,460
app.post and the route was called /delete and this also is going to have a callback, req and
47
00:03:45,480 --> 00:03:52,590
res and now I'm going to console log simply request.body
48
00:03:52,590 --> 00:04:00,090
so what is being sent over basically from our form inside list.ejs because we know that over here in
49
00:04:00,090 --> 00:04:09,000
our app.post we're getting the new item being sent over because in that form we have an input with
50
00:04:09,000 --> 00:04:16,320
type text and has the name of new item and we're going to send over whatever it is that the user typed
51
00:04:16,320 --> 00:04:20,980
in here over to this route via the req.body.
52
00:04:21,300 --> 00:04:28,760
If we run our app now let's see what our console logs for the req.body of our /delete
53
00:04:28,780 --> 00:04:31,250
route.
54
00:04:31,460 --> 00:04:37,250
I'm going to refresh my to-do list and I'm just going to check one of these boxes.
55
00:04:37,490 --> 00:04:44,120
And if we have a look inside our console then you can see that absolutely nothing happens here.
56
00:04:44,440 --> 00:04:52,310
And the reason is because inside our list.ejs, if you remember we actually have this button
57
00:04:52,350 --> 00:04:56,550
here and it's type is submit.
58
00:04:56,780 --> 00:05:03,560
And whenever we have a submit button anywhere inside a form then its job is that when it gets pressed
59
00:05:03,740 --> 00:05:12,170
it will submit all of the data inside the form and make the post request to the required route.
60
00:05:12,170 --> 00:05:20,990
Now in this form however we don't have any way of submitting and it'll look kind of ugly if we added a submit
61
00:05:20,990 --> 00:05:23,510
button next to the checkbox right?
62
00:05:23,510 --> 00:05:30,260
I mean, ideally what we want is whenever we tick a checkbox we just want it to be able to delete that
63
00:05:30,290 --> 00:05:31,430
item.
64
00:05:31,430 --> 00:05:35,840
The action has to happen when we check the checkbox.
65
00:05:36,240 --> 00:05:41,400
So how can we get the form to submit when the checkbox is checked?
66
00:05:42,520 --> 00:05:48,420
Well if we didn't have any better ideas then we can always ask a developer's best friend
67
00:05:48,460 --> 00:05:48,890
right?
68
00:05:49,000 --> 00:05:49,860
It's Google.
69
00:05:49,960 --> 00:05:57,480
So if we put in the query "submit form when checkbox is checked" for example.
70
00:05:57,850 --> 00:05:59,920
That seems pretty much like what we want.
71
00:06:00,160 --> 00:06:06,880
And if we click on the first Stack Overflow answer, then the person is asking how do you submit a form
72
00:06:06,880 --> 00:06:08,890
when a checkbox is checked.
73
00:06:08,890 --> 00:06:10,580
Sounds like what we want too.
74
00:06:10,730 --> 00:06:18,650
So if you scroll down, the first answer tells us that in plain Javascript simply add this attribute on
75
00:06:18,650 --> 00:06:23,560
change to the input that is going to change and then inside it
76
00:06:23,560 --> 00:06:28,850
just add a little snippet of Javascript code to submit the current form.
77
00:06:28,870 --> 00:06:33,490
Let's go ahead and copy this over to our input.
78
00:06:33,490 --> 00:06:37,640
The input that we want to trigger the submit is of course our checkbox.
79
00:06:37,870 --> 00:06:44,980
In addition to having a type it's now also going to have a onChange attribute. And so that means when
80
00:06:44,980 --> 00:06:46,530
the checkbox is changed,
81
00:06:46,570 --> 00:06:53,140
so from checked to unchecked, unchecked to checked, then we're going to run this line of Javascript code
82
00:06:53,470 --> 00:06:57,350
which will take the current form that the input is inside,
83
00:06:57,490 --> 00:07:05,560
so this one, and it's going to submit it to make that post request to our delete route.
84
00:07:05,950 --> 00:07:13,330
In addition to just getting the form to submit we also need a way of accessing this input. To do that
85
00:07:13,360 --> 00:07:18,040
we have to give it a name. For our text input to add new items
86
00:07:18,040 --> 00:07:24,360
we gave it a name of newItem which is what allowed us to tap into it inside the req.body.
87
00:07:24,910 --> 00:07:30,130
So for this check box we're also going to give it a name and I'm going to give it something really simple.
88
00:07:30,130 --> 00:07:32,480
I'm just going to call it checkbox.
89
00:07:33,040 --> 00:07:42,250
So now if we save our code and go back to our console and refresh our page then I'm going to click on
90
00:07:42,250 --> 00:07:44,670
one of these boxes to check it.
91
00:07:44,740 --> 00:07:53,760
And now if I have a look inside my console you can see that I've got the "on" value printed for my check
92
00:07:53,760 --> 00:08:01,780
box. And this comes from the log statement that's inside my app.js inside this route.
93
00:08:01,840 --> 00:08:05,110
This is what is being logged right now.
94
00:08:05,110 --> 00:08:08,480
And of course I can now tap into this thing called checkbox.
95
00:08:08,680 --> 00:08:16,870
So if I hit save now and I refresh my page and go back to my root route, refresh my page and check one
96
00:08:16,870 --> 00:08:18,510
of the items, you can see
97
00:08:18,510 --> 00:08:27,580
I now get the value of that req.body which is "on". On is not very useful for us
98
00:08:27,590 --> 00:08:28,320
right?
99
00:08:28,340 --> 00:08:34,289
What we want is the item name that they actually checked off.
100
00:08:34,500 --> 00:08:43,799
So we know that our forEach loop is going to render as many checkboxes as we have items in our items
101
00:08:43,799 --> 00:08:45,010
collection.
102
00:08:45,060 --> 00:08:56,240
That means that we can also assign a value to our checkbox based on the item's ID. Inside here I'm going
103
00:08:56,240 --> 00:09:04,780
to add another attribute called value and this value is going to be equal to some EJS values.
104
00:09:04,850 --> 00:09:11,060
So I'm going to add that classic angle bracket percentage equal sign and then I'm going to close it
105
00:09:11,060 --> 00:09:14,610
off with percent angle bracket. And inside here
106
00:09:14,630 --> 00:09:22,730
I'm going to tap into that item object that we get access to and I'm going to tap into its ID.
107
00:09:22,970 --> 00:09:29,740
Remember, when we pass new list items over we're passing over an array of Mongo documents.
108
00:09:29,900 --> 00:09:37,310
Each of these documents or each of these items that we're looping through has a name as well as an ID.
109
00:09:37,550 --> 00:09:45,860
So if I bind that ID to the value of each of the checkboxes then when it gets checked I can submit this
110
00:09:45,860 --> 00:09:50,210
form and find out which item was actually checked off.
111
00:09:50,690 --> 00:09:58,460
So now let's hit save and let's again refresh our home page and check off one of the items
112
00:09:58,580 --> 00:10:03,650
and now you can see I've got the ID of that item.
113
00:10:03,650 --> 00:10:10,610
So once I've got the ID then everything else is so much easier because we can now delete the item with
114
00:10:10,610 --> 00:10:12,200
that particular ID.
115
00:10:13,970 --> 00:10:20,210
Inside our app.js instead of console logging this, I'm going to bind it to a constant and it's
116
00:10:20,210 --> 00:10:28,660
going to be called the checkedItemId and it's just going to equal req.body.checkbox.
117
00:10:28,860 --> 00:10:37,400
And now as a challenge I want you to remove the item from the database that has the ID of the one that
118
00:10:37,400 --> 00:10:42,530
was checked off. Again as a reminder, in the Mongoose documentation
119
00:10:42,560 --> 00:10:47,420
you can find a method called findByIdAndRemove
120
00:10:47,570 --> 00:10:50,450
which seems pretty much like what we need to do.
121
00:10:50,480 --> 00:10:58,040
So in this case we simply provide the ID as an argument and then we have a callback to handle any errors
122
00:10:58,100 --> 00:11:00,090
or log success.
123
00:11:00,350 --> 00:11:05,900
And when this is executed, it should delete that document with that particular ID.
124
00:11:06,840 --> 00:11:11,730
Pause the video and try to complete the challenge.
125
00:11:11,730 --> 00:11:15,750
All right. So let's do that right here where we've got access to that ID.
126
00:11:16,020 --> 00:11:25,020
I'm going to tap into the items collection using that item model and then I'm going to call
127
00:11:25,080 --> 00:11:31,260
findByIdAndRemove. And make sure that you don't have any typos in there.
128
00:11:31,560 --> 00:11:38,250
And then the ID is of course going to be the checkedItemId and then we're going to provide that callback
129
00:11:38,850 --> 00:11:46,590
to see if there were any errors. And if there were no errors then in that case we're simply going to
130
00:11:46,620 --> 00:11:56,220
log that we "Successfully deleted checked item".
131
00:11:56,240 --> 00:12:04,610
Now if we check the Mongoose API documentation and you locate the findByIdAndRemove method, if you
132
00:12:04,610 --> 00:12:13,320
read through it ill tell you that if you don't provide the callback it won't actually execute the delete.
133
00:12:13,340 --> 00:12:16,990
It's only when the callback is there does it actually execute it.
134
00:12:17,180 --> 00:12:21,610
Whereas if it only has an ID or option, then it'll just return the query.
135
00:12:21,610 --> 00:12:24,480
It'll just find that item by ID.
136
00:12:24,710 --> 00:12:29,870
So in order to get the and remove part,we have to provide the callback
137
00:12:29,870 --> 00:12:36,740
even if you don't care to check if there were any errors or not. Let's hit save and let's go back to
138
00:12:36,740 --> 00:12:40,990
our root route and try to delete one of these items.
139
00:12:41,030 --> 00:12:49,850
Again our web interface is not updating but if you go over to the console it says that it successfully
140
00:12:49,880 --> 00:12:55,850
deleted the checked item which means that it's probably been deleted
141
00:12:56,000 --> 00:13:03,500
and if we again check our Mongo shell and we do "db.items.find" then indeed that item that
142
00:13:03,500 --> 00:13:12,800
we just checked off here hit this to delete an item no longer exists in our items collection.
143
00:13:12,800 --> 00:13:20,150
But in order for it to reflect in our web page then again we have to call a redirect right? We can say
144
00:13:20,160 --> 00:13:24,440
res.redirect to the home route.
145
00:13:24,800 --> 00:13:32,060
And now it will find all of the items that we still have in our items collection and render it on the
146
00:13:32,060 --> 00:13:33,170
page.
147
00:13:33,740 --> 00:13:40,230
So now let's go back to our home page and let's delete some of these random ones
148
00:13:40,340 --> 00:13:44,890
then you can see that they're all just getting crossed off and deleted.
149
00:13:46,370 --> 00:13:47,090
Pretty neat right?
15889
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.