Show and style the search results

Constantin Druc ยท 02 Jan, 2022

[00:00] Let's move on with the search functionality. Here, on the search field, we'll add an input event listener that will receive the event as a parameter and call a search function with the field value. To get the field value we can do e.target.value.

[00:20] Now let's go to our setup and define the search function, but before we do that, let's define our results reactive object to store the search results; this will be an array. Let's add the search function, we'll receive term as a parameter, and then make an axios get request to the endpoint that will return the results. In my case, I have this dummy endpoint at tallpad.test/search. To send the term as a query parameter we can pass a second object that will have params, and then an object with the term key containing our search term. Let's console.log the results, and since we're using await, we'll have to turn this function into an async one, and then make sure we import axios. Then let's expose the results, and the search function, go in the browser open the modal, open the dev tools, type something in, and here's our request. We're passing term as a query parameter, and if we look at the logs, we see the results being logged in.

[01:22] Back to our search function, we can use the structuring to get the data, and then results.value = data;. One thing I want to do is make sure we debounce this function so it's not being called with every keystroke. We'll do debounce, paste in the function, and let's say 250 milliseconds. Let's import the debounce function from lowdash, go in the browser, refresh, open the vue dev tools, open the modal, and type in laragel. The results are empty but if we refresh, here they are.

[02:01] Moving on, let's add a list and loop through the results to display them. We'll go here, under the form and do ul, and we'll only show this if we have results. So v-if="results.length > 0", then we'll do li, v-for="(item, index) in results", we'll set the key to index, and then we'll have an image where the source will be item.featured_image, the alt will be item.title, and then we'll have a container with one div for the title, and another one for the item category. Save, and the results appear but the form is a bit broken. The search icon and escape button are centered to the modal instead of just the form input. That's because these two are absolute elements and the form is missing the relative class. Let's add it, and the issue is gone.

[03:03] Another problem has to do with the images not being displayed. So let's scroll down to them and here's the problem; it should be featured image. Save, and here they are. Let's continue styling the results. For the li we'll do flex item-center px-4 and py-2.5 for padding. The image will have w-16 h-16, rounded-full object-cover. We'll also add a white border using border-white border-2 and to prevent the image from shrinking, we'll add shrink-0 and let's also add the bg-gray-200 to show like a placeholder while the image is being loaded.

[03:51] For the title and category container we'll just add a bit of left margin, then for the title we'll have font-semibold text-gray-600, and for the category we'll have text xs text-gray-600 and mt-1 for margin; and here they are.

[04:13] It would be nice to have like a border separating the items, so let's go to our list element and add divide-y divide-gray-100. Now the list looks somewhat nice, but if I try and scroll it, it doesn't work. To make the list scrollable we need to do two things: the first is wrap it into a parent container that has an overflow-auto class, and the second is to make that container take the remaining space of the modal. To do that we can go to our modal container and turn it into a vertical flex using flex flex-col, save, and here it is, we can now scroll the list.

[04:55] Another thing that's missing is the anchor tag. We want the whole list item to be clickable. To do that we can go to our li element and add an anchor tag, fill in the href attribute, and then inside it we'll add a span absolute inset-0 and make the li relative. Now if I go into browser, we see that the whole list item is clickable.

[05:30] One last thing I want to do is to add a message for when there are no results to be displayed. I'll go here under the list and say <p v-if="results.length === 0">No results...</p>, and let's style it a bit. We'll do pt-20 text-lg text-center text-gray-400. Let's test it out, and here it is.

[06:08] Finally, let's make sure that when we open the modal the results are already there. So we'll go to our setup and let's say on onMounted(() => search()). Let's make sure we move these two after the results and search function, save, refresh, and here it is.