This episode is for members only

Sign up to access "Build a Forum with Inertia and Laravel" right now.

Get started
Already a member? Sign in to continue
Playing
49. Searching discussions

Episodes

0%
Your progress
  • Total: 6h 54m
  • Played: 0m
  • Remaining: 6h 54m
Join or sign in to track your progress
01. Introduction and demo
6m 59s
0%
02. Getting set up
10m 36s
0%
03. Modifying registration for usernames
7m 15s
0%
04. Figuring out the forum layout
5m 57s
0%
05. Creating and listing topics
9m 15s
0%
06. Basic discussion listing
13m 33s
0%
07. Pinning discussions
4m 1s
0%
08. Tackling pagination in Inertia
8m 23s
0%
09. Customising pagination text in Laravel
52s
0%
10. Showing a discussion
6m 4s
0%
11. Setting up discussion posts
5m 53s
0%
12. Listing through discussion posts
5m 28s
0%
13. Adding more data to posts
8m 24s
0%
14. Adding pagination to posts
1m 35s
0%
15. Adding a post preview to discussions
4m 52s
0%
16. Adding the last reply to discussions
5m 54s
0%
17. Outputting discussion participants
8m 4s
0%
18. Limiting participants in the UI
5m 56s
0%
19. Ordering discussions by last post
4m 30s
0%
20. Handling deleted users
2m 31s
0%
21. Counting replies
8m 13s
0%
22. Building our first filter
8m 31s
0%
23. Highlighting current filters, and merging with pagination
5m 37s
0%
24. Adding auth specific filters
6m 40s
0%
25. Adding the topic filter
8m 18s
0%
26. Scaffolding the new discussion form
13m 29s
0%
27. Toggling the create discussion form
9m 2s
0%
28. Keeping form state
4m 59s
0%
29. Storing a new discussion
11m 29s
0%
30. Discussion validation and authorization
5m 1s
0%
31. Generating markdown for posts
8m 37s
0%
32. Toggling the markdown preview
7m 43s
0%
33. Fetching and displaying markdown
8m 6s
0%
34. Adding a markdown shortcut toolbar
5m 53s
0%
35. Dealing with SVG icons
7m 46s
0%
36. Creating the reply form
7m 48s
0%
37. Basic Inertia permission checking
6m 26s
0%
38. Creating replies to discussions
5m 37s
0%
39. Jumping to posts
11m 40s
0%
40. Automatically scrolling to posts
6m 18s
0%
41. Toggling post editing
7m 32s
0%
42. Editing posts
3m 36s
0%
43. Deleting posts
4m 21s
0%
44. Deleting discussions
6m 7s
0%
45. Setting up for best answers
7m 29s
0%
46. Toggling the best discussion answer
12m 14s
0%
47. Solved and unsolved filters
2m 23s
0%
48. Indexing discussions for search
8m 6s
0%
49. Searching discussions
12m 35s
0%
50. Debouncing search
2m 47s
0%
51. Adding mentionable functionality to forms
6m 32s
0%
52. Indexing users for mentioning
9m 9s
0%
53. Hooking up users for mentions
10m 10s
0%
54. Detecting and storing mentioned users
9m 54s
0%
55. Adding the mentioned filter
2m 26s
0%
56. Adding mentions to the markdown toolbar
1m 1s
0%
57. Adding mentions to the reply form
7m 21s
0%
58. Fixing up some unauthenticated state
1m 1s
0%
59. Fixing up post scrolling
1m 48s
0%
60. Reviewing SSR (Server-side rendering)
8m 20s
0%
61. Preventing parent posts from being deleted
2m 31s
0%
62. Improving solution marking
4m 9s
0%

Transcript

00:00
The first step to getting search working is obviously having a search bar. So let's go ahead and build that out. First of all, we know that lives over on our forum index and it will just go next to our topics list.
00:12
So let's search all topics. And what do we have here? So we've got this here and we want our search to go just before that. And we want a flex grow on this.
00:23
So it pushes all of that content out. Now, at the moment, that is not a flex. So let's say item center. And there we go. Great.
00:32
So let's have our search bar into here now. So this is just going to be a standard text input. Let's just check that we actually have this imported. And it looks like we don't.
00:43
So let's go ahead and do that. First of all, let's find one of these. Text input. And let's go down to that text input and change this over.
00:54
So the type of this can be changed to search because that's going to give us that X icon at the side of this when we actually have some search items in there like that. So we can just clear it off by clicking on it, which is handy.
01:09
The idea of this can be searched because we are going to add in a label to this. And let's go ahead and give some additional classes here to stretch this out. So we'll set a width to full. And that should be good.
01:24
Looks fine to me. We can add a placeholder in here as well. So search for a or search discussions. That's fine.
01:35
And let's just separate these two things out. So space X six, maybe. And maybe that's bummed that down a little bit to three. OK, yes, that's fine.
01:47
We can start searching in here and our results will automatically all come through. So let's just go ahead and add in an input label to this. And that's going to be for search. And the value of this is going to be search.
02:04
Let's just make sure that's hooked up properly. And it is before we go ahead and set screen reader only. OK, our search input is there. Now we just need to figure out when we type, how do we make a search?
02:19
So there's a couple of ways that you can approach hitting Mellis search to actually get back data. We are going to be covering doing this directly from the client side when we look at mentioning people in discussions later,
02:31
because we're going to be using Mellis search to drive the search for usernames throughout our app. But in this instance, what we're going to do is we're just going to add a query on the back end to pull back the results
02:46
we want based on what is typed in here. So it's going to be more of a back end thing here. You can switch this over later. But since we already have a list of discussions here being driven
02:57
from our back end, it makes sense to just reload that data based on what we've already searched here. So we're going to offer in this course two solutions to this, which you can chop and change if you need to.
03:08
OK, so the first thing we need to do is work out how do we trigger this search? It's just a basically just an input. How do we do this? Well, we're actually going to go ahead and hook this up to a model
03:19
and then we're going to watch that model for changes. So we're going to go ahead and say search query, because we can actually then use that model to grab the value of this pretty easily. There are lots of different ways to do this, but this just seems a little bit
03:31
cleaner. And if we go up to the top here, let's just do this all down here. We're going to go ahead and create out a search query variable. It's just going to be a ref with an empty string. So let's go up and make sure we have ref imported from view,
03:46
which it doesn't look like we have at the moment. So import ref from view. And then we're going to watch this. So let's pull in watch now and let's go down to here.
03:58
We're going to watch the search query. And when that changes, we're going to do something. Let's just console log out search for now so we can see that this is working. And let's try this out.
04:10
So let's open up our console here, type something in. And sure enough, I've typed three characters and we have three console logs. Now, we're going to change this over later to debounce this because we don't want a request sent for every single character we type, because that's going to be sending
04:26
a huge amount of requests to our back end and it's going to really just slow things down. So we'll debounce that when we've got this working. So we know that we're not sending too much data down or back. Now, before we go ahead and fill this in, let's take a look at how we actually make
04:41
a search with Laravel Scout. So I'm going to come over to the forum index controller. We're going to do this right up here on the discussion model before anything gets rendered out, just so we can see how this works.
04:53
Now, we can use the model directly because remember, over in the discussion model, we added that searchable trait to here. This searchable trait contains the ability to, if we just look here, actually search on this so we can pass a query in to find this within MeliSearch or any other driver
05:14
that we're using to actually bring back the results. So we can just say search and then we pass in a query and we get back the results that we want. So let's go and find something in here that is a little bit more unique. So if we look for Laravel, we should just get back one topic or one discussion.
05:32
So let's search for Laravel in here and we'll go ahead and die dump on this and we can just continue to chain like we normally would like get. So that will just get a collection of results back here. So sure enough, back from MeliSearch, this has pulled back the discussion that matches
05:47
these. This is very, very powerful search functionality that you can add to later if you want to. But generally, this works really nicely. For example, if we kind of misspell Laravel and write L-A-R-V-E-L, we should actually still get that discussion back.
06:03
So we have got spelling mistake checking in there as well. So that's how this search functionality works. We just use the search function method and then just use get to pull back a collection of these records. Now, we're going to do things slightly differently because what we want
06:18
to do is basically take this query that is potentially being typed into here, make a manual inertia request not to link anywhere, but just to reload the page. We're not posting a form here. We're just reloading the page with new data.
06:37
So let's just see how that looks over on the client side, first of all, making sure that we have our router pulled in here. Yeah, we do. So we're going to go ahead and say router reload. All that will do within inertia is just make a request to the same page that we're on.
06:57
And what we can do in here is pass down the data that we actually want to send. So, for example, we could send search and let's just manually send this as Laravel for now. We're going to go ahead and preserve the scroll as well. So let's pick up this search thing inside of our forum index controller.
07:16
So why don't we just die dump here on request and search and see what we get. So I'm going to type and there we go. We get Laravel, which obviously we didn't type, but we are manually sending that down. So now every time we type into that search input, we're making a request to the same page,
07:34
sending down the search query in here. Now, the search query comes from this model, so we can just pass query in there and then say query. And now, effectively, every time we type in here, this data gets reloaded with the new request. And of course, the request contains the query that we want to actually search for.
07:55
So now what we can do is somewhere down here, so let's do it just before the pagination. We can actually use the tap function, which will modify what we're doing, but return it back to us. So we're going to modify what we're building up, but still return it back. It just means we can do this conveniently in line here.
08:14
And we can go ahead and pull in the builder, which is the thing that we're tapping into here. And then we can go ahead and use the request in here to bring that into scope. And then we can just make a search request. So we want to only do this when the search actually has data.
08:32
So we can actually use a convenient filled helper function within Laravel to help us do this. So if this is filled, e.g. it's not empty or it's not null or anything like that, then we're going to go ahead and return, continue to chain on the builder.
08:46
So we're going to continue to build this up. But remember, we search like this, discussion, search and then get. We can't really do that because this is going to return to us a collection. What we want to do within this is on this query builder, only select records that come back from this search.
09:05
So what we can do is we can use where in ID and then the IDs, the list of IDs will be basically what we did earlier. So it will be discussion, search, get. So that, remember, gives us back a collection. But what we can do with that is then just pluck the ID out, which will give us an array of IDs.
09:28
So if we pass that array of IDs into here, it's only going to return basically things that matched the query that we type in here. So step one, we make a search, grab the IDs of the results that are relevant to the keyword that's been passed in, and then continue to build this up by just selecting them IDs out inside of here. So let's go ahead and add this in.
09:51
So we're going to say discussion, search. And remember, that's request and search. Then we go ahead and fetch the results back as a collection. But then we pluck out the IDs.
10:05
So there are maybe slightly shorter ways to do this, but we'll leave this as it is for now, because it's a little bit clearer this way. Let's go ahead and see if this actually works. So let's go ahead and search for Laravel. Sure enough, it does.
10:20
Let's search for another. Sure enough, that works. Let's search for view. And you kind of get the idea.
10:26
We now have a list of search results coming back filtered based on what we have searched. You'll also notice that we have this in the query string as well, which really helps. For example, if we have pagination set to one and I searched for, let's get rid of that here. And I searched for A, let's try a different letter, D, and we switch this over.
10:51
Sure enough, we can now navigate between that. Remember, this is because we are always keeping our query string within our pagination. So all of this adds up. So it nicely works.
11:03
Now, one other thing you might have noticed, if we search for something. So let's search for view and we refresh the page. The search results persist, which is great because someone might want to link to a specific search within our forum, but it doesn't exist within our search box here.
11:22
So let's quickly fix that up before we do anything else. So we'll go over to our index just here and the search query basically just needs to be by default the search from our query string. Now, we know that over in our forum index controller, we are always passing our query
11:41
string down so we can just say props query search, or if that's not available, just an empty string. Let's try this out. And OK, so props is not defined.
11:54
Let's fix that up really quickly. That should be good. And there we go. So we've now got that in here.
12:01
And of course, we can change that around if we want to. Now, we have completed our search functionality now. It's working really nicely. But over in our network tab, if we just keep an eye on this and I search for Laravel, you can
12:13
see it's sending a huge amount of requests. In fact, every letter that we type is sending a request, which is not good. So let's just quickly refactor what we have done over here in the next episode so we can tidy this up, making sure we have a slight delay between sending requests to our backend.
62 episodes6 hrs 54 mins

Overview

Ready to build a forum with Inertia and Laravel?

Why a forum? A forum touches a whole load of concepts that you'll use throughout your development career – particularly on the client-side, where we'll be doing most of the heavy lifting.

So, let's build a clean, modern forum with features like markdown support, code highlighting, advanced filtering, user mentions, full-text search, the ability to mark best answers, and more.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Episode discussion

No comments, yet. Be the first!