1 00:00:00,000 --> 00:00:09,344 [MUSIC] 2 00:00:09,344 --> 00:00:10,209 Hey, what's up? 3 00:00:10,209 --> 00:00:13,061 My name is Dustin, and I'm a developer here at Treehouse. 4 00:00:13,061 --> 00:00:15,485 Being able to search through your website or app, 5 00:00:15,485 --> 00:00:18,094 is a super important feature that you can implement. 6 00:00:18,094 --> 00:00:19,422 I'll show you one simple, 7 00:00:19,422 --> 00:00:23,473 low-level way that we can add this to an existing project, or a brand new project. 8 00:00:23,473 --> 00:00:25,420 Let's take a look at what I built. 9 00:00:25,420 --> 00:00:29,107 Sometimes you may want to search through data on your website, or 10 00:00:29,107 --> 00:00:31,262 maybe just a certain post on your app. 11 00:00:31,262 --> 00:00:32,365 In this example, 12 00:00:32,365 --> 00:00:37,001 I wanted to search for a specific user from a list of any user in my user base. 13 00:00:37,001 --> 00:00:38,674 Take a look at how this works. 14 00:00:38,674 --> 00:00:41,777 As soon as I start typing a drop down menu appears. 15 00:00:41,777 --> 00:00:46,345 And it's populated with any user in my user base that contains the characters in 16 00:00:46,345 --> 00:00:47,380 my search field. 17 00:00:47,380 --> 00:00:49,358 We'll be building this project from scratch. 18 00:00:49,358 --> 00:00:53,390 So the only prerequisites that I would mention would be to have a basic 19 00:00:53,390 --> 00:00:57,854 understanding of HTML and CSS, and of course, a little bit of JavaScript. 20 00:00:57,854 --> 00:01:02,125 We'll be working closely with the DOM as well as some loops in this project. 21 00:01:02,125 --> 00:01:04,541 So, if you feel like you want to follow along with me, 22 00:01:04,541 --> 00:01:07,659 grab the link in the teacher's notes, or description down below for 23 00:01:07,659 --> 00:01:09,621 the GitHub repo, and let's get started. 24 00:01:09,621 --> 00:01:15,114 Okay, so, just head on over to the description or teacher's notes for 25 00:01:15,114 --> 00:01:22,000 the GitHub link, or you can just go to github.com/treehouse/auto-user-search. 26 00:01:22,000 --> 00:01:24,393 And once you're there, you just wanna hit this big code button. 27 00:01:24,393 --> 00:01:27,979 And in the drop down, you just wanna hit this copy button. 28 00:01:27,979 --> 00:01:31,360 You can use GitHub desktop or your terminal to clone down the project. 29 00:01:31,360 --> 00:01:32,882 I'm gonna use my terminal. 30 00:01:32,882 --> 00:01:36,050 So I'm gonna open that up, type in cd desktop, and 31 00:01:36,050 --> 00:01:41,169 then I'm just gonna type in git clone, and then paste in that link that we copied. 32 00:01:41,169 --> 00:01:46,895 And then I'm just gonna drag this to VS Code to get started. 33 00:01:46,895 --> 00:01:50,995 So let's take a look at the files and folders that we have in here. 34 00:01:50,995 --> 00:01:53,561 You'll notice a master and a starter folder. 35 00:01:53,561 --> 00:01:57,115 Inside master is all of the completed code in case you get lost or 36 00:01:57,115 --> 00:01:59,747 stuck along the way and you need to refer to it. 37 00:01:59,747 --> 00:02:02,977 But everything that we'll be using is gonna be in the starter folder. 38 00:02:02,977 --> 00:02:06,505 So let's take a look at what we have in here. 39 00:02:06,505 --> 00:02:10,225 All the way at the bottom of that folder, we have our index.html file. 40 00:02:10,225 --> 00:02:16,261 And in here we are just linking our app.css file as well as our app.js file. 41 00:02:16,261 --> 00:02:20,160 So let's go and take a look at those. 42 00:02:20,160 --> 00:02:23,302 Inside of our styles folder we have our app.css and 43 00:02:23,302 --> 00:02:28,650 we're just importing a Google font, we're resetting the browser just a little bit. 44 00:02:28,650 --> 00:02:34,120 And we have a few CSS variables to style up the UI. 45 00:02:34,120 --> 00:02:38,176 And inside of our scripts folder, we have an app.js file. 46 00:02:38,176 --> 00:02:42,482 And in here is just one variable for an array. 47 00:02:42,482 --> 00:02:47,036 And we call that userData, and it just holds a bunch of objects containing all 48 00:02:47,036 --> 00:02:48,873 the data we need for each user. 49 00:02:48,873 --> 00:02:51,592 So we'll be looping over this whenever we get to 50 00:02:51,592 --> 00:02:53,980 the JavaScript portion of this project. 51 00:02:53,980 --> 00:02:58,026 So the only other thing that we have in this starter folder that we should go 52 00:02:58,026 --> 00:02:59,150 over is the images. 53 00:02:59,150 --> 00:03:01,917 So in here we have a another folder for users. 54 00:03:01,917 --> 00:03:07,397 And these are just some fun images that I have made that we can use for our users. 55 00:03:07,397 --> 00:03:10,824 And then we have our mockup, which is what we'll be building out. 56 00:03:10,824 --> 00:03:14,352 And then we have our search icon. 57 00:03:14,352 --> 00:03:18,666 Okay, so that covers it for all the files and folders in this repo. 58 00:03:18,666 --> 00:03:21,199 Let's get started actually coding. 59 00:03:21,199 --> 00:03:28,397 The first thing I wanna do is just open up the index.html file as well as our markup. 60 00:03:28,397 --> 00:03:30,435 And I'm gonna open them up side by side. 61 00:03:30,435 --> 00:03:36,755 And let's see if we can't write the markup that we'll need to build this out. 62 00:03:36,755 --> 00:03:40,050 So let's make the editor just a little bit smaller. 63 00:03:40,050 --> 00:03:43,122 Okay, so let's break down this mockup. 64 00:03:43,122 --> 00:03:48,604 It looks like we have one container and it's not centered, but it's sort 65 00:03:48,604 --> 00:03:54,453 of at the top of the page, and we have a search field, and then a drop down menu. 66 00:03:54,453 --> 00:04:00,137 So I think what I'll do is I'll create auto-user-search container. 67 00:04:00,137 --> 00:04:02,379 And I'll put everything in here. 68 00:04:02,379 --> 00:04:08,181 So first thing I wanna do is let's create a div called search-container. 69 00:04:08,181 --> 00:04:13,991 And I'll first put in our image of our search icon. 70 00:04:13,991 --> 00:04:17,773 So I'll navigate to images and then search.png. 71 00:04:17,773 --> 00:04:24,944 And for the alt I'll just put an icon for our search input. 72 00:04:26,743 --> 00:04:31,423 And after that I'll just go ahead and put our input with the type of text. 73 00:04:31,423 --> 00:04:36,943 And I'll give it an id of searchInput. 74 00:04:36,943 --> 00:04:40,586 And I'm gonna remove the name attribute, we won't need that. 75 00:04:40,586 --> 00:04:43,915 And I'm also going to give an id to our search-container, 76 00:04:43,915 --> 00:04:47,053 because we will need this in the JavaScript later also. 77 00:04:47,053 --> 00:04:51,550 So I'll just call this searchContainer. 78 00:04:51,550 --> 00:04:52,314 Sweet, so 79 00:04:52,314 --> 00:04:58,022 now I guess let's also put our drop down menu inside of the search-container. 80 00:04:58,022 --> 00:05:02,911 So I'll create a div with a class of .dropdown-container. 81 00:05:02,911 --> 00:05:07,037 I'll also give it an id of dropdownContainer. 82 00:05:07,037 --> 00:05:11,853 And in here, I'll just have a ul called dropdown. 83 00:05:11,853 --> 00:05:16,900 And also give this an id, we'll need this in the JavaScript also. 84 00:05:16,900 --> 00:05:19,428 And I'll just call this dropdown. 85 00:05:19,428 --> 00:05:23,624 Now, all these list items will be rendered dynamically, so 86 00:05:23,624 --> 00:05:28,331 we're gonna loop over that userData array in our JavaScript file. 87 00:05:28,331 --> 00:05:32,829 But, in order to style this out, I want to create these statically. 88 00:05:32,829 --> 00:05:38,144 So, I'm gonna create a list item, and in here I'm gonna put an image. 89 00:05:38,144 --> 00:05:43,524 And for now I'm just gonna navigate to one of the random images in here, 90 00:05:43,524 --> 00:05:47,469 and we don't need to worry about the alt attribute, 91 00:05:47,469 --> 00:05:50,803 since this will be done dynamically later. 92 00:05:50,803 --> 00:05:54,614 And then I'll just create a div with the class of .group, and 93 00:05:54,614 --> 00:05:56,990 I'll put in a
for our username. 94 00:05:59,056 --> 00:06:03,306 And I'll copy that down and replace the username with an email. 95 00:06:03,306 --> 00:06:12,282 I'll right sjohnson@myteam.com. 96 00:06:12,282 --> 00:06:15,325 Okay, so I think that's it that we'll need for the list item. 97 00:06:15,325 --> 00:06:19,401 So let's copy that and create a few more of these. 98 00:06:19,401 --> 00:06:22,079 And I'm gonna close each of these up so 99 00:06:22,079 --> 00:06:25,361 that we can see our markup a little bit better. 100 00:06:25,361 --> 00:06:27,507 Actually, I think that's all we'll need for the markup. 101 00:06:27,507 --> 00:06:32,037 So let's close down each block and let's review what we've written. 102 00:06:32,037 --> 00:06:35,152 So, inside of our body we just have one child element, 103 00:06:35,152 --> 00:06:37,811 which is our auto-user-search container. 104 00:06:37,811 --> 00:06:41,502 And inside of here we have our actual search-container. 105 00:06:41,502 --> 00:06:43,958 And inside of the search-container holds everything. 106 00:06:43,958 --> 00:06:47,401 We have our image for our search icon, 107 00:06:47,401 --> 00:06:51,605 we have our input, we have our dropdown menu. 108 00:06:51,605 --> 00:06:52,697 So I think that's everything. 109 00:06:52,697 --> 00:06:54,901 Let's go ahead and save this. 110 00:06:54,901 --> 00:06:59,186 And I'm gonna move the mockup back to the side with the HTML file. 111 00:06:59,186 --> 00:07:01,905 I'm gonna open up the Explorer window and 112 00:07:01,905 --> 00:07:05,021 I'm gonna open index.html with live-server. 113 00:07:05,021 --> 00:07:08,770 Okay, so we have our live server open. 114 00:07:08,770 --> 00:07:10,431 And it looks pretty bad right now. 115 00:07:10,431 --> 00:07:11,901 So we need to style this. 116 00:07:11,901 --> 00:07:15,985 But what's important to note is it looks like we have everything we need. 117 00:07:15,985 --> 00:07:21,676 According to the mockup, we have our search icon, we have our search-container, 118 00:07:21,676 --> 00:07:26,902 and we have our list items, and our list items have a name and a email address. 119 00:07:26,902 --> 00:07:30,244 So, let's start styling this up. 120 00:07:30,244 --> 00:07:34,837 Just so that we can kind of see everything better, I'm gonna hop back into our HTML 121 00:07:34,837 --> 00:07:39,184 file really quickly, and I'm gonna comment out the dropdown-container. 122 00:07:39,184 --> 00:07:40,855 And we can come back and 123 00:07:40,855 --> 00:07:45,353 uncomment this out once we're ready to start styling that. 124 00:07:45,353 --> 00:07:47,973 So, let's open up our style sheet. 125 00:07:47,973 --> 00:07:53,665 Let's go to starter/styles/app.css. 126 00:07:53,665 --> 00:07:58,133 Awesome, so the first thing I'll do is, I'll just create a rule for the body. 127 00:07:58,133 --> 00:08:03,145 And I'll give it a background-color. 128 00:08:03,145 --> 00:08:05,443 And I'm gonna use a CSS variable for this. 129 00:08:05,443 --> 00:08:08,741 And if you're unfamiliar with how CSS variables work, 130 00:08:08,741 --> 00:08:12,109 you just write the var keyword with a set of parentheses, 131 00:08:12,109 --> 00:08:15,777 you copy the variable that you wanna use, and you paste it in. 132 00:08:15,777 --> 00:08:20,274 And it's important to note that all CSS variables start with two dashes. 133 00:08:20,274 --> 00:08:24,987 So I'll hit save and you'll notice our darker background color now. 134 00:08:24,987 --> 00:08:27,178 So, let's start styling this up. 135 00:08:27,178 --> 00:08:30,912 I'll do a min-height of 100vh for the body. 136 00:08:30,912 --> 00:08:38,118 I'll give it a display of flex and I'll justify-content center. 137 00:08:38,118 --> 00:08:41,002 And it looks like in the mockup it's a little bit off from the top. 138 00:08:41,002 --> 00:08:47,369 So, what I'll do is I'll target our auto-user-search and 139 00:08:47,369 --> 00:08:52,150 I'll just give it a margin top of maybe 3rem. 140 00:08:52,150 --> 00:08:54,266 Cool, I think that looks good. 141 00:08:54,266 --> 00:08:57,961 So let's also give it a background color. 142 00:08:57,961 --> 00:09:04,221 I have a CSS variable for this called --white and I think that looks pretty good. 143 00:09:06,597 --> 00:09:10,190 Why is this so big? 144 00:09:10,190 --> 00:09:11,361 Let's see. 145 00:09:15,412 --> 00:09:19,507 Okay, so this needs to be in our search-container. 146 00:09:19,507 --> 00:09:22,889 So let's remove that background color, and let's create a new rule for 147 00:09:22,889 --> 00:09:25,501 our search-container, and then paste that in there. 148 00:09:25,501 --> 00:09:28,691 There we go, that looks much better. 149 00:09:28,691 --> 00:09:33,451 I'll give it a border radius of .5rem. 150 00:09:33,451 --> 00:09:34,904 I'll give it some box-shadow. 151 00:09:34,904 --> 00:09:39,512 And I have a CSS variable set up for this too, it's called --box-shadow. 152 00:09:41,500 --> 00:09:45,727 And I'll give it a little bit of padding, we can do .25rem. 153 00:09:45,727 --> 00:09:47,652 Think that looks pretty good. 154 00:09:47,652 --> 00:09:53,745 Now let's target our input and our image. 155 00:09:56,365 --> 00:10:02,240 Actually we have more than one image in this container, so let's give our 156 00:10:03,820 --> 00:10:09,704 Let's give the search-icon 157 00:10:09,704 --> 00:10:14,885 a class of search-icon. 158 00:10:14,885 --> 00:10:20,021 Save that, and we'll come back to the search-container, 159 00:10:20,021 --> 00:10:24,460 and we'll do image with the class of search-icon. 160 00:10:24,460 --> 00:10:27,060 So let's open these two rules up. 161 00:10:27,060 --> 00:10:31,490 And for the search-icon, let's give it a width of 1rem, 162 00:10:31,490 --> 00:10:33,979 which I think looks pretty good. 163 00:10:33,979 --> 00:10:40,946 And we'll do a margin of auto on the top and bottom, and maybe 1rem left and right. 164 00:10:40,946 --> 00:10:45,220 That's way too much, let's do maybe 0.25rem, left and right. 165 00:10:45,220 --> 00:10:46,853 I think it looks okay. 166 00:10:46,853 --> 00:10:51,172 Let's also give a display of flex to the search-container, 167 00:10:51,172 --> 00:10:53,671 and we'll align the items center. 168 00:10:53,671 --> 00:10:59,516 And that's gonna kinda put the search icon in the input container on the same line, 169 00:10:59,516 --> 00:11:02,449 or more centered together, should say. 170 00:11:02,449 --> 00:11:04,578 So great, that looks pretty good. 171 00:11:04,578 --> 00:11:09,785 Let's target the input, and we'll give this a border of none and 172 00:11:09,785 --> 00:11:15,104 an outline of none, and the font-size, we'll up to 1.3rem. 173 00:11:18,764 --> 00:11:23,840 And we'll do a padding-left of 0.5rem 174 00:11:23,840 --> 00:11:29,482 to space it a little bit more away from the icon. 175 00:11:29,482 --> 00:11:31,456 Great, I think that looks pretty good. 176 00:11:31,456 --> 00:11:34,526 One thing though is the auto-user-search. 177 00:11:34,526 --> 00:11:37,290 Let's give it a width of 80%. 178 00:11:37,290 --> 00:11:42,471 But let's give it a max-width of 350px, 179 00:11:45,494 --> 00:11:46,759 Which I think looks pretty good. 180 00:11:46,759 --> 00:11:51,640 But now our input element is outside of the container, 181 00:11:51,640 --> 00:11:55,472 so let's give our input a width 100%. 182 00:11:55,472 --> 00:11:57,962 Great, so I think this is looking pretty good. 183 00:11:57,962 --> 00:12:00,593 Let's also give it a color. 184 00:12:00,593 --> 00:12:04,638 We have a CSS variable named --text for this. 185 00:12:04,638 --> 00:12:07,563 And I'm actually gonna copy this property and 186 00:12:07,563 --> 00:12:12,514 I'm gonna set this on the body as well, so that everything has the same color. 187 00:12:12,514 --> 00:12:14,801 Awesome, you might not notice it, but 188 00:12:14,801 --> 00:12:17,934 it's just a little bit lighter than just pure black. 189 00:12:17,934 --> 00:12:23,051 Okay, so I think that's actually it for the input, as well as the image. 190 00:12:23,051 --> 00:12:29,533 So let's style up the, well, let's take a look at the mockup. 191 00:12:29,533 --> 00:12:34,717 Okay, so it actually does not have a border-radius on the bottom right and 192 00:12:34,717 --> 00:12:35,715 bottom left. 193 00:12:35,715 --> 00:12:40,792 And what I think we can do is we can keep the border-radius as is, but 194 00:12:40,792 --> 00:12:45,603 when the dropdown is open, we can remove that border-radius so 195 00:12:45,603 --> 00:12:49,723 that the dropdown looks like it's part of this input. 196 00:12:49,723 --> 00:12:57,281 So what we can do is, let's give our search-container a class of expanded, 197 00:12:57,281 --> 00:13:03,811 so we'll do search-container when it has the class of expanded. 198 00:13:03,811 --> 00:13:06,503 And when the dropdown menu is expanded, 199 00:13:06,503 --> 00:13:12,205 we want the search-container to have a border-radius of 0.5rem on the top left, 200 00:13:12,205 --> 00:13:17,372 0.5rem on the top right, and 0 and 0 on the bottom left and bottom right. 201 00:13:17,372 --> 00:13:18,744 So let's check this out. 202 00:13:18,744 --> 00:13:23,673 We'll give the search-container a class of expanded, sweet, 203 00:13:23,673 --> 00:13:28,703 and it removes the border-radius from the bottom left and right. 204 00:13:28,703 --> 00:13:29,449 That's awesome. 205 00:13:29,449 --> 00:13:35,138 Okay, so we'll keep that on for now in the HTML because 206 00:13:35,138 --> 00:13:39,974 we're gonna style up the dropdown menu next. 207 00:13:39,974 --> 00:13:44,021 So let's go back to our stylesheet, and 208 00:13:44,021 --> 00:13:48,312 let's target the dropdown-container. 209 00:13:48,312 --> 00:13:50,385 What we'll do is we'll give this a padding. 210 00:13:50,385 --> 00:13:56,079 Actually, we need to uncomment this out, it was commented out in HTML. 211 00:13:56,079 --> 00:13:59,454 So we're gonna put it back into the mockup. 212 00:13:59,454 --> 00:14:02,902 And instantly, everything's messed up, cuz these images are pretty big. 213 00:14:02,902 --> 00:14:07,606 So let's actually target these images really quickly and 214 00:14:07,606 --> 00:14:09,817 give them a smaller width. 215 00:14:09,817 --> 00:14:12,626 So we'll do dropdown-container and we could 216 00:14:12,626 --> 00:14:17,458 just target all the images inside of there and give them a width of 1rem for now. 217 00:14:17,458 --> 00:14:20,469 Sweet, I think that looks pretty good. 218 00:14:20,469 --> 00:14:25,313 So one thing that I do wanna mention is that this dropdown menu is gonna be 219 00:14:25,313 --> 00:14:28,810 positioned absolute, so let's handle that now. 220 00:14:28,810 --> 00:14:32,320 Inside of the dropdown-container itself, 221 00:14:32,320 --> 00:14:37,303 let's give it a position of absolute, the top of 100%, and 222 00:14:37,303 --> 00:14:41,759 a left of 0, and we'll also give it a width of 100%. 223 00:14:41,759 --> 00:14:44,097 And you'll notice that it's completely gone. 224 00:14:44,097 --> 00:14:49,541 It's all the way down here now, and that's because we're positioning this absolute. 225 00:14:49,541 --> 00:14:54,182 And since its parent does not have a position of relative, 226 00:14:54,182 --> 00:14:56,275 its absolute to the body. 227 00:14:56,275 --> 00:15:00,795 So its parent, which is the search-container itself, 228 00:15:00,795 --> 00:15:04,103 we're gonna put a position of relative. 229 00:15:04,103 --> 00:15:09,180 And now you're gonna see the dropdown menu is now underneath the input. 230 00:15:09,180 --> 00:15:13,782 So let's go back to the dropdown-container, and 231 00:15:13,782 --> 00:15:16,995 we'll give it a background color. 232 00:15:16,995 --> 00:15:21,662 We'll do our --white CSS variable. 233 00:15:21,662 --> 00:15:28,541 And let's see, we'll also give it some padding of maybe 0.5rem. 234 00:15:28,541 --> 00:15:32,848 And what we can do is target the dropdown, 235 00:15:32,848 --> 00:15:37,648 actually, the ul with the class of dropdown, 236 00:15:37,648 --> 00:15:42,713 and we'll give it a maximum height of 125px. 237 00:15:42,713 --> 00:15:46,205 And now we see the overflow outside of the container. 238 00:15:46,205 --> 00:15:53,119 And the easiest way to fix this would be to give it a overflow property of auto. 239 00:15:53,119 --> 00:15:55,930 And now we'll have this little scrollbar. 240 00:15:55,930 --> 00:15:59,876 And we can actually style up the scrollbar, but it's important to note that 241 00:15:59,876 --> 00:16:04,206 the styles that I'm about to use for the scrollbar will only work on Google Chrome. 242 00:16:04,206 --> 00:16:06,126 It's not gonna work on Firefox, so 243 00:16:06,126 --> 00:16:09,273 you might not see the same thing if you're using Firefox. 244 00:16:09,273 --> 00:16:14,019 But what we can do is we can target the ul with the dropdown class. 245 00:16:14,019 --> 00:16:20,486 And we can do ::webkit-scrollbar. 246 00:16:20,486 --> 00:16:25,862 And we can give it a background-color, 247 00:16:25,862 --> 00:16:30,063 and we'll use --gray-light. 248 00:16:30,063 --> 00:16:35,273 And we'll give it a border-radius of 25px, 249 00:16:35,273 --> 00:16:41,272 and we'll give it a width of maybe, let's do 10px. 250 00:16:41,272 --> 00:16:43,436 That is way too much width. 251 00:16:43,436 --> 00:16:44,985 Let's do 5px. 252 00:16:44,985 --> 00:16:47,057 I think 5px looks pretty good. 253 00:16:47,057 --> 00:16:51,971 So it might be hard to see, this is actually the scrollbar track, and 254 00:16:51,971 --> 00:16:55,386 we can actually target the thumb for it as well. 255 00:16:55,386 --> 00:17:01,048 So we can write ul with the class of dropdown, 256 00:17:01,048 --> 00:17:05,971 and we'll type in ::scrollbar-thumb. 257 00:17:05,971 --> 00:17:09,696 And all we'll do with this is give it a background-color. 258 00:17:09,696 --> 00:17:14,059 And we'll use our --primary color, which is a light orange, and 259 00:17:14,059 --> 00:17:16,950 we'll give it a border radius of 25px. 260 00:17:16,950 --> 00:17:21,265 And now we have a pretty neat looking scrollbar. 261 00:17:21,265 --> 00:17:22,400 I think it's still a little wide. 262 00:17:22,400 --> 00:17:29,296 Let's maybe do 3px in width, keep it kinda skinny, or maybe 4. 263 00:17:29,296 --> 00:17:30,847 I think 4 looks pretty good. 264 00:17:30,847 --> 00:17:32,816 Okay, sweet. 265 00:17:32,816 --> 00:17:39,714 So now let's start targeting these list items inside. 266 00:17:39,714 --> 00:17:44,481 And actually, we're gonna want to give bottom border-radius for 267 00:17:44,481 --> 00:17:48,926 this dropdown menu, because it is round on the bottom as well. 268 00:17:48,926 --> 00:17:54,541 So, This would be on the dropdown-container, 269 00:17:54,541 --> 00:17:56,495 so we can do border-radius. 270 00:17:56,495 --> 00:18:00,645 We'll do 0 for the top left, 0 for the top right, 0.5rem for 271 00:18:00,645 --> 00:18:04,133 the bottom right, and 0.5rem for the bottom left. 272 00:18:04,133 --> 00:18:07,249 Sweet, and now we have our rounded borders. 273 00:18:08,782 --> 00:18:12,588 Awesome, so let's work on the list items now. 274 00:18:12,588 --> 00:18:17,327 We can target, The ul with 275 00:18:17,327 --> 00:18:21,505 the class of dropdown, and we'll target the list items inside. 276 00:18:21,505 --> 00:18:26,048 And the first thing I wanna do is just give them a display of flex, and 277 00:18:26,048 --> 00:18:28,137 we'll align the item center. 278 00:18:28,137 --> 00:18:34,792 And what we can do now is, Okay, 279 00:18:34,792 --> 00:18:40,015 so this image right here that's targeting these images, let's keep it consistent. 280 00:18:40,015 --> 00:18:45,140 We'll do a ul with the class of dropdown, and we'll just target the list item image. 281 00:18:45,140 --> 00:18:48,761 I'll hit Save, and we shouldn't see any differences, so that's good. 282 00:18:48,761 --> 00:18:51,895 And now I wanna target the group. 283 00:18:51,895 --> 00:18:56,721 So we'll do ul with the class of dropdown, li and 284 00:18:56,721 --> 00:19:03,213 then the class group, and we want to put a margin-left of 1rem. 285 00:19:03,213 --> 00:19:08,014 It might be too much, we'll see. 286 00:19:08,014 --> 00:19:12,552 We're going to target the
inside. 287 00:19:15,942 --> 00:19:21,492 And actually, we're gonna target each one individually, so we'll do :first-of -type. 288 00:19:21,492 --> 00:19:25,801 So I wrote ul with the class of dropdown, li, we're targeting the group, and 289 00:19:25,801 --> 00:19:28,762 we're targeting the very first
element. 290 00:19:28,762 --> 00:19:36,853 And what we'll do with this is we'll just up the font-weight to maybe 500, 291 00:19:36,853 --> 00:19:42,430 do font-size 0.7rem, and let's copy this down. 292 00:19:44,390 --> 00:19:49,161 And we'll change :first-of-type to :last-of-type. 293 00:19:49,161 --> 00:19:56,699 And we'll remove these properties, and we'll just lower the font-size to 0.5rem. 294 00:19:56,699 --> 00:19:59,319 I think that looks okay. 295 00:19:59,319 --> 00:20:02,660 So, now, let's go back to our images. 296 00:20:03,710 --> 00:20:08,271 And what I'll do is I'll do a border-radius of 50% to give it a perfect 297 00:20:08,271 --> 00:20:11,910 circle, and I'll do a background-color. 298 00:20:11,910 --> 00:20:13,820 And we'll use our --primary color for this. 299 00:20:15,650 --> 00:20:20,484 And now, we have our somewhat of an orange background color that matches 300 00:20:20,484 --> 00:20:22,730 the rest of the UI. 301 00:20:22,730 --> 00:20:26,090 I'm not liking the spacing on that margin-left, so let's do 0.5 rem. 302 00:20:27,880 --> 00:20:29,890 And I think that looks pretty okay. 303 00:20:29,890 --> 00:20:37,330 Let's also lower the email address font size. 304 00:20:37,330 --> 00:20:38,310 Cool, I think that looks good. 305 00:20:40,140 --> 00:20:44,170 So now for each list item, let's also give it a little bit of padding. 306 00:20:44,170 --> 00:20:50,122 So we'll go back up to our list item rule, and we'll give it a padding of 0.5 rem. 307 00:20:50,122 --> 00:20:53,600 And that's way too much, let's do 0.25 rem. 308 00:20:53,600 --> 00:20:54,960 I think that looks pretty okay. 309 00:20:54,960 --> 00:20:59,371 And we'll also give them a border-radius of .5 rem to be 310 00:20:59,371 --> 00:21:02,230 consistent with everything else. 311 00:21:02,230 --> 00:21:05,774 And I know what you're thinking, what's the point of a border-radius on that? 312 00:21:05,774 --> 00:21:08,389 If there's no background-color, you can't see it, but 313 00:21:08,389 --> 00:21:09,970 we will have a hover effect on this. 314 00:21:09,970 --> 00:21:12,924 So let's do ul.dropdown li:hover. 315 00:21:12,924 --> 00:21:16,884 And we just wanna target the background-color, 316 00:21:16,884 --> 00:21:20,570 and we'll use our --gray-light CSS variable. 317 00:21:21,870 --> 00:21:28,010 I'll hit that and now when we scroll over, we have a subtle background color change. 318 00:21:28,010 --> 00:21:32,920 So let's actually transition our background color. 319 00:21:34,490 --> 00:21:36,485 0.2 seconds ease, and 320 00:21:36,485 --> 00:21:41,570 we're also gonna want to give a cursor a pointer to each list item. 321 00:21:43,470 --> 00:21:44,550 And I think that looks pretty good. 322 00:21:46,050 --> 00:21:50,466 So I think there's just a little bit too much padding on this left side, or 323 00:21:50,466 --> 00:21:53,090 actually what I think that looks fine. 324 00:21:53,090 --> 00:21:58,132 Let's add in a, or let's adjust the maximum height so 325 00:21:58,132 --> 00:22:02,960 we can see what this looks like with the scroll bars. 326 00:22:06,147 --> 00:22:10,220 So, URL, max height, let's do like 50 pixels. 327 00:22:10,220 --> 00:22:10,870 Okay, cool. 328 00:22:10,870 --> 00:22:12,770 So, our scroll bar still looks good. 329 00:22:12,770 --> 00:22:14,990 Everything's looking pretty okay. 330 00:22:14,990 --> 00:22:17,700 Sweet. So, let's check out the mock-up. 331 00:22:17,700 --> 00:22:19,540 And this looks pretty close. 332 00:22:19,540 --> 00:22:24,870 So it looks like there is a somewhat of a border up here or a divider. 333 00:22:24,870 --> 00:22:29,740 And I think we can tackle that by giving our drop-down container a border-top. 334 00:22:31,370 --> 00:22:35,190 So, let's look for our drop down container, which is right here. 335 00:22:35,190 --> 00:22:42,470 We'll do border top, one pixel, solid and we'll use our, let's try grey dark. 336 00:22:44,140 --> 00:22:48,670 There we go, I think that looks pretty good. 337 00:22:50,180 --> 00:22:53,150 So, yeah, I think this is everything we need. 338 00:22:53,150 --> 00:23:00,040 Let's go ahead and update our maximum height on our drop down again. 339 00:23:01,650 --> 00:23:08,972 Set to 100 pixels, or maybe let's do like something like 75. 340 00:23:08,972 --> 00:23:10,680 What about 65? 341 00:23:10,680 --> 00:23:11,413 There we go. 342 00:23:11,413 --> 00:23:16,309 That way you can kinda see there's another item there so it would let the end user 343 00:23:16,309 --> 00:23:20,640 know that, hey, that you might need to scroll down for more options. 344 00:23:21,690 --> 00:23:25,060 Sweet, so I think we're actually done with the UI. 345 00:23:25,060 --> 00:23:29,817 So now what we need to do is render these items dynamically when a user 346 00:23:29,817 --> 00:23:31,460 types in a name. 347 00:23:31,460 --> 00:23:35,380 I take it back, there is actually one other thing we need to do in the styles so 348 00:23:35,380 --> 00:23:38,550 by default this drop down menu is gonna be hidden. 349 00:23:38,550 --> 00:23:41,230 So we need to go ahead and hide that. 350 00:23:41,230 --> 00:23:45,979 If we look at our dropdown container rule, we'll see that the top is set to 100%. 351 00:23:45,979 --> 00:23:53,870 So what we wanna do is we wanna have a dropdown-container.show class. 352 00:23:53,870 --> 00:23:57,860 So I'll add a class of show to dropdown-container. 353 00:23:57,860 --> 00:24:00,254 And we want the top to be that 100%. 354 00:24:01,410 --> 00:24:05,387 And, we're gonna change the 100% in the original 355 00:24:05,387 --> 00:24:09,830 dropdown-container rule to something like maybe 75%. 356 00:24:09,830 --> 00:24:17,530 And, we're also gonna give it an opacity of zero, and pointer events set to none. 357 00:24:17,530 --> 00:24:22,226 And, pointer events set to none basically removes any events that the pointer can 358 00:24:22,226 --> 00:24:25,503 trigger as far as clicking, hovering, focus all that. 359 00:24:25,503 --> 00:24:30,162 So with that done let's also give it a transition to transition these things so 360 00:24:30,162 --> 00:24:31,940 that we have a smooth effect. 361 00:24:33,010 --> 00:24:37,910 We can just type in transition and we can just write all and do 0.2 seconds ease and 362 00:24:37,910 --> 00:24:41,350 that will transition everything, 0.2 seconds ease. 363 00:24:42,680 --> 00:24:46,945 So in our show class, we need to adjust the top back to 100%. 364 00:24:46,945 --> 00:24:49,819 And we need to bump the opacity back up to one and 365 00:24:49,819 --> 00:24:52,950 give it access to all the pointer events again. 366 00:24:52,950 --> 00:24:58,174 And we can do that by writing pointer-events: all. 367 00:24:58,174 --> 00:25:05,190 So we can test this by going into the Developer Console. 368 00:25:05,190 --> 00:25:09,593 And let's find our dropdown-container and give it a class of show. 369 00:25:12,850 --> 00:25:14,530 And our dropdown menu shows up. 370 00:25:15,680 --> 00:25:16,980 So that's awesome. 371 00:25:16,980 --> 00:25:22,060 Let's also remove the expanded class from our searchContainer. 372 00:25:23,180 --> 00:25:26,857 So I'll remove that and now we are left with the way our UI should look when 373 00:25:26,857 --> 00:25:29,220 the page loads, which is just a search field. 374 00:25:30,640 --> 00:25:32,650 Sweet. So now let's work on the JavaScript. 375 00:25:35,550 --> 00:25:39,270 So what I'll do is I'll open up the app.js file. 376 00:25:39,270 --> 00:25:42,135 And I'm going to open up the developer console again, and 377 00:25:42,135 --> 00:25:44,250 I'm gonna head on over to the console tab. 378 00:25:45,930 --> 00:25:49,424 And I think the first thing that I wanna try to tackle is seeing if I can get 379 00:25:49,424 --> 00:25:53,110 whatever we type in this search field to show up in the browser's console. 380 00:25:54,200 --> 00:25:57,933 So I do know that our input right here has an ID of searchInput, so 381 00:25:57,933 --> 00:26:00,460 let's create a variable for that. 382 00:26:00,460 --> 00:26:07,799 I'll type in const searchInput = document.getElementbyId('searchInput'): 383 00:26:07,799 --> 00:26:11,900 and we want to listen for the keyup event on this. 384 00:26:11,900 --> 00:26:13,154 So let's set up an event listener. 385 00:26:13,154 --> 00:26:17,621 We'll do searchInput.addEventListener, and 386 00:26:17,621 --> 00:26:22,521 we wanna listen for keyup and we want to grab the event. 387 00:26:22,521 --> 00:26:29,480 And what we can do is log the value of this input to the console. 388 00:26:29,480 --> 00:26:31,570 So let's set up a variable for this as well. 389 00:26:31,570 --> 00:26:38,275 We can write, let value=e.target.value. 390 00:26:38,275 --> 00:26:42,596 And let's log this to the console every time this event handler runs. 391 00:26:42,596 --> 00:26:46,400 So we'll console.log(value) 392 00:26:46,400 --> 00:26:50,197 So if I come over here and I start typing, hello world, 393 00:26:50,197 --> 00:26:54,656 you'll see in the console that every single time that this input 394 00:26:54,656 --> 00:26:59,547 detected a key up event it logged the value of the input to the console. 395 00:26:59,547 --> 00:27:04,617 Which is exactly what we want because we're gonna wanna test what words, 396 00:27:04,617 --> 00:27:08,470 and what letters are in here to match with our user data. 397 00:27:09,540 --> 00:27:13,073 So let's go ahead and remove this console.log and 398 00:27:13,073 --> 00:27:16,000 let's loop over our user data. 399 00:27:16,000 --> 00:27:19,046 Or actually let's make sure our input is not empty. 400 00:27:19,046 --> 00:27:24,075 So we'll do if value is not equal to an empty 401 00:27:24,075 --> 00:27:28,281 string we want to first let's see. 402 00:27:28,281 --> 00:27:33,337 The first thing we'll wanna do is probably 403 00:27:33,337 --> 00:27:37,691 add that expanded class to the search 404 00:27:37,691 --> 00:27:42,620 container as well as show our dropdown. 405 00:27:42,620 --> 00:27:46,310 So let's set up some variables for those elements. 406 00:27:46,310 --> 00:27:51,428 So I'll write const searchContainer=document.getElementById('searchContainer') 407 00:27:51,428 --> 00:27:55,459 and 408 00:27:55,459 --> 00:28:01,349 then I'll set up a variable for our dropdown container as well. 409 00:28:01,349 --> 00:28:04,580 All right, const dropdownContainer = document.getElementById ('dropdownContainer') 410 00:28:04,580 --> 00:28:09,440 411 00:28:09,440 --> 00:28:14,123 So if we start typing into our search field and 412 00:28:14,123 --> 00:28:18,435 the value is not empty, we want to take our 413 00:28:18,435 --> 00:28:24,500 searchContainer.classList.add( 'expanded'). 414 00:28:24,500 --> 00:28:32,390 And then we want to take our dropdownContainer.classList.add( 'show'). 415 00:28:32,390 --> 00:28:35,390 So let's start typing and see if anything happens. 416 00:28:36,660 --> 00:28:42,300 Sweet, we started typing and our drop down menu appeared. 417 00:28:42,300 --> 00:28:45,170 So if we backspace it should go away, right? 418 00:28:46,180 --> 00:28:48,460 Nope, we have not written the logic for that. 419 00:28:48,460 --> 00:28:51,780 So, we need to write an else statement in our conditional. 420 00:28:51,780 --> 00:28:57,770 So if we write else, we can just reverse these two statements. 421 00:28:57,770 --> 00:29:01,160 So I'll just change add to remove for both of these. 422 00:29:02,910 --> 00:29:06,558 I'll hit Save and I'll start typing, and then I'll backspace and 423 00:29:06,558 --> 00:29:08,030 I'll start typing again. 424 00:29:08,030 --> 00:29:09,840 And I'll backspace. 425 00:29:09,840 --> 00:29:11,420 Sweet that works. 426 00:29:11,420 --> 00:29:16,569 I am noticing that the border radius or the lack of border radius that is applied 427 00:29:16,569 --> 00:29:21,420 to our search containers instant, so it kind of messes up the animation. 428 00:29:21,420 --> 00:29:24,080 So let's see if we can hop back in the CSS, and 429 00:29:24,080 --> 00:29:26,600 we'll scroll up to the searchContainer. 430 00:29:27,900 --> 00:29:33,295 And we will give it a transition of border radius 0.2 seconds ease. 431 00:29:33,295 --> 00:29:37,160 And now that should be a pretty fluid animation. 432 00:29:38,490 --> 00:29:39,940 Sweet that looks so much better. 433 00:29:41,550 --> 00:29:43,140 Awesome, okay. 434 00:29:43,140 --> 00:29:45,850 And you're probably wondering why there's already people in here. 435 00:29:45,850 --> 00:29:48,090 This is just the static markup that we wrote. 436 00:29:48,090 --> 00:29:52,150 We'll be deleting this pretty soon and we'll actually loop over our data. 437 00:29:53,590 --> 00:29:58,080 So we now have a conditional statement inside of our eventListener. 438 00:29:58,080 --> 00:30:03,004 So our value is not empty we want to show our drop down menu, so 439 00:30:03,004 --> 00:30:08,798 it would make sense that also in this first block of our conditional, we 440 00:30:08,798 --> 00:30:15,484 start matching the users that are in our user data variable up here with our value. 441 00:30:15,484 --> 00:30:20,372 So what we can do is we can loop over userData,so we can do 442 00:30:20,372 --> 00:30:25,468 userData.forEach() and for each user what do we wanna do, 443 00:30:25,468 --> 00:30:30,980 well for each user we want to add them to the page as a list item and 444 00:30:30,980 --> 00:30:34,828 we want to append that list item to our ul, so 445 00:30:34,828 --> 00:30:40,070 we'll need to grab this ul's id and reference it. 446 00:30:40,070 --> 00:30:42,488 So I'm gonna copy this and while I'm in here, 447 00:30:42,488 --> 00:30:46,766 I'm also going to remove all of these li's but one, and I'm only gonna' leave one in 448 00:30:46,766 --> 00:30:49,750 here so that we can copy this markup here and a little bit. 449 00:30:51,080 --> 00:30:56,362 So what we'll do is inside of this for each method, all right userData.forEach()_ 450 00:30:56,362 --> 00:31:00,570 and we wanna write, well, we need to set up our variable first. 451 00:31:01,600 --> 00:31:07,414 We'll type const dropdown = document.getElementById('dropdown') 452 00:31:07,414 --> 00:31:12,658 and now we have access to it, 453 00:31:12,658 --> 00:31:17,560 so we'll put dropdown.innerHTML += 454 00:31:19,390 --> 00:31:25,017 And what we want to render is this markup here, so I'll cut this and 455 00:31:25,017 --> 00:31:29,250 I'll leave a comment in the HTML called dynamic. 456 00:31:31,230 --> 00:31:36,619 And now if we start typing, nothing actually shows up cuz we don't 457 00:31:36,619 --> 00:31:41,622 have anything in there yet, so we will paste in that markup and 458 00:31:41,622 --> 00:31:48,070 the easiest way to get the data that we need is to use interpolation. 459 00:31:48,070 --> 00:31:50,702 So if we come up to our user data variable, 460 00:31:50,702 --> 00:31:55,296 you'll notice that we have a name attribute, I'm sorry, a name property, 461 00:31:55,296 --> 00:31:59,850 an email property and an image, so we'll be using these. 462 00:31:59,850 --> 00:32:05,759 So each time that this for each method iterates over our array, 463 00:32:05,759 --> 00:32:12,950 this variable that we set called user holds that current iteration. 464 00:32:12,950 --> 00:32:17,940 So the first time it will hold the very first item. 465 00:32:17,940 --> 00:32:22,870 So what we can do is in the source attribute, we can do user dot image, 466 00:32:22,870 --> 00:32:27,970 and it will give us a reference to that current iteration of our array and 467 00:32:27,970 --> 00:32:30,560 it will give us the image. 468 00:32:30,560 --> 00:32:36,336 And for the alt attribute we can write a picture of, 469 00:32:36,336 --> 00:32:40,904 and we could write user.name and for 470 00:32:40,904 --> 00:32:46,006 the name we can also just write user.name, 471 00:32:46,006 --> 00:32:51,670 and for the email, we can write, user.email. 472 00:32:53,570 --> 00:32:57,035 And it's important to note that this string interpolation only works if 473 00:32:57,035 --> 00:33:00,290 you're using backticks, so you have to use backticks right here. 474 00:33:02,090 --> 00:33:04,349 So, basically, for each user, 475 00:33:04,349 --> 00:33:08,880 it's going to automatically throw every one of our users in here. 476 00:33:08,880 --> 00:33:12,530 Now, you're gonna see why this is not a good idea. 477 00:33:12,530 --> 00:33:14,651 So, I'm gonna hit save, and if we start typing, 478 00:33:14,651 --> 00:33:16,380 you're gonna see everyone's in here. 479 00:33:17,470 --> 00:33:22,023 So, all we're doing now is just adding all these users each time the event 480 00:33:22,023 --> 00:33:24,160 handler runs, which is not good. 481 00:33:24,160 --> 00:33:28,182 Look how many users we have, we actually only have a few users in here, 482 00:33:28,182 --> 00:33:29,690 we don't have that many. 483 00:33:30,890 --> 00:33:34,965 So what's happening is each time this runs, 484 00:33:34,965 --> 00:33:40,885 we're just adding and adding and adding to this unordered list. 485 00:33:40,885 --> 00:33:44,180 So, What we should do is reset it each time. 486 00:33:44,180 --> 00:33:46,549 So at the very top of our if statement, 487 00:33:46,549 --> 00:33:50,340 we wanna do dropdown.innerHTML = ''; 488 00:33:51,780 --> 00:33:55,353 And now no matter how many times we type, the list of users will never get any 489 00:33:55,353 --> 00:33:57,650 bigger it'll always be our full list of users. 490 00:33:58,990 --> 00:34:01,810 So that leaves us with one other problem, 491 00:34:01,810 --> 00:34:05,928 is we want the users to match the search, so how do we do that? 492 00:34:07,857 --> 00:34:13,080 Well, this problem is actually really easy, so inside of our four loop, 493 00:34:13,080 --> 00:34:17,376 we can run another conditional to test if the value is equal or 494 00:34:17,376 --> 00:34:20,440 includes any of the usernames. 495 00:34:20,440 --> 00:34:26,266 So what we can do is, we can write if and then in here we can put user.name and 496 00:34:26,266 --> 00:34:32,480 we wanna make sure it's in toLowerCase() so that we can always match the string. 497 00:34:32,480 --> 00:34:38,420 So we'll do .toLowerCase() and we'll write that includes value, 498 00:34:38,420 --> 00:34:42,820 and we'll also do .toLowerCase() on the value. 499 00:34:43,900 --> 00:34:49,287 And if this is true, we want to run this bit of logic right here, 500 00:34:49,287 --> 00:34:51,330 so I will paste that in. 501 00:34:52,770 --> 00:34:53,270 Oops. 502 00:34:54,340 --> 00:34:59,020 So I'll cut this and I'll paste this in the conditional, and I'll hit Save. 503 00:34:59,020 --> 00:35:00,975 So now if I come over here and 504 00:35:00,975 --> 00:35:05,330 I start typing in things It actually will start matching. 505 00:35:05,330 --> 00:35:10,220 So if I type in Samantha,Samantha Taylor will show up, if I type in Sam, 506 00:35:10,220 --> 00:35:15,512 we have Samuel King,Sameer Johnson and Samantha Taylor, if I type in Smith, 507 00:35:15,512 --> 00:35:20,909 we have two people with the same last name Jay Smith and Kenan Smith both show up. 508 00:35:20,909 --> 00:35:26,269 And if we just start typing, it will always match the person. 509 00:35:26,269 --> 00:35:29,761 Sweet, so that about covers it for using just a little bit of JavaScript to add 510 00:35:29,761 --> 00:35:32,550 a ton of functionality to your Web page. 511 00:35:32,550 --> 00:35:35,742 I hope you were able to understand the relationship between the markup and 512 00:35:35,742 --> 00:35:39,500 the JavaScript, and how we use the DOM to kind of tie it all together. 513 00:35:39,500 --> 00:35:42,890 This is a great feature to add to your projects, even your old ones. 514 00:35:42,890 --> 00:35:45,469 So I hope you build something really, really great with this, 515 00:35:45,469 --> 00:35:48,500 I'll see you in the next one, and until then, have fun and happy coding.