Editing Comments Menu0:00
Okay, let's work on editing comments. So it's going to be similar to editing ideas. So let's get started. So first thing I'm going to do is work on this menu here, and that's within our IdeaComment component. So I'm going to wrap this in an auth directive because it should only be available for anyone that's logged in, and each action will have auth as well. So let's close this and I am logged in, so it should still show. Okay, and let's grab the menu item from here and put
So let's close this and I am logged in, so it should still show. Okay, and let's grab the menu item from here and put it in our menu here for the comment. So I believe that's an Idea show, and we have editIdea here. So let's grab this. Actually, let's grab the auth as well, and we'll work on that later on. So back to idea comment. Let's put it right here as the first one. Let's re-indent and let's get rid of the auth for now.
Creating EditComment Component0:51
Let's put it right here as the first one. Let's re-indent and let's get rid of the auth for now. Okay, and it's called editComment. Okay, so that should render in our menu. There it is. So now let's go ahead and make our Livewire component to handle this functionality like we've been doing for all the other actions in our Idea here. So let's do that. php artisan livewire make editComment.
So let's do that. php artisan livewire make edit Comment. Okay, so as a reminder of how we communicated between models. So, for example, for editing an Idea, we click on this, and then another component opens here, and these are Alpine components. So let's go through that. So back to our Idea show. We have editIdea. We use the click handler on Alpine, and we close the menu.
We have editIdea. We use the click handler on Alpine, and we close the menu because this is the menu on Idea show. So this menu, and then we dispatch an event using Alpine called customShowEditModal right here. And then we're listening for this event on that model. So let's go to editIdea right here. So this is listening for that event. And when it receives that event, it opens the editIdea dialog.
And when it receives that event, it opens the editIdea dialog. And we have this thing that focuses the first textarea or the first input. So like I said, this is just communication between two Alpine components. And if you don't remember, if you go into our models container, we have all of our dialogues and models for all of the actions on our Idea here. So if you take a look at the updating of the Idea or editing
actions on our ideas here. So if you take a look at the updating of the Idea or editing Idea, you'll see that we're passing through an Idea here. So we can do something like that, but there has to be a change here. So again, we'll take a look at the off later on. This is going to be editComment, and we're not editing an Idea, so we don't need to pass an Idea in, and we actually don't need to pass anything in at all. So for updating an Idea, we already know the thing that we
actually don't need to pass anything in at all. So for updating an Idea, we already know the thing that we want to update. In this case, the idea. That's because we're on the page already. So we're on this idea, and we know we want to update it or delete it or do any other action on it in this case. But for comments, we have a whole bunch of comments for this specific idea, so we can't pass it in when we render it here. So what we want to do is.
specific idea, so we can't pass it in when we render it here. So what we want to do is. So if I just undo that, the thing we want to pass in is a Comment, but that changes depending on whatever the User clicks here. So we sort of want to make a constructor, but that's going to change based on whatever Comment the User clicks. So Let's go ahead and do that. So again, let me remove this. We are going to set that based on whatever the User clicks,
Setting Comment via Event3:51
So again, let me remove this. We are going to set that based on whatever the user clicks, and Let's go to our editComment. And instead of a mount method, Let's make a setter which sets the comment based on whatever the user clicked in here. So if they click this, then it will set the comment to this comment and so on and so forth for other comments here. So Let's make a method called setEditComment, and it will take in a commentId, and this will set the comment. We also need a public property for it.
take in a comment ID, and this will set the comment. We also need a public property for it. So Let's make that as well. So say public. Let's type in it to a comment, say comment. Say comment. Okay, and it's import comment. And here we can set that. So this comment is comment. Let's use findOrFail and comment ID.
So this Comment is comment. Let's use findOrFail and commentId. Okay, and let's just dd the commentId or if it finds one. So this commentId. Okay, so we want to call this method anytime the User clicks edit Comment in one of these comments over here. Okay, so let's work on that back to our code. Let's go to IdeaComment. Actually, let's start from the menu here.
Let's go to IdeaComment. Actually, Let's start from the menu here. So that was an IdeaComment. So Let's open that up. And like I said earlier, we were just using Alpine before to communicate between the components. But now we want to hit a Livewire endpoint so we can do that with events. So instead of an Alpine event, Let's emit a Livewire event. So we can say Livewire.emit, and Let's call it setEditComment.
So instead of an Alpine event, Let's emit a Livewire event. So we can say Livewire.emit, and Let's call it setEditComment. And we have to pass in the commentId. So we do have access to the comment within this component. For example, up here we have the actual body being rendered on the page here. So Let's just pass it in directly. So Let's say commentId. So we are exposing the commentId on the front end, which can be a security issue depending on what type of app you're.
So we are exposing the comment ID on the front end, which can be a security issue depending on what type of app you're building. But in this case, I think it's okay. So if you don't follow what I'm trying to say, the user can just view the source and they can see that comment ID here. So Let's look for that setEditComment. I don't think I refreshed. So Let's try that again. setEditComment.
So Let's try that again. setEditComment. And you can see this specific comment is 491. So if it's auto incrementing, they can have an idea of how many comments are in the system. And like I said, for this type of app, it's not a big deal. However, for apps like eCommerce apps and orders, if you expose the order ID, the user can have a sense of how many orders are in the system. So in those cases, you can make use of a package like this.
orders are in the system. So in those cases, you can make use of a package like this. I've used this in the past, and it works great. This hides the model ID, and you can just make use of this ID instead of the real one. But like I said, for our app, it's fine. So back to our app, we're passing in the commentId, and we're emitting this event. So we want to listen for this event. So let me grab this in our EditComment Livewire component.
So we want to listen for this event. So let me grab this in our EditComment Livewire component. So let's do protected $listeners equals $this. Okay. And let's make a method for that. So let's say setEditComment. And the param is the commentId. Actually, I already have that. Sorry. What am I doing here?
Sorry. What am I doing here? So they're named the same. So whenever Livewire listens for this event, it will call this method. So let's see if this works. I think I have everything hooked up, and it's just dying and dumping the comment if it found it here, depending on what the user clicked. So let's try this out.
what the user clicked. So let's try this out. Let's refresh, and let's try this one. Okay. So it does work. So this is comment 492, 493, and it looks like it works. Cool. Okay. So now we should have a comment. So let's work on the Blade view.
Building Edit Modal UI8:26
So now we should have a Comment. So let's work on the Blade view. So let's go to editComment, and this should be similar to Idea or editIdea. So let's grab that. So I'm going to grab everything here, put it in editComment, and let's make a few changes here. So this is for ideas. So let's change it to the actual comment first. We don't need this.
So let's change it to the actual Comment first. We don't need this. This is editComment. Okay. Let's change this to updateComment. So the action on the Livewire component, and we don't need a title. So let's get rid of that. Let's get rid of the error here, and we only need the textarea here.
Let's get rid of the error here, and we only need the text area here. The text area here. Don't need to select. Okay. And we just need this text area. So let's call it body. So the comment body, and let's get rid of this required for now to make sure validation works. And this is body.
now to make sure validation works. And this is body. Okay. So we have to make a property on our Livewire component called body. So let's do that. So EditComment. Sorry. EditComment. This one.
Edit comment. This one. Let's make a new property here called body public body. Okay. And whenever we're setting the comment, we want to set that property here. So this body equals the new comment we just set. So this comment body. Okay. So now after we set the comment and the body, we can emit
Okay. So now after we set the comment and the body, we can emit an event from here. So this emit, let's say editComment was set. Okay. And now back to our Blade view up here, instead of responding to the Alpine event, which we're not doing anymore. So we can comment this out. We have to respond to the Livewire event so we can do that within x-init.
We have to respond to the Livewire event so we can do that within X in it. So it's similar to this. I thought it changes to Livewire on, which is the same thing. So let's change that. And now we just want to respond to that new event that we just created. So it's called editCommentWasSet. Let's grab this to respond to that. Oops.
Let's grab this to respond to that. Oops. And whenever that happens, we can do the same thing we did before. But now we're listening for the Livewire component or the Livewire event. So space that in. And this hopefully should work. We don't have this ref yet, so let's just comment that out. So let's just see if the edit Comment model opens whenever.
We don't have this ref yet, so let's just comment that out. So let's just see if the EditComment model opens whenever we click on a Comment here. So let's click this one and it does work. Cool. So this corresponds to this Comment here, and let's see if it works for this one. So remember that text and comment. Okay, so it is correct. One more.
Okay, so it is correct. One more. Okay, let's just make sure to focus this when it opens. So same thing. It's already in there. We just have to add the ref. So let's say editComment, and we'll add a ref for that. So that should be this textarea textarea. And let's say x-ref equals editComment. Okay, make sure it focuses.
And let's say $x equals editComment. Okay, make sure it focuses. Refresh doesn't focus, and it does. Cool. So now we just have to update the comment, and we already have the wire:submit in place. It's called updateComments. So we have to make a method on here called updateComment. So let's do that. updateComment.
Validating and Saving Update12:11
So let's do that. Update Comment. You have to do some off here, which we'll do in a second. Some validation. Actually, let's do that first. So this validate, and we just want rules for. So let's put up here protected $rules. It's the same as adding comments. So say $body required. I mean, four, I believe, is what I had for adding comments.
So say body required. I mean, four, I believe, is what I had for adding comments. Okay. And do I have the error directive in place? Edit comment. I do right here. Okay, so let's try that out. So if we try to edit a comment, but have less than four characters, that should be an error. So let's try that.
Okay. Okay. Now let's work on actually updating the Comment. Pretty straightforward. So we already have the comment, so we can just set the body on that. So this comment body is this body. Okay. Let's save that comment. So this comment save, and it's emit an event similar to
Let's save that comment. So this comment save, and it's emit an event similar to what we've been doing for everything else. So for example, here, let's grab this. Let's say emit commentWasUpdated, and we have to listen for this event in a few places and say commentWasUpdated. Okay. So we have to listen for this event in two places. So one of those places is the notification or the success message.
So one of those places is the notification or the success message. So that's in our notification success right here. Let's add that new one. Comment was updated. So add that, and that should add the message. Okay. And we also need to update the actual comment. So that would be on our IdeaComment component. And let's just grab what we have from ideaComments.
So that would be on our IdeaComment component. And let's just grab what we have from ideaComments. The listeners here. So let's grab this. Let's grab this as well, actually. And it's the same thing, but we just want to make sure that the Idea refreshes when we update the comment. So let's add those listeners. At least comment was updated. So let's grab these two.
At least comment was updated. So let's grab these two. Comment was updated, and we just have to refresh the comment that's being passed through. So this comment refresh. Okay. So let's see if everything works. Let's hard refresh. Let's try updating this comment here. Okay.
Let's try updating this Comment here. Okay. Let's say updated. Let's see if the message comes up and this actually refreshes. Okay. It does. But this model does not close. And to fix that, I believe we have to add that event in here as well. So, yeah, we have to update this one here.
Adding Comment Authorization16:09
Okay. So it's refreshed. The message comes up and the dialogue closes. So, yeah, everything is working. Let's add authorization, and then we'll be done with this feature. So similar to our policies for Ideas. Let's create one for Comments. So let's grab this. It's called CommentPolicy, and the model is Comment.
So let's grab this. It's called CommentPolicy, and the model is Comment. So commentPolicy model equals Comment. Okay. And let's open that up. CommentPolicy, and it should be the update method. And it should be the same or almost the same as the IdeaPolicy. So let's grab that update. So we only need this condition here.
So let's grab that update. So we only need this condition here. Comment policy, paste that in. User id is equal to the comment userId. Okay. So let's add a semicolon here, and we can add authorization. So let's take a look at what we did for editIdea. Pretty much the same thing. Let's grab this. Let's go to editComment, and let's put the auth in here.
Let's grab this. Let's go to editComment, and let's put the auth in here. So if the user is not logged in or the user cannot update the comment, then abort. Let's import this. And now we should not be able to update our comment unless we created it. So let's try this out. So I'm logged in as my admin account, so I didn't create any of these comments.
So let's try that out. Say edit. Can I edit? I can. Cool. So let's hide it from the menu if we can't even edit it. So that's simple enough. So it's an Idea Comment, I believe. So I think I have it in here already. Yeah, I do.
So I think I have it in here already. Yeah, I do. Let's just put this back and say, can update comment instead of the Idea. And now it should not show up in the menu if we can't edit it. Okay, cool. But this one should show up, and it does. Looks good. And I think we can add one more in our models container. So at this point, we don't have a comment, so we can just
And I think that's it. Let's just make sure that this menu does not show up when we're logged out. And it does not. Cool. So as always, let's make a commit here. This is episode 53. git add. git commit. Episode 53.
Get commit. Episode 53. Edit comments.
