Auto-focus comment textarea0:00
Okay, so let's go ahead and add some nice UX additions to our comments here. So the first thing I want to do is focus this textarea whenever we open this dialog. So we did the same thing for these features here. And this is focused. So same thing, we need to add a ref on this textarea and then focus it. So let's look for the textarea in our component here. So textarea. Let's add a ref on it. So let's say x-ref equals, let's call it comment, okay. And as a reminder, this is an Alpine component as well as a Livewire component, as you see.
So let's say xref equals, let's call it comment, okay. And as a reminder, this is an Alpine component as well as a Livewire component, as you see here. And now in our click handler, we can add the code to focus it. So we have to wrap it in a nextTick because it has to wait for the transition to finish. So say nextTick. And then we can do refs.comments, is what I named it, or comment. And we can just focus it. And that should do it. So actually, I just want to focus it if it is open.
Scroll to new comment1:33
Okay. So next thing I want to do is scroll to the Comment after it's added. So right now, it doesn't scroll to the Comment. We get this notification, but we have to scroll manually to the end of the comments list. So if you've ever posted a Comment on the Laracasts form or on a video, you'll see that it does scroll. And this is where I got the idea from. So let's go ahead and try to do that. So you would think that you can do it in here, where we're listening for this commentWas
So let's go ahead and try to do that. So you would think that you can do it in here, where we're listening for this commentWasAdded event. But unfortunately, the DOM element is not inserted into the DOM at this point. So let me show you what I mean. So if we do, let's say lastElement, or lastComment, I'll name it. And let's just do document.querySelector. And let me take a look at DevTools for a second. And you'll see that each one of these has a class of comment-container, if I'm not mistaken. Yeah, so each one of these is a comment and has this comment-container.
And you'll see that each one of these has a class of comment-container, if I'm not mistaken. Yeah, so each one of these is a comment and has this comment-container. And we're interested in the last one here. So we can do .comment-container, and we can use the :last-child selector to grab the last one. But like I said, at this point, the new element has not been inserted into the DOM yet. So let me show you that. We'll just console.log the last comment. And you'll see that it's not the last one. So let's try this again.
And you'll see that it's not the last one. So let's try this again. Let's add a new Comment. Let me just do that. New Comment. Actually, let me open this. And let's go ahead and post it. So if you see, there's the new element. But you'll see, it's not the last one, it's the second last one. So that's not going to work for us.
But you'll see, it's not the last one, it's the second last one. So that's not going to work for us. And as a quick reminder of how to scroll to an element, it's pretty straightforward. So let me just grab this one, which is the one we want to scroll to. So it's this one. Go into the console. Let me scroll up here. Let's do $0, which is the element we have selected. And we can just scroll into view. And then we can do behavior: 'smooth'.
Use Livewire message hook4:44
So let me just comment it out for now. And we're going to put it within the X in it as well. Okay. And let's just console.log the message here. So say console.log message. Okay. And let's see what we get. So let's refresh. So all of our Livewire components are going to make use of this hook. So anything we do that's Livewire required because we have a whole bunch of Livewire
So all of our Livewire components are going to make use of this hook. So anything we do that's Livewire required because we have a whole bunch of Livewire components here is going to trigger that hook. So for example, if I unvoted, you'll see a console log here. So even if we type into this, you'll see that it triggers that hook because there's a wire:model on this. Okay. And when I post a comment, it will trigger that as well. So what we want to do is isolate it to just what we're interested in. So I'm only interested in adding a comment.
So this is the one I'm interested in, or at least one of these ones. So let's take a look at that again. So payload, sorry, not payload, updateQueue, the first one, payload, and we get this event. So Comment was added. So that's what I'm going to use to isolate this event. So let's try that. So let's try doing a conditional. So if message, and it was the updateQueue, updateQueue. And it was the first one, I believe. Yep.
And it was the first one, I believe. Yep. So let's say zero. And it was the payload.event. So payload.event. So if that equals, what was it called? Comment was added. Let's see if it isolates it. So the other components are no longer listening. So let's paste this in there.
So the other components are no longer listening. So let's paste this in there. Okay. Uncomment. Actually, let's grab this and see if the last element is correct at this point. And just console.log that last comment. Okay. So let's see if this works. So now the other components should not be listening, because we've isolated it to just listen for when there's an event called commentWasAdded.
So now the other components should not be listening, because we've isolated it to just listen for when there's an event called commentWasAdded. So if you take a look, if I do any other Livewire things, it should not respond or not console log anything here. If I type in here, nothing happens, but it should respond when I hit postComment. So let's try that. Oops. postComment. Okay. So we actually get two.
So again, let me refresh. Let's try again. So reply trying again, let's post a Comment, and we do get two. So let's see if there's any differences in here and try to figure out why two are firing. So let's take a look at the fingerprint. So let's take a look at the component, and there's a fingerprint in here, and you'll see that the name of this one is IdeaShow. So that's this component up here, and the other one is let me open the other one here. So component fingerprint, this one's called IdeaComments. So we're only interested in this one here.
So component fingerprint, this one's called IdeaComments. So we're only interested in this one here. So it's firing twice because both of these components are responding to that ideaWasAdded event. So let me just prove that to you. The comments should be responding to the event, so we can add it right here. Comment was added, and we just refresh the Idea, so it adds it to the DOM. And we're doing it in IdeaShow as well. So we can update the commentCount right here. Hope that makes sense.
Filter to IdeaComments component9:28
So we can update the comment count right here. Hope that makes sense. But now we can isolate it by just adding another condition. So back here, let's just add another condition here to check if it's that specific component that we want. So say message.component, what was it? MessageComponent, fingerprint.name, fingerprint.name. And we're interested in the IdeaCommentsComponent. So this one right here, this one here, okay. And now it should only fire once.
So if I scroll down, it does work. So all we have to do now is scroll to it. And I already showed you how to do that. So let's go ahead and do that again. Last comment scrollIntoView. I wish there was a Alpine plugin that does some syntax highlighting here because it's kind of hard to write code when there's no syntax highlighting anyways intoView. And then we have behavior. Behavior is smooth. Okay.
Highlight new comment briefly11:18
Cool. So I also want to add a color here for maybe five seconds to highlight that this is the comment that was added. So let's do that. First, let me grab a color from Tailwind. I just want to grab a very light green. So let's grab green-50 and we'll add that to our Tailwind config. So Tailwind config, green-50. Let's add it here. Just say green-50.
Let's add it here. Just say green 50. Okay. And that should work after I do npm run dev. Okay. So now we just have to add the class to our element here, which can be easily done using JavaScript. So back to our code. We don't need this. Don't need this.
We don't need this. Don't need this. So to add a class, we can just do lastComment.classList.add('bg-green-50'); Okay. And then let's remove it after a set amount of time. So let's do setTimeout. And then let's just do lastComment.classList.remove('bg-green-50'); Okay. And the second parameter should be how long. So say five seconds.
It's very faint. I should have made it another color, but it does disappear. So to make it transition, we can just make use of tailwind's transition classes. So let's go to our code. Let's go to that Idea Comment. And we do have transitions on the buttons already. So let's just grab that. So grab this transition duration and the easing curve. And we're going to add it to the Comment container. So this one here.
And we're going to add it to the Comment container. So this one here. So let's just add it to here and I'm going to increase the duration. So it's a smooth transition. Okay. Let me just make it a darker green for now so you can see it. So instead of bg-green-50, I have one named bg-green. So let's do that. And then we'll move it back to bg-green-50 after we see it working. So hard refresh, transition, scrolls, there's the green should disappear after five seconds.
Commit the UX changes14:22
So yeah, everything is working nicely. So as always, let's go ahead and make a commit here. This is episode 50, git add, git commit, episode 50, let's say comments, frontend, UX.
