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
46. Toggling the best discussion answer

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
OK, so now the goal for this episode is to be able to click on any of the posts within a discussion that we've started to mark that as the best solution.
00:08
This will just work for any post in here. And as we saw from the instruction, it's going to add a darker border around it with a little solution tag up here. So we're going to start out with the route and the controller for this.
00:22
So let's jump straight over to our route. Let's think about how we might define this out. Now, we're trying to keep this as restful as possible, but in some cases like this, it makes it a little bit difficult.
00:34
So we're going to go ahead and make a patch request, not to discussion, which we usually would, because technically what we're doing is modifying the solution post ID as part of this. We're going to add on solution as well,
00:45
because it's a very specific update to this and we want to be able to toggle this with one controller. So let's go ahead and say discussions, solution and patch. And we'll use that name, obviously, to reference that in our UI.
00:58
So the controller for this, let's go ahead and just create this out. Just going to go ahead and comment this out real quick. And let's go ahead and make out a controller called discussion solution. Patch.
01:12
Controller, just it's super clear, so let's go ahead and add this in here, discussion, solution, patch controller, and again, we'll head over to this and let's create out an invoke method in here. And once again, we'll start off with a form request.
01:26
So let's make out a request in here. Again, pretty long names, but they're very clear. Discussion, solution, patch, request. Let's go ahead and add this into here.
01:39
Discussion, solution, patch request. And of course, we're going to need our discussion in there as well. OK, so over here we already have the authorization in our policy. So let's say auth, user, can, solve, and this discussion.
02:00
And we're good. OK, so how are we going to toggle this? Well, we're only passing the discussion in here. So we're going to need to accept in some
02:09
sort of post ID so we know which one to actually fill in here. So like a normal patch request, you would send this over passing in the columns that you want to update. It doesn't have to be the entire resource,
02:21
just any individual column that you want to update. So let's imagine that we're passing this through. We haven't done this on the client side yet. But with the discussion, we would basically just want to go ahead
02:32
and associate something with the solution relationship that we set up. And that would be a post model. So what we're going to do is associate, but we're going to fetch an entire post model here.
02:44
So we're just going to say find and we're going to say request post ID. Now, bear in mind at the moment, this post ID could be any post within this system. So technically what we could do or someone could do is send a request through
03:00
and set the solution to a post that exists in an entirely different topic. So we're going to just add a note here, make sure post ID is within this topic. So we're just going to be really careful of that. And then once we have associated this, we're going to save the discussion out.
03:18
Now, the benefit of doing it this way is if we pass a null value for post ID post find is going to just return an empty response, it's going to return null to us anyway. So when we associate something that's empty, it's just going to get rid of it.
03:33
So we can actually use this entire controller as a kind of toggle rather than having to build out another controller to make this work. So finally, we're going to go ahead and return back and let's just start to hook this up on the front end to see if we can get this working.
03:49
So we're going to, of course, do this over in post up view. We have our mark best solution button here. So let's go ahead and fill this in now just to give you an example of this. Sometimes you might want to or all of the time
04:03
do all of your inertia calls in line within your markup. You don't have to extract these out to methods. So, for example, what we could do is say V on click and we could just directly make a request, a patch request with a route inside of here.
04:20
Sometimes this helps when you have pretty short requests to make and you don't have lots of things to do in here. You don't have a non success callback where you need to run a load of other commands, so sometimes you can just put it in here.
04:31
And I'm going to do that now just so it's an example and a reference for you. So the route that we're posting through to is discussions, solution and patch. And of course, we're going to pass through the post discussion to this. And let's go and pass through the data that we need.
04:49
And that's going to be the post ID. So the post ID that we're going to pass through is just going to be the post ID that we are currently iterating through. And we can add some options in here.
05:01
So let's go ahead and preserve the scroll on this because that's pretty much what we want to do. And that's it. So in line, this isn't too bad. We don't really need to extract it out
05:11
to a method, and I think this is absolutely fine. So let's go ahead and just double check that this is working. So we've got another discussion with another discussion body. So that is this one just here.
05:22
So basically, we want to see if this solution post ID gets actually set. So let's hit Mark best solution. Let's come over. And there we go. It's in there is the correct post.
05:33
And we're pretty much done. Now, if I click this again and we come over, notice nothing happens. But I said that the controller works as a toggle. Well, if you think about it, we're just
05:44
passing through the post ID every single time here, which is not great. Now, before we do this so we can set this to potentially null, we need to work out how we're going to work out whether this entire post is actually a solution. And that starts over on the discussion show
06:00
page when we're iterating through all of our posts. So what we're going to do is for each of these, we're going to pass through a prop that is is solution rather than doing all this checking within each individual post. We're just going to have a prop in here,
06:15
which, of course, is going to be true or false. So how do we work out whether this particular post that we are iterating through is the solution? Well, from the discussion, we can just grab the solution ID.
06:26
Remember, a null safe is required here because we might not have a solution, in which case accessing ID on null is not going to work. And we're just going to check this and check that it equals the post that we're currently iterating through.
06:39
So we're going to accept this prop into our post component. So let's go to where our props are defined just here. And let's say is solution. And that's going to be a boolean.
06:51
And then we can now use this to show whether it's a solution, we can border it with a darker color, or we in our case, we can send down null instead of post ID. Now, just before we do that,
07:05
let's just dump out is solution somewhere just so we can see this. So you can see we've got true here. If I go ahead and get rid of this, of course, it's going to be false. And this is going to happen for every single post within a discussion.
07:19
So if I mark this as the best solution, it is now the best solution. But now we can add in a little ternary to make sure that this is changed to null. So we're going to say is solution. If it is the solution, we're going to pass down null.
07:36
Otherwise, we're going to pass the post ID. So if it's already been marked, unset it, otherwise use the post ID. So now I can click on this to toggle it back and forward. Lastly, just to tidy this up,
07:49
we, of course, want to change this text based on whether it is the solution or not. So let's say is solution. We're going to say unmark. Otherwise, we're going to say mark.
08:00
And of course, you can choose what that says. So unmark and mark. And that's working nicely. OK, so obviously, let's get rid of that dump in here.
08:10
The next thing that we're going to do is highlight the border here and add a little label if this is the solution. Now to demo this, I'm just going to add a couple more replies just so we can get the hang of what this is going to look like.
08:25
Another one, and we can mark any of these as the best solution, and it should just flip between them as we change them around. So we're going to add this styling now. So on the post itself, this overall post, we are going to go ahead and add in a
08:40
border to this if it's the solution. So let's add in a class binding in here. And let's always have a border on here of two. And we will set the border to transparent here, and then here we'll set the border
08:57
to say grey 800 if this is the solution. And we might just want to important that it may not work otherwise. In fact, a better way to do this is to say border transparent if it's not the solution.
09:14
So instead of relying on marking, this is important. OK, so we've got an overall border which is invisible if it's not the solution. And we've got a border that's dark if it is the solution. So let's go over and try this out.
09:29
OK, so it's already working because we've already got this solution in here. But now I can just go ahead and click to mark this. So we've got this annoying issue here where when we set up scrolling to the post earlier, we used on update and that was over on the show page.
09:47
So on updated, let's go ahead and look for that. And I'm not sure we need this at the moment. Let's go ahead and just comment this out, because otherwise it's going to be just jumping around every time we mark something.
10:03
OK, so this works now and we can pretty much just toggle between each one now, because, of course, as we set one, another one automatically gets untoggled. So that is looking good.
10:13
And I just want to build out a label here just so this is really clear exactly what this is. So at the very bottom of our post marker, let's go ahead and add a div in here and say best answer or solution,
10:29
whatever you want to say. And I said some styles to this to make this look nice. So we're going to set this to absolute. It's going to be on the right hand side so we can use right zero.
10:39
And it's going to be in the very top corner. And let's go ahead and set the background color on here to a dark gray to match the border that we set at the top. And we'll set the text to something like a gray one hundred.
10:53
Let's just check this out really quickly. And it's floating up here, which means we just need to set a relative on this outer container. And there we go. Great.
11:03
So that's looking a little bit better. Let's go back to our markup here. OK, so what do we need to do here? A little bit of padding. So let's set some padding on the X axis to three and padding on the Y to one.
11:15
We'll go ahead and set the text to extra small. And let's go and uppercase this. Now, when we uppercase things, it tends to look a little bit squashed. So with that, we can go ahead and set
11:27
the tracking to widest with Tailwind and we'll go ahead and set the font to Semibold. OK, so that's looking a little bit better. Maybe we don't need this tracking. Let's just say tracking wide.
11:40
Yeah, I think that looks OK. OK, so last thing to do is we're going to set a little border radius on the bottom left hand corner. So let's set a border or rounded rather
11:52
on the bottom left. And that looks a lot better. And why don't we just go ahead and add a small shadow to that while we're at it? OK, perfect.
12:01
Now, obviously, we only want to show this if it is the best answer or if it is the solution. So let's go ahead and just add a VIF. And there we go. So that nicely toggles between each of these now.
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!