تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Feature Overview0:00

In this episode, we're going to be building a tag input with auto-suggestions, complete keyboard navigation and a feature to create a tag on the fly if it doesn't exist already. Here it is. Let me start searching for something. I can see the auto-suggestions dropdown. I'm using my keyboard right now to move between the suggestions. I can also use my arrow and let me pick one and the tag is created. Let me search for something that doesn't exist, like singing. I should be able to create it by just hitting enter and a new tag is created. I also see the toast notification, which is from one of the previous episodes.

I should be able to create it by just hitting enter and a new tag is created. I also see the toast notification, which is from one of the previous episodes. Great. So let's work on this. I won't be starting from scratch. Of course, we have a skeleton ready with a simple input, a public property search in our single file live via component. And this input is bound using via model live debounce to search. So what we want now is once I start typing, that is when the search is updated, we want to look into the database.

Loading Suggestions1:11

So what we want now is once I start typing, that is when the search is updated, we want to look into the database. I already have a database of tags. We want to look into the tag and find all the suggestions. So let's create another public property, array suggestions, and on updated search, we will have to load the suggestions. Okay. So let me paste that method here. So load suggestions, it checks if the length of the string is less than one, then it clears all the suggestions.

So load suggestions, it checks if the length of the string is less than one, then it clears all the suggestions. Otherwise we have this tag model and it checks if the name is like the search. So it matches anywhere, then it gets all the suggestions, limits it to five, selects only the ID and name because that's all we need, gets it and converts it into an array. So now we simply have to show those suggestions right here below the input. So here's the drop down. If there is search and if there are more than zero suggestions, then we just show this in a list. Each of the suggestions will have a wire key, which is very important here and the name

a list. Each of the suggestions will have a wire key, which is very important here and the name of the suggestion. So let's see. Let me start typing. Yeah. You are able to see all of this. Of course the keyboard navigation doesn't work yet, but I'm able to see. And because we have hover BG blue, the mouse hover works. It looks like we are selecting it, but if I click on it, nothing happens yet.

Selecting and Displaying Tags2:45

And because we have hover BG blue, the mouse hover works. It looks like we are selecting it, but if I click on it, nothing happens yet. So here, let me add wire click, add tag so that if I click on it, it should be able to make a tag, right? So we pass in this key. Let me create that method. But even before that, we need selected tags array so that we can add it into the array. Let's add the add tag method here. Since we've passed the ID, it finds the particular ID and it makes sure that it's not already present in the selected tags.

Since we've passed the ID, it finds the particular ID and it makes sure that it's not already present in the selected tags. So if I've already selected an interest of mine, I can't select it again. So just make sure it isn't in that array and it just adds the tags ID and name into the selected tags array. But now if you try doing this again and click on something, it looks like nothing happened, but the search got cleared and the suggestions became empty. Also the selected tags array has this now. So let's display the selected tags just about the input field before the tag input. I'm going to paste this.

So let's display the selected tags just about the input field before the tag input. I'm going to paste this. So if we have some selected tags, each of them are displayed in, uh, that look like a tag, right? Like a label. So now let's try this again. Let me say art. I click on it and we see a pill there, but this button right now, it is, uh, already it has the wire click remove tag. It doesn't work.

it has the wire click remove tag. It doesn't work. Let's add that remove tag method. This is again, very simple. We're just gonna simply remove the tag. Let's test it once. Let me say art, click on it, remove the tag and it's gone. Let me add a few more. Art, Gaming and then yeah, remove any of them and they are gone. This is good.

Art, Gaming and then yeah, remove any of them and they are gone. This is good. Okay. But we have a small problem here. Let's say I have typed art and selected it. If I type art again, I should not be able to see it in the dropdown itself, but since it's appearing, let's make sure it doesn't happen right here. When we are looking for the suggestions, we have to also say where not in, and it should look at the selected tags array and remove it from there. So now let's try it again.

Alpine Dropdown Behavior5:16

look at the selected tags array and remove it from there. So now let's try it again. Let's say I have art and I try typing art again and you see it doesn't appear. All right. Now let's try and add keyboard navigation. To do that, we have to convert the entire input into an Alpine component because keyboard navigation can only be handled using Alpine. Scroll down to the tag input. I will wrap this div in an Alpine component, div x data. I will simply have a state which is open and set it to false right now to begin with.

I will wrap this div in an Alpine component, div x data. I will simply have a state which is open and set it to false right now to begin with. And instead of checking using live wire, if search is empty or suggestions is less than is greater than zero, let's do that here in Alpine and remove this entirely. So I'll remove the if here. So I'm just gonna watch the search wire dot search and if the value dot length is greater than zero, then we show the suggestions, otherwise we don't. But for that to work here, I have to add X show to the dropdown and set it to open. Not just that, we also have to see if there are any suggestions. If currently we're just checking if the search length is greater than zero.

Not just that, we also have to see if there are any suggestions. If currently we're just checking if the search length is greater than zero. So let's also add and if the suggestions length is greater than zero, only then we show the dropdown. So now let me start searching again. As you can see, it works the same as before. Only thing is now we can add something like if we click outside the input, like so, add click outside, open is false. So now let's say you're typing something, you click outside and it's gone. You click back again and we want it to reappear.

So now let's say you're typing something, you click outside and it's gone. You click back again and we want it to reappear. So we will add a focus on the input right here and say at focus open equals true. So now let's type something, click outside, click back inside and we're able to see the suggestions again. And also it would be nice to hit escape and close this. So let's add that also here at keydown.escape, open equals false. So type something again, click escape and it's gone. Now let's try and actually navigate using the down and up arrow into these dropdown. For that, we need to be able to highlight the item when the user uses the down or up

Keyboard Navigation7:49

Now let's try and actually navigate using the down and up arrow into these dropdown. For that, we need to be able to highlight the item when the user uses the down or up arrow key, which means we need an index to keep track of which is the highlighted item and we need a method to move it up or down. So let's add all of those right here. So in Xdata, let's also add a highlighted index and the methods I told you about. Okay, so let this start with minus one. The moment we move to, you know, we move down, if the highlighted index is less than the number of suggestions, highlighted index plus plus, it's minus one because it starts from zero.

number of suggestions, highlighted index plus plus, it's minus one because it starts from zero. And then when you move up, you reduce the highlighted index. So let's bind the input here. We will say keydown.up.preventMoveUp. Now prevent is needed because if I type something and if I press down, it actually moves to the end. If I press up, it moves to the beginning. If I have prevent, then it doesn't do that. So we need to prevent the default action.

If I have prevent, then it doesn't do that. So we need to prevent the default action. So keydown also down.preventMoveDown. So now if you type something, you'll actually not notice anything happening. The highlighted index is getting updated, but based on that index, we should highlight this. Let's go to the drop down to the list here. And instead of having this class, let's bind it with the highlighted index. So if the highlighted index is equal to this loop index, then we change the background so that it looks like highlighted.

So if the highlighted index is equal to this loop index, then we change the background so that it looks like highlighted. Let's see if this works. Let me try typing something and I'll use my down and up arrow keys. It is working. But if I hit enter on a selected item, it should be able to add that key. So right here in on the input, let's also add the key down, enter prevent. And here I'm just going to use the addTag method. So I will say $wire.addTag. So I'm going to add this tag and I'll get the ID from the highlighted index.

So I will say $wire.addTag. So I'm going to add this tag and I'll get the ID from the highlighted index. So suggestions.highlightedIndex.id. And then I have to set open to false because we've selected the item. Now we can close the drop down and reset the highlighted index to minus one. Let's see. So now let me type something, use the keys and hit enter. Yeah. So now our tag input with auto suggestions is completely working including keyboard navigation. So next let's add a feature to be able to create a tag if it doesn't exist.

Creating New Tags10:41

So now our tag input with auto suggestions is completely working including keyboard navigation. So next let's add a feature to be able to create a tag if it doesn't exist. So let's say I want to add an interest as singing. I should be able to see an option here to create it. So in LiveWire, let's first create, let's first make a method called createTag. Let me paste it here. So it first trims the string and if it's empty, it does nothing. It also checks if it already exists. So let's say I type art here and it already exists, but if I don't look at it and if I instead click on create art, it shouldn't create a duplicate.

So let's say I type art here and it already exists, but if I don't look at it and if I instead click on create art, it shouldn't create a duplicate. So it first makes a case insensitive check. So if it exists, it adds the existing tag instead of creating a new one. Otherwise it creates a tag and then it also populates the selected tags with that and clears the search and clears the drop down also. That is the suggestions and it also dispatches the toast. So now onto the UI, let me scroll down to the drop down. So after this drop down, let's add the createTag div. Let me paste that here.

So after this drop down, let's add the createTag div. Let me paste that here. So this div with a createTag text appears only if the search is not empty and if there is no exact match found for the tag. So let's say if I type gaming, look, I'm able to see this because there's no exact match yet. But if I type gaming fully, then it doesn't show me that because we don't need it. However, if I type something lowercase, it still appears. It's up to you. If you want to remove that check, you can, but yes, we have this and now if you click

It's up to you. If you want to remove that check, you can, but yes, we have this and now if you click on it, it will directly call the createTag method. Okay. Let's try this out. Let me search for painting and I'm not able to see this drop down. We do have this. Oh yeah. So right here on top, we said show this only if the suggestions length is greater than zero.

So right here on top, we said show this only if the suggestions length is greater than zero. That works fine for when we don't have the create option, but now we'll have to remove this and let me try typing painting again. And yes, I'm able to see this. The main thing is to see this when there are no suggestions, right? So let me click on it using mouse because keyboard doesn't work yet. And it's able to create a new tag. I also see the toast. This is great.

I also see the toast. This is great. So the final thing we need is to be able to make this work using keyboard. So to our moveDown function, we are hard coding this, we are saying if, you know, the highlighted index is less than the length minus one, then increase it. But we are not sure if there is a create option or not. So if there's an exact match, there is no create option. If there's no exact match, only then it is, we need to first make that check here and then allow it to select the last option also. So here we say a max, which checks if there is, if the search, if there is something in

then allow it to select the last option also. So here we say a max, which checks if there is, if the search, if there is something in the search and also checks, if there is an exact match accordingly, it will update the length. So we can simply check for max and use it. Let's see if we are able to highlight it or wait, we also have to change the class here. Yeah, we need to bind the class. The same thing as we did for each of the elements. If it's this very index, that is, if it's the last one, then we add a background color. So let's just see if the highlight is working.

If it's this very index, that is, if it's the last one, then we add a background color. So let's just see if the highlight is working. Let's say I search for something and I scroll down. Yes, I'm able to move to the last div and it highlights accordingly. So now if I click on it, it works, but the keyboard enter is something we need to work on here for our input. This is the logic we have for key down enter. So it's currently just adding the current tag. We should also be able to create it if that is the one that's highlighted. So replace this line with the check.

We should also be able to create it if that is the one that's highlighted. So replace this line with the check. So if the highlighted index is less than the length, then we add the tag. Otherwise we create the tag. Okay. This should work. And final check, let me add singing if it doesn't exist, but yeah, that's good. Let me add singing and it works. Let me just add A or something. I'll move to the last item and it also works.

Let me just add A or something. I'll move to the last item and it also works. So that's it. We have a tag input that autocompletes with complete keyboard navigation and also creates a tag if it doesn't exist. Hope you enjoyed this one. See you in the next episode.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟