Creating Article model0:00
Let's take a moment and apply everything that we have talked about thus far, and this will be at least something that is somewhat usable. So let's start by making a model called Article. We want the migration, we also want a factory. The idea being that we are going to have some data that we can search, so that we will have a form that we will type a search term into, we will perform that search, and then of course display the results in the browser. Let's start with the migration, we are going to add two columns, both are going to be strings. The first is going to be the title for that article, the second is simply going to be the content, and that's it for this example.
The first is going to be the title for that article, the second is simply going to be the content, and that's it for this example. Next let's open up the factory, because we want to supply some actual content that we can search. So let's start with our title, and we will use Faker to generate some real text, and we'll have a length of 50, because the title doesn't necessarily need to be very long. The content, however, does need a little length to it. So let's also make this real text, and we'll have a length of 500. But that's going to be sufficient for our needs, so then we just need to seed our database. Now of course we could comment all of this out, but I think what we'll do is just wipe
Seeding the database1:14
But that's going to be sufficient for our needs, so then we just need to seed our database. Now of course we could comment all of this out, but I think what we'll do is just wipe the database, run the migrations, and then the seeder, and everything else is going to be fine. So we'll start off with the Article, we want to use the factory, so that we will create, let's have 50 articles. So we'll have a count of 50, and then we want to create those. And then it's just a matter of getting the database all ready to go. So let's start by just wiping the database, so that we can migrate the database, and then seed the database.
Building search component UI1:45
So let's start by just wiping the database, so that we can migrate the database, and then seed the database. And now we're ready to make a new Livewire component for searching our data. So we're just going to call it search, and let's open up the Blade view. Let's also open up the greeter.blade.php view, because this gives us a pretty good starting point, at least as far as the form is concerned. We of course do need to make a few changes, like for example, we aren't going to be submitting this form, because the text box is going to be the only input element. We aren't going to have a select, we aren't even going to have a button. So let's get rid of the error message, let's get rid of the button.
We aren't going to have a select, we aren't even going to have a button. So let's get rid of the error message, let's get rid of the button. And let's add a class, w-full, to the input element, just so that it will span the width of the page. But of course, we need to open up the welcome view, so that we can use our new search component instead of the greeter. So we'll just make that change to search, and now that's great. But I do want a placeholder here, just so that we know that this is a place to type something to search. So with that in place, we can close everything else, because all we need is our view, and
Adding component state validation2:54
something to search. So with that in place, we can close everything else, because all we need is our view, and then we need the Search class. So really, there's only two things that we need to be working with as far as our component is concerned. We will need the searchText, which we can initialize as an empty string. Then we will need our searchResults, which we will initialize as an empty array. Now we do need some validation here, so let's use the validate attribute. And really, we only need to be sure that we have something to work with, because we should be able to let the user search with a single character, if that were the case.
And really, we only need to be sure that we have something to work with, because we should be able to let the User search with a single character, if that were the case. So all we need is required. Now because our form does not have a button to actually submit the search, we are going to need to do something when the user types into that input element. So we need to change the model to searchText. I'm gonna add the live modifier, but we don't want this running for every keystroke. Just like we learned a couple of lessons ago, we can debounce this. So let's do that. I think the default value for debounce is gonna be fine, so I'm not going to specify.
So let's do that. I think the default value for debounce is gonna be fine, so I'm not going to specify that anymore with another modifier. But then we also need a place to display our search results. So let's have a div that is going to serve as our container, and we'll just have some margin at the top. So that inside of here, we will have our foreach results as result. Of course, we don't have anything to work with yet, but this will at least give us our boilerplate stuff. So that then we can have a div, let's give it a padding at the top for 2.
Implementing search logic4:25
this will at least give us our boilerplate stuff. So that then we can have a div, let's give it a padding at the top for two. And then here, let's just output the title of the result. So now all we really need to do is perform the search. When the user types something into the input element, we want to get that value and then perform our search. And we can do that using the updated hook. But in this case, we want the updated searchText hook, because that's really the only update that we care about. And there are a few things that we need to do.
because that's really the only update that we care about. And there are a few things that we need to do. First of all, I want to reset the results. Because if we are performing a new search, I want to clear out any existing results that we might have. The next thing I want to do is create my own searchTerm, because I'm going to use a like query. Now, of course, there are many other ways that we can approach this. But for this particular exercise, this is going to be fine. And then finally, we are going to set results based upon if we find
But for this particular exercise, this is going to be fine. And then finally, we are going to set results based upon if we find any articles where the title is like our searchTerm. And then, of course, we want to get those results. Now we can see I have an error because I have invalid syntax. I need a public function updatedSearchText. So now let's just perform a search. Let's put in a single character. We can see that we get a lot of results. So let's see if we can filter this down even more by searching for after.
We can see that we get a lot of results. So let's see if we can filter this down even more by searching for after. So now we see after in that first one, there's after, and then there's after. So it looks like our search is working just fine. So what happens whenever we clear out our search box completely? We can see that we still get search results. In fact, it looks like everything is here. And the reason is very simple, because we aren't validating the search text. And we can do that very easily by just calling the validate method after we reset the results.
And we can do that very easily by just calling the validate method after we reset the results. So now we can type after, we will see the same results that we got before. We can back out to where we see a lot. We should probably search for something else. Not every title is going to have an M, so let's do that. But notice, whenever we clear out the search box, all of our results go away. And that is exactly what we want, because we don't want to display anything when we haven't technically really searched. But that's not enough, because we need to provide a clear and
Adding clear button behavior6:45
when we haven't technically really searched. But that's not enough, because we need to provide a clear and easy way for users to, well, clear the results. So let's do that by adding a button. I want this button to be in line with this input element. So let's change its width from full to 9 out of 12. And then we'll just add our button. The text is gonna be white. Let's give it a medium font. Let's also give it the same rounded corners as the input element,
Let's give it a medium font. Let's also give it the same rounded corners as the input element, as well as the same padding. And the background color, let's do indigo 600. And I think that that's gonna be fine. The text will be clear. And yeah, I think that's gonna work just fine. So whenever we click on this button, we want to call an action. So let's say it will just be called clear. And this action method is, well, it's gonna be very simple.
So let's say it will just be called clear. And this action method is, well, it's gonna be very simple. Because all we really need to do is, well, clear the results. But not just the results, we also need to reset the searchText. So we can pass multiple property names to the reset method. And that's going to give us, well, exactly the functionality that we need. So we can save those files. And let's give this a try in the browser. So we perform a search, we see our results. And whenever we click on the Clear button, well, it cleared it.
So we perform a search, we see our results. And whenever we click on the Clear button, well, it cleared it. But only because it actually submitted the form. And while that's not the behavior that we wanted, this is the behavior that we should expect. Because we have a button inside of a form. And by default, a single button is going to submit that form. So we need to solve this in one of two ways. We can either take out that form element, because really it doesn't serve us any purpose.
We can either take out that form element, because really it doesn't serve us any purpose. Or we can use a modifier to prevent that default action from occurring. Let's do that, because we haven't really talked about the prevent modifier. It's very simple. It simply prevents the default action from occurring for whatever event we have set up on that element. So the default action of clicking a button inside of a form is to submit that form. We are therefore preventing that from occurring. So now, whenever we perform a search, we see our results.
We are therefore preventing that from occurring. So now, whenever we perform a search, we see our results. We can click on the Clear button. It did not submit that form, and it cleared the results. The only other thing I want to do is change the styling of the Clear button when there is really nothing to clear. Really what we want to do is set it to disabled. And we can do that very easily, because after all, this is just a Blade view. So we can check if the searchText is empty. And if it is, then we will simply output the disabled attribute.
So we can check if the searchText is empty. And if it is, then we will simply output the disabled attribute. Otherwise, we don't need anything, and that's gonna work. However, visually, we don't really see anything, so we need to add some other styles here. So we will use disabled, bg-indigo-400, let's do 400. So immediately, we can see that the button is indeed disabled. Whenever we type something into the textBox, we get our search results. The Clear button is clickable. We clear, and everything goes back.
The Clear button is clickable. We clear, and everything goes back. And this is perfect, because it's based upon the search text. So even if there aren't any results, we would still want to be able to clear our input element. So we clear it, and everything goes back as it should. Well, that reviews just about everything that we have talked about thus far. And it gives us something else that we can use. Because now that we have some articles, we want to actually see those articles in their own individual pages.
Because now that we have some articles, we want to actually see those articles in their own individual pages. And we will look at how we can implement that in the next episode.
