Mention users with TributeJS | SupeRails #186

25/08/2024
  • How mentions work
  • Scaffold Messages
  • Install TributeJS, display mentions dropdown
  • CSS styling for mentions dropdown
  • Scaffold Users
  • Search users in database
  • Scaffold Mentions
  • Create mentions in database
  • Display mentioned usernames as links in text

In episode #95 we focused on parsing text and converting hashtags and mentions into links. Now let's add an @ mentions dropdown to any text field, so that you can select a user that you want to mention!

Episode source code: https://github.com/corsego/186-mentions-tributejs
Based on this blogpost: https://blog.corsego.com/create-mentions-tribute-js

0:00 How mentions work
1:35 Scaffold Messages
2:23 Install TributeJS, display mentions dropdown
5:24 CSS styling for mentions dropdown
6:10 Scaffold Users
7:29 Search users in database
16:00 Scaffold Mentions
16:42 Create mentions in database
21:08 Display mentioned usernames as links in text

Transcript
Hello friends. So previously I recorded episode number 95, where we had the text field and we passed it to find mentions and the hashtags. And now we're going to actually create mentions. So here is how it works on super.com. I will type hello, I type at, and you see I have this, uh, search pop up no matches found at start typing ov. And you see I have a few match and, uh, usernames, uh, pop up. I can select the username and keep typing. I can select another username. And when I create a comment, you see I have, uh, the usernames that are turned in to actual links that I can click and direct to the user's profile. So the user has been, uh, mentioned and, uh, we're going to build this kind of mentions in a application. Now. Now, uh, initially I was thinking of, uh, building SST controller to, uh, create mentions out from zero, but then I understood there's no point in recreating the ve so I decided to use tri BGS. That is actually a really nice JavaScript plugin for adding, uh, mentions. You can test it on the official playground here. Um, you see I type at and, uh, I have, uh, results pop up. I type normal text. And then just when I type at I, I see this, uh, results pop up. And here is the GitHub repository for tri BGS. You can also have a look at it here. So let's, um, add, uh, this kind of mentions to, uh, usernames in a new results application. So let's create a new results application here I have just generated one and I will open in my code, uh, editor. Okay. First of all, I will need some kind of text field where I'm going to add mentions. So I will say I will create a new, uh, message rails, generate the scaffold, uh, message and message will have body that is text field, let's say rails db, uh, migrate. Uh, I will say, uh, yeah, I will go to our route. And here I will say route to messages index. So if I run the server with bin Dev, because I would have installed VIN CSS, I have, uh, a list of messages. Okay, let's save our changes scaffold messages. If you make, uh, lots of comments, uh, comments often, then it'll be easier for you to track the change history. Okay, so here I have generated our messages and now I've install, uh, tri BGS to be able to display, uh, this ad mentions in, uh, this field. So I will say, uh, bin input map bin triple js bin slash input map bin tris. It is going to add triple js to input map A, B and add the JavaScript inve slash JavaScript slash trigs. And I will create a new stimulus controller rails generate stimulus, I'll name it, mentions. Let's open our mentions controller. And here I will, uh, connect tribute gs. So I will say import tribute from, uh, tribute js. And how do I initialize tribute? Let's see. I will, uh, go to the docs. And uh, here I have, uh, this example. So I will say, uh, this tribute equals new tribute, and I have a couple of values to choose from in this, uh, example. And I'm going to attach this mentions, uh, controller to our search, uh, to, to field. So I will go to the form field, uh, for the message, and I will say, data controller mentions I will start the server. Okay? I will type text, I will type at, and nothing's happening. Uh, okay, maybe I need to have a look at the console. So nothing in the console. Maybe I need to, uh, say that, uh, I'm attaching tribute to this, uh, element. So I will say, um, what is it? This tribute attach this dot element. And this element is, uh, the one where, uh, the control is initialized. Okay, let's refresh. Hello. And you see we have the user names pop up, but it is not styled. Uh, I can type you see, type in the works. Uh, so we need to add some stylin. Uh, first of all, let's save our changes. So, uh, display tribute, uh, search field. So to add some stylin, we can go to the library. And here we have, uh, this, and we have the example CSS. We can just input this tiny bit of CSS into our application. So I will go and open assets style sheets, application CSS, I will input the CSS. And you say it is all scope to tribute, so it'll not override other CSS in your application. Let's, uh, go back to our app refresh. And you see the STA looks, uh, much better. Again, if you want, you can start it to look more install with your application. Okay, so we can tag users. Looks good. Let's say our changes that we've added, the tribute styles add tribute js CSS. Okay, looks okay, but we don't want to have this predefined list. We want to search from our users. We want to have a list of users in our database and search users from the database. So let's add the, a user model where a user has a username and search from this user model. I will say rails generate scaffold, A user and user will have username. Okay, let's, uh, also add users to our seeds. So, uh, here we'll have a predefined list of usernames. I will say usernames. Do each do username, and I will create a user with each of these usernames. User dot create. By this username, I will run the seeds rails DB seed. Okay? Uh, yeah, I mean to say rails, DB migrate, and then TB seed rails console, user dot all you said the users have been created with our seeds and each user has a unique username. Okay, let's, uh, run, um, uh, yeah, let's save our changes scaffold users. Okay? Now we want to be able to search for users in our mentions controller. So we're going to make a fast to our users controller here. We're going to make a request in the JSON format, find the user by our request PERS and, uh, uh, return, uh, JSON of, uh, users. How are we going to do it? Uh, we're going to also, I think, install the GEM request just rails. That is good for making the, uh, requests from, uh, your stimulus controllers. So I will add this gem to our gem file run bundle. You see, I've added request G rails. Now according to the docs, I need to say bin rails request. GS install. You see run, install added this input rails request yes to our application gs. Okay? Uh, now going back to our mentions controller. Instead of defining the values like this, we're going to do something else. First of all, we will need to make, get request for the request gs. So I will say import, uh, get from and, uh, from rails slash request Gs. And here I will say, so values, uh, equals, we're going to make a, a sync, uh, requests. We'll have, uh, the text that we submit, uh, uh, in the search field, we have the server running. Let's run the server. So we'll have the text that we submit, uh, in the search field, and we have the results. Let's name it CB, whatever. Um, and I will save, uh, constant response equals a weight. We are going to make the get request with rails request. You see it, uh, becomes active. And I will get the slash users slash uh, uh, do json and we're going have a search query. So I will say at query equals, and they're going to have, uh, uh, dollar sign and text. So we're going to search, we're going to input this, uh, text into our search pres when we, uh, search for users do js o let's, uh, say if, uh, response do, okay, then we'll have, uh, constant users equals, uh, evade the response. Do JS o and let's, uh, log our users. Yeah, I'm forgetting the JavaScript syntax. So if response, okay, and then console log users. Okay, let's, uh, see if something happens. I will refresh, I will say at Y. And you see, I always get a list of all the users. Okay, that's already not bad. I have a list of all the users. So let's try displaying all the users from our database. Now they're not displayed because we just have an array and we don't want just an array. We want to, uh, just the usernames. Mm-Hmm. And we will have keys and values as we have, uh, in, uh, in the GBGS example. So in our case, both, uh, keys and values are going to be the username. So, uh, let's go back and here will have, uh, uh, c, b, so kind of the results users map. And, uh, in map, I will have, uh, braces. Key equals user, user, user. Yeah, we need to have, uh, users map, uh, braces. Let me try one. Scan users map. He will have user, and the user is going to have, uh, uh, key user username and value user username. I need another close. Okay? Uh, this should be much better. So let's try the search for users. And you see, we always get a list of all the users that they have an database, d, HH, okay, at ov, okay? But now we always have a list of all the users in our database. And if we don't want the list of all the users, we want to have by default only the list of users that match the search query. So we're going to go to our users controller and, um, do some manipulations here. We're going to display not all the users, but only the users that measure the search theory. So, uh, let's try making, uh, putting it a binding B, I just now run the rail survey instead of bin dev to hit the binding. And I will type something. Let's, let's type something. You see, I hit the binding. So it makes the request to users, the js O, and let's say pres in the PREMs, we have the query equals s perri. And now we're going to search the users. So I will say, um, respond bond to do format in format HT MLI will return all the users and, uh, in format that, uh, JSOI will perform the search. So let's say users equals if ifs present, then we'll have user dot, uh, what is it like, uh, there. And we'll have username, uh, I like so matches. Um, and here we'll have, uh, dollar signs inside dollar signs rams, uh, query. Uh, yeah, I forgot the hashtag sign here. Okay. Uh, and, uh, yeah, I forgot to close it. Okay, so we're going to search for users. Uh, and if, uh, the is not present, we will have user none. So an empty active record collection of users. Um, okay, so we have, uh, the search. Let's see if the search would work. I will try to search and I have the users that measure this, uh, uh, query that have the letter S in their, uh, username. Let's search for, uh, SHM. And there is just one user that has SHM in the his username. So, looks cool. Continue. I will remove the binding and let's refresh the page. So let's search again. So hello at, okay, failed because internal server error. Okay, I have a syntax error somewhere. Let's see. Uh, maybe it is because I need to say, uh, render Jason o at users. Let's see. It might be at, we, okay, still we have, uh, an internal server error, unexpected input line eight two. Okay, we might have made a typo somewhere here. Let's see. Yeah, I think I just forgot an, and here. I don't know why my code edit didn't give me this error. Okay, let's try once scan. Okay, and search works. So at a, uh, or C, okay, search, uh, seems to be working well. So now the search our database for users, that looks good. So, um, find users from database. Looks good. Okay, now let's, uh, actually create mentioned records. So when a user has been mentioned, we want to create a, a mentioned, uh, where we have the user and the, uh, message. And this value user would be able to see a list of, uh, all the messages that he was mentioned. Uh, to do this, we are going to create a new model that is going to be called mention. So let's say rails generate scaffold, mention user references, and uh, message references, rails. They be migrate bin dev, let's say scaffold mentions. Okay? So how we are going to create the mentions. Now, whenever a message was created, they're going to pass the message for the users that were mentioned, and we are going to, uh, create the records for mentions. So to do this, I will go to our, uh, message. rb, I will say has many mentions in mention, we already have belongs to user and belongs to the message. And I will say, uh, after grade commit, um, uh, generate mentions. Now we'll have private and private, I will say dev generate mentions. And we're going to pass the message body for mentions. So for text, that starts with the at, uh, symbol. Uh, let's say, uh, mentioned usernames equals uh, content scan. And we're going to scan, scan, uh, starting with the, uh, at, and we'll have, uh, uh, votes, uh, like Let's try scanning the some kind of mention or message. Let's go to our console. Let's say message equals message, lost message. Okay, we have the body. Let's try to scan. Now it's going to be not content, but it's going to be body. So message, body scan, we have this, uh, area of arrays. We're gonna say do flatten to just have an array of Latin. And we have these mentioned usernames. Looks good. And for these mentioned usernames, we're going to find the, uh, users. So here we have mentioned usernames. We don't have body, we have, uh, yeah, we have message body, okay? And we'll say, uh, users equals user dot their username matches, uh, mentioned usernames, okay? We found the users, users dot count. We found two users, okay? And we're going to create, uh, uh, a mentioned for each of the users. So I'll say users each do user. Now we'll have kind of self, so message mentions, create, and they're going to find user will be this, uh, user. Now an end statement, and this should be good, let's, um, go and try creating a new message. Okay? Uh, so let's destroy this one. Let's destroy this message. Let's go to mentions you. We don't have any mentions. Now I will create a new message, uh, no, not a new mention, a new message. So hello vice OV and Marco. Great message. I go to mentions and you see both, uh, users have, uh, mentions. So I generated two mentions. Looks good. Now let's try deleting the message. Okay? We get an error. We need to say dependent destroy. Now, once again, I go to delete, the message was deleted and the dimensions for deleted loose call. Let's go and create another message. Uh, hello at Adrian and, uh, Mets. Okay. I created this message and I have this two usernames here, but they are not clickable, and we want to be able to click on the username and go to the user page. So to this, we're going to, uh, add another scam. So I'm going to scan, uh, and display this, uh, as a link. I'll go to the message helper, or before I do it, I'm going to save out changes. So generate mentions. Okay, yeah. Now I'm going to highlight the, the, uh, mentioned usernames as links to open the user's page. So I will say dev, uh, with mentions text. And instead of just having body scan, I'm going to, uh, replace the usernames with a link to the username. So I will say text gs o, uh, this. And, uh, for each of them I will say do mention, and I'm going to have, uh, uh, a link. So link to, uh, mention, and it's going to be user path at mention. And going to the partial message, I will have with mentions message body. You see I have the HTML that was generated. Uh, looks, uh, okay, I'm going to say simple format. And the HTML has been turned into normal links. Looks good. Let's try clicking on one of them. You see we get an error and we have this at agent dev, so we don't want to have the at in our links. Let's, uh, open the inspector here. We have this at, we want to have no at in the path. So I will say username equals mention, uh, one. So everything after the AT and however will have the link to username. Okay? Uh, so we have the username, we don't have the at, but we can't find the user by username. We can only find the user by id. So going to user's controller, instead of searching just by username, I will search by, uh, ID or username, find by ID or user. The username matches this id. So refreshing. And if you can find the user by the, uh, username, or we can find the user by an id. So looks, uh, good. And, uh, that's basically it. Let's also add a few navigation links to our application, uh, application, application, html, er BI will add a few navigation links, link, uh, to messages, link to users, and link to mentions. Okay, here we have a few links. So messages, users, and mentions. Let's, uh, again, for a final demo, delete all the messages. We have a list of, uh, users in our application. Each user has a username. We have, uh, no mentions yet. We have, uh, an empty list of messages. Let's try, type in a message. I would say hello at ov, uh, from, at the, uh, Mets and the Adrian. Great message. Uh, these are actually links. Let's, uh, yeah, highlight these links. Let's go to message Helper. Let's say glass text Blue 500. Okay? There's actual links I can open the users and I have also generated mentions in the database. So in theory 10, a user goes to his profile, he would be able to see all the mentions for himself, and that's basically it. So I really like this, uh, G Js plugin for Creon mentions. Thanks Fortune, and see you in the next one.
4
Join the conversation
Sign in to access PRO lessons, access private repos, leave comments, create watch lists.
We collect your email address, name and username to create your account. We do not share your email address with anyone else.