Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
Let's add a new feature: filtering out guests who have yet to respond. This will enable our users to see the current guest list at a glance. Unlike the previous features we've implemented, we'll add this one to the page dynamically. In other words, we'll create and insert all the new elements we need to the DOM. Then we'll attach behavior to those elements, all with JavaScript.
Our users can add names to the list,
remove them,
0:00
check them off when they responded,
and edit them.
0:03
Now let's give users a way
to filter the guest list, so
0:06
they can see everyone who
has responded at a glance.
0:09
We'll create a checkbox above the list
to toggle this feature on and off.
0:12
When the box is checked, we'll hide
the guests who haven't yet responded and
0:17
display only those who have.
0:21
And when the box is unchecked,
all invitees will be visible in the list.
0:23
So first, let's add a checkbox to
the page, but rather than editing
0:29
index.html, let's add a checkbox and
its behavior with JavaScript.
0:33
Apart from a checkbox,
0:38
we'll want to add a label to let
users know what the checkbox is for.
0:40
And we can do this with a label element.
0:44
We'll place the label and checkbox in
a div and append that to the page.
0:46
So to plan where we want to put the div
let's take a look at index.HTML.
0:51
And looking at the code,
0:56
it looks like the best place to add
the div is just before the UL element.
0:58
So let's go into app.js.
1:04
And at the top create the three elements
1:06
we want to use we'll create the div,
1:11
first with const div =
document.createElement div,
1:16
then we'll create the label.
1:23
Let's call it filterLabel.
1:27
And we'll create the checkbox.
1:40
We'll call this one filterCheckbox.
1:43
Next under this we want to set
the labels text content to hide those
1:58
who haven't responded.
2:03
So we'll type filterLabel.textContent.
2:05
And since this string
has an apostrophe in it.
2:11
I'll switch over to using double quotes so
inside the quotes.
2:14
I'll type hide those
who haven't responded.
2:18
And now we'll set the input's
type to checkbox with
2:25
filterCheckBox.type = checkbox,
2:30
And then we'll append the two elements
the label and checkbox to the div.
2:37
So first we'll say
div.appendChild filterLabel.
2:42
Then div.appendChild Filter checkbox.
2:51
Next, to insert this new div above the UL,
we'll need to call insert before
2:58
on the parent of the UL which
is the div with the class main.
3:04
Now we don't have a reference
to the main development yet.
3:10
So let's select it.
3:13
Now the main div sits
under the form in the DOM.
3:15
So I'll place it below the form and
above the UL.
3:19
And now we can insert the div we built
3:38
into the DOM with mainDiv.insertBefore.
3:44
And we'll want to insert the div before
the UL so we'll pass div first then UL.
3:51
So let's save our changes.
3:57
And go over to the browser and refresh and
3:59
you should see the check-box
we just added.
4:02
Now it's there but
it doesn't do anything yet.
4:04
So for example I'll add a name to the list
and check the box and it doesn't hide it.
4:06
So let's fix that.
4:13
Back in app.js let's add
an event handler to the checkbox.
4:15
Now we all ready have
a reference to the checkbox here
4:20
in the filter checkbox constant.
4:23
So let's use this constant to
call addEventListener on right
4:26
underneath where it was
inserted into the DOM.
4:30
We'll say filterCheckBox.addEventListener.
4:34
Now check boxes trigger a change event so
let's create a change event handler.
4:39
And here we want to know
if the box is checked or
4:50
not which can be found in
the checked property of the end put.
4:53
Remember at the end put is
the target of the change event so
4:56
let's store its value in
a constant called is checked.
5:00
If the box is checked, is checked will be
true, and if not is checked will be false.
5:13
So now we'll need a reference
to all the list items as
5:19
well because we'll be looping
through them with this handler.
5:22
So we can traverse to them from
the UL using the children property so
5:25
right below the constant.
5:29
We'll type const Lis ul.children.
5:31
Now if you haven't seen this before,
5:38
children provides a reference to
a collection of elements children.
5:40
So next, if is checked is true,
5:46
we'll want to hide invitees
that haven't responded yet.
5:49
And if it's false, we'll need to make
sure all the invitees are displaying.
5:52
This sounds like a perfect case for
an if statement.
5:56
So right below our constant,
we'll write and if else.
5:58
Passing in is checked as the condition.
6:03
So now we also know that we'll need to go
through all the list items in either case.
6:14
So let's set up for loops for both cases.
6:19
Now, we can go ahead and copy this for
loop and paste it inside the else branch.
6:43
And now we'll also need
to create a variable
6:51
to represent the individual allies inside
each loop to make them more readable.
6:53
So first, we'll create
a variable with let li = lists,
6:58
Then we can copy this variable and
paste it inside the second for loop.
7:10
All right so now let's address
the case where the filter is checked.
7:16
So we need to know whether the individual
list items have been marked
7:21
responded or not.
7:24
Remember we're storing that information
on the list items class attribute.
7:26
So we can check whether that class
exists or not in an if statement.
7:30
So in the first for loop, we'll say if
7:34
Li.classname, === responded,
7:39
Run this code block, then else,
run the code we include here.
7:47
And now we can hide an element by setting
its CSS display property to none.
7:54
So in the else branch we'll
type li style.display, = none.
8:00
And to show it again,
we can set its display to an empty string.
8:09
So up here in the if branch, we'll say
li.style.display = an empty string.
8:13
This will allow it to pick
up its previous style.
8:22
So now let's move on to the case where
we want to show all the guests whether
8:25
they've responded or not.
8:29
In this case we simply want to set every
list items display property to an empty
8:31
string.
8:35
So in this bottom else branch,
8:37
we'll add li.styl.display
= the empty string.
8:41
All right, so let's save our file and
try this in the browser.
8:49
I'm going to refresh the page and
enter a few names.
8:53
Let's say Elizabeth.
9:00
Andrew and Janice,
I'll add a couple more let's say Gil and
9:03
Henry and then I'll just go through and
check two names off.
9:09
And now when I check mark the new
filter the unchecked names disappear.
9:16
And when I uncheck it,
they show up again, perfect.
9:21
Our app now does everything
we need it to do,
9:26
but there are still a few
improvements we can make.
9:28
So far, we've been writing the app
in a stream of consciousness way.
9:31
And this can really be useful for
getting something up and running and
9:34
is often the approach developers use
when they first write a program.
9:37
But once the basic functionality is in
place you can often improve your programs
9:40
by looking at your code again.
9:44
And re factoring or changing your code,
so that it still works the same but
9:46
it's easier to understand an update.
9:50
You need to sign up for Treehouse in order to download course files.
Sign up