تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Creating Livewire Component0:00

Okay, let's build the search drop down. And for that, we're going to be making use of Livewire once again. So let's get started. Let's make a new Livewire component, php artisan livewire:make, let's call it SearchDropDown. Okay. And let's move some of this markup into that Livewire component. So I'm in my app.php. And I want to move this, which has the searchInput. So that's this. And let's put it into the SearchDropDown component. So when we cut this, I'm going to say Livewire SearchDropDown. And let's go ahead and open that up. And let's paste that in. Okay. This should still work. And let's see if it still works. Okay, cool. And let's focus on the styling first. So let's do that. So I'm going to make a new div here. And this will be the results for the drop down. So let's make it absolute. And let's give it a high z-index, make it gray-800.

Styling Dropdown Results1:04

So I'm going to make a new div here. And this will be the results for the drop down. So let's make it absolute. And let's give it a high z-index, make it gray, 800. Let's make it small text, make it rounded, let's make it width 64. And give it a margin top. Okay. And let's put an ul here. And make an a tag. Because each result is going to be a link. So let me just reformat this. And let's format this link. Let's make it block, hover, PG, gray, 700. Let's give it some padding. And just see what this gives us. So let's say game one. And let's just duplicate this a few times to three and see how this looks. Okay, that looks pretty good. Let's put a border between each item. So I'm going to do this again, and put a class on the list item. Border, B, border, gray, 700. Okay.

Okay, that looks pretty good. Let's put a border between each item. So I'm going to do this again, and put a class on the list item. border, border, gray, 700. Okay. That's only one. Let's duplicate that again. Stick with two for now. Okay, looks good. And there's a hover work does. Okay. And I want a small image here. So let's do that. So the anchor tag will be flex items center. And I want to put a transition on it like we did for images. So transition, ease in out duration 150. And the first flex item is going to be the image. And I believe I have just a image here. So let's grab this for now. And then we'll replace it later. Just put that in there. Let's say cover. And the second flex item is just the name of the game. Put a margin left on it. Say Zelda. Okay, see how this looks. Okay, let's give the image a width.

Binding Input with Livewire3:10

Just put that in there. Let's say cover. And the second flex item is just the name of the game. Put a margin left on it. Say Zelda. Okay, see how this looks. Okay, let's give the image a width. image a width. So say, glass with 10. Okay, so that looks good to me. So let's go ahead and start wiring this up with Livewire. So I'm going to make a wire:model on the input. So let me just reformat this. So I'm going to do wire:model. And this will update the property on the class, which we'll work on in a second. So wire:model equals search. So this will be the public property on the class. And it will get updated every time we type something in here. And if you want, you can also debounce and give it a time. I think the default is 150. I want it a bit higher. So it doesn't keep making requests to the back end as you type.

and give it a time. I think the default is 150. I want it a bit higher. So it doesn't keep making requests to the back end as you type. Okay, so let me save that. And let me just dump that here. You'll get a better understanding of how wire:model works. So let me just dump the search variable here. And let's go to our class. So SearchDropdown. And let's make that variable. So public $search. And this is what's coming from the input. And we'll get updated as we type. And let's make it empty to begin with. So if I type in here, you'll see that it updates. Cool. Okay, I can get rid of that now. And let's go back to our SearchDropdown class. And I also want a piece of state here which will hold our searchResults. Let's say $searchResults. And it's going to be empty by

Fetching API Search Results5:03

And let's go back to our SearchDropdown class. And I also want a piece of state here which will hold our searchResults. Let's say searchResults. And it's going to be empty by default. And here, we can actually make use of the API and get some results and update the searchResults here. So let's do that. So I'm just going to grab a piece of code from one of our other components. So let's grab this. And let's go back here. And let's just say searchResults equals that. And let me just show you how to use this. So if you go to the docs, you'll see that there is a section for search here, the endpoint is the same. And all we have to do is give it a search string. So let's go ahead and do that. Actually, let me show to you in my REST client first. So I have an endpoint for search, we're searching for Zelda, and we just want these fields back. If I do this, you'll see the results come back. So let's do that within

in my REST client first. So I have an endpoint for search, we're searching for Zelda, and we just want these fields back. If I do this, you'll see the results come back. So let's do that within Laravel. So let's say search. And we want to search in quotes, let's escape the quotes, has to be double quotes. And we are getting that from the search variable, which gets updated as we type. And don't forget the semicolon. And the fields we want is just name, slug, and coverURL, that's all we need. Let's get rid of all this. Say slug, cover.urls, but a semicolon. And I'm going to limit it to however many fits on the screen. We'll see. I'll stick to six for now. And the endpoint is the same. So let's go ahead and dump this and see if we're getting the correct results. So let's say dump this searchResults. Okay. And let's type and let's see if it changes as we type. And we have to import HTTP. So there's the dump. Let's see if it updates if we type.

Rendering Results and Links7:01

results. So let's say dump this search results. Okay. And let's type and let's see if it changes as we type. And we have to import HTTP. So there's the dump. Let's see if it updates if we type something. And it does. Cool. And these are the results for Zelda, and I limited it to six. So this does work. Cool. So now we can update the view. So let me get rid of this dump. So let's go back to our view. And now for each list item, we can loop over them. So let's do foreach, say, searchResults. That's the public variable that's updating. Let's say game. And let's just move this list item in there. Okay. And let's update the name. So it's just game.name. And for the cover, we have to check if it's set, because sometimes there's no cover. Let's do isset(game.cover). So if it is set, we can do this. And I'm just going to grab the code

And for the cover, we have to check if it's set, because sometimes there's no cover. Let's do isSet game cover. So if it is set, we can do this. And I'm just going to grab the code that replaces the string. So let's go to a different component. Let's go look for a place. So it's just this code. Grab this back here. And it's replaced to this. Back here. And it's replaced to this. And let's just paste that in. Okay. And it's going to be coverSmall. And this is just game cover. No, that's the right one. And if there is no cover, we can just put in a placeholder here. And I'm just going to paste that in. Now, if you remember the videos where we refactored our code, we can do that, too. And I might do that in the final code. But

And I'm just going to paste that in. Now, if you remember the videos where we refactored our code, we can do that, too. And I might do that in the final code. But for this video, I'm just going to leave it like this. Okay. Let's try this out. And search for Zelda. And there are the results. So I think we can fit a few more. So let's say limit eight or nine back to search drop down, say eight. Okay. And I also forgot the link. So we want to click on the link, no pun intended, and go to that game page. So we already have the slug coming back. So we can do that easily in the view right here. We can just say route(games.show, $game->slug). That should link correctly. Let's try again. Zelda. And this will link to that page. Cool.

Cool. So if we type more than three, but there's nothing that it will show. Awesome. And we can also put this in the class, so it doesn't perform that call. If we go here, we can wrap this whole block of code in an if as well. So if that, and let's put the curly brace, and let's put the ending one here, and let's just reinvent this. Okay. So this should still work. Sorry, this should be this search. Okay. One more time. Cool. Let's add a loading spinner here for when our app is loading data from the API. So Livewire makes this really easy. So I'm just going to add it up here after the search input. And let me just add the spinner first. So if you remember, I installed that Tailwind CSS spinner library, and we used it before we made that skeleton loader system.

input. And let me just add the spinner first. So if you remember, I installed that Tailwind CSS spinner library, and we used it before we made that skeleton loader system. And all we have to do is make a div with a class of spinner to have it render. So let's see if that renders anywhere here. Okay. So there it is. We have to make it absolute, and then we can place it right here on the right. So by default, I believe it's relative. So we have to overwrite that. So let me just add a few classes here. top: 0, right: 0, and let's add a margin-right: 4, and a margin-top: 3. And like I said, I have to overwrite it. So it might work if I just put an inline style. So let's see. If we do position: absolute, will that overwrite the relative or no? Let's see. Okay. So it does. So that works out. So now to make it show only when it's loading, we just have to give

Adding Spinner and Tests13:34

see. If we do position: absolute, will that overwrite the relative or no? Let's see. Okay. So it does. So that works out. So now to make it show only when it's loading, we just have to give it wire:loading, and that will only show once it's loading. So by default, it doesn't show, but when we're searching, it shows. Cool. Okay. Let's quickly test our Livewire component. So back to our code. Let's go to our tests, and let's make a new one. I'll just duplicate this, and let's call it SearchDropdownTest, and let's make sure to rename this, and we don't need this. Okay. And for our test, let's call it the SearchDropdownTest. Searches for games. Okay. And the endpoint is the same. Let's fake search games, and I'm going to paste that in. So if you remember the testing video, I'm just going to paste in a similar response to the actual response, and then we can assert

search games, and I'm going to paste that in. So if you remember the testing video, I'm just going to paste in a similar response to the actual response, and then we can assert against that data. So I'm going to paste that in right now. Okay. So I pasted in that method, and we have a fake response here. So now we just have to assert against that data. So let's remove this. Let's change this to our searchDropdown. Let's import that. Okay. And first thing I want to assert is assert that we don't see the string Zelda because we haven't searched for it yet. So this should work. So let me run this test. Okay. And now I want to set the search. So I'm going to set this variable to our searchQuery. So I'm going to search for Zelda. So let's just set the search public property to the thing we

Okay. And now I want to set the search. So I'm going to set this variable to our search query. So I'm going to search for Zelda. So let's just set the search public property to the thing we want to search for. And then we can assert against any data that we have in our fake response. And I believe I have Breath of the Wild somewhere in here. Okay. And I'm going to rename it to fake just so it's clear that it's a fake. So let's assert against that data. And then you can assert other games as well. So let's do one more. Let's do Ocarina of Time. So let me just grab this. Let's call it fake as well. Okay. And let's assert that as well. So let me just duplicate this and paste that in. And if I did everything correctly, save and run this test, everything should be passing. And it does. Cool. So we successfully built this Livewire component that searches the API for games.

And if I did everything correctly, save and run this test, everything should be passing. And it does. Cool. So we successfully built this Livewire component that searches the API for games. We've tested our component as well. But in terms of UX, it's not the best experience because we're missing things like clicking off of the dropdown to hide it, maybe pressing escape to hide it, and stuff like that. So in the next video, we'll take a look at adding this interactivity using AlpineJS.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟