Blueprint by Tiny
Return to Tiny.cloud
Return to Tiny.cloudTry TinyMCE for Free
Search by

How to get started with TinyMCE Mentions

Joe Robinson

November 11th, 2021

Written by

Joe Robinson

Category

How-tos & Tutorials

User mentions are vital for communication in an increasingly remote working world. It’s now a core need for users to be able to tag each other (using mentions) and keep on top of collaborative tasks that need to be done.

TinyMCE has a Mentions plugin designed exactly for this task. 

You can build a working version of the TinyMCE Mentions plugin using as few as 19 lines of JavaScript in an HTML file. That said, the following demonstration uses more lines of code (about 45) because when we designed the guide, we wanted to implement some more user information. However, the goal of this article is for you to be able to take the demo Mentions plugin, and then adjust it, expand on it, and change it to meet your own needs for user mentions.

Where do Mentions come from?

The concept of typing an “@” symbol to talk to another person on a particular web application first became prominent on Twitter. It serves a specific purpose: drawing attention to content. 

Under this general use case are the specific actions you may have seen when studying how user communication works online: a person mentioning multiple people, a person mentioning an organization or a business’ account, and groups of people or organizations communicating with each other on a topic.

Twitter implemented the specific user mentions syntax in 2007, and it has since proliferated across social media platforms. It has also found its way into many web applications with communities that need to work on content, and draw each other's attention to content.

How does the TinyMCE Mentions plugin work?

The Mentions plugin queries a data source (usually your database on a server) when an end user types the “@” symbol. The request to the server is a callback that has two parameters passed into it:

1. The search query object
2. A success callback to execute results

The search query object as a property - search term – that has the characters the user typed after the “@” symbol. The success call contains an array of user information in a specific pattern of keys and values.

The mentions_fetch option controls the callbacks. It’s not a Request construct, although the userRequests function works in a similar way. It does make use of a fetch method, and also the slice method, since the user only needs the part of the returned array that matches their query. Take a look through each line of this example:

mentions_fetch: function (query, success) {
  // Fetch your full user list from the server and cache locally
  if (usersRequest === null) {
  usersRequest = fetch('/users');
  }
  usersRequest.then(function(users) {
  // query.term is the text the user typed after the '@'
  users = users.filter(function (user) {
  return user.name.indexOf(query.term.toLowerCase()) !== -1;
});

users = users.slice(0, 10);

  // Where the user object must contain the properties `id` and `name`
  // but you could additionally include anything else you deem useful.
 success(users);
 });
}

Providing the Mentions plugin with the right array

When typing in the ‘@’ trigger character, the mentions_fetch option calls out to a server, and the response received needs to have specific user properties. It must have an id, and a name key with values. Description and image values can also be introduced, but both are optional.

What’s important is that you have these specific keys and values set up in an array, otherwise the mentions_fetch option will return an error to the browser console:

“mentions_fetch didn't produce a valid list of users.”

So to produce a valid list of users, check the documentation example:

const user = {
  id: id,
  name: name,
  description: "A user description"
  image: “image file reference”
}

Setting up a demo user Mention instance

Weather apps are a commonly used project when learning JavaScript. Some YouTube tutorials attract over 400,000 views, and there are recent weather app tutorials published online. If you’ve ever attempted one of these weather app projects published on YouTube, you may still have a weather service API key you can use.

If you have yet to try a weather app, this demo uses data from the Open Weather API, and you can sign up with Open Weather for a free API key.

It does sound unusual. However, the Mentions plugin can receive information from any source as long as it fits the pattern of information needed in the array. 

Therefore, we decided a novel and unusual approach to the demo would be an app that uses the abilities of the Mentions plugin to mention the weather (it’s a common icebreaker question after all!).

Some demo prerequisites

  1. Sign up for a free API key from Open Weather.
  2. Set up an index.html file in your text editor of choice.
  3. Have access to some method of hosting your index.html file, either through localhost Node.js http server, Python3 simple server, or another method.
  4. Select a location in the world, and note it’s latitude and longitude coordinates. It doesn’t have to be a potential vacation destination. Places with different weather patterns are a better fit for this project.

1. Getting started: setting up a TinyMCE API key

The first step is heading to Tiny.cloud, and signing up for a free API key. You’ll have access to the Mentions plugin – one of the TinyMCE premium plugins – for 14 days with a new account.

2. Making the index.html file, and including TinyMCE

Open up a new index.html file, save it, and include a source link to the TinyMCE CDN using your API key in place of “api-key” in the following example:    

<script
  src="https://cdn.tiny.cloud/1/api-key/tinymce/5/tinymce.min.js"
  referrerpolicy="origin"
></script>;

3. Calling the Open Weather API

This demo makes two calls in parallel. You could add to this and create more weather locations to mention, but two seemed like a sensible number for this how-to guide. Create a new script tag in your index.html file, and Add your Open Weather API key in place of “api-key”

const apiA = https://api.openweathermap.org/data/2.5/onecall?lat=23.6980&lon=133.8807&appid=api-key';
const apiL = https://api.openweathermap.org/data/2.5/onecall?lat=51.5072&lon=0.1276&appid=api-key';

The locations we selected were Alice Springs, and London (contrasting the capital of England to the Australian desert!).

4. Setting up the fetchUsers function

The mentions_fetch option needs a variable called fetchUsers to work correctly, so set that up first after the Open Weather API:

const fetchUsers = () => {};

Then setup up user detail information inside fetchUsers. Remember, the “name” and “id” variables are required.

  let firstUser = {
    const name =
    const id =
    const user = {}
   return user;
   })

  let firstUser = {
    const name =
    const id =
    const user = {}
  return user;
  })
 })
}

5. Sending the API information into an object, and then an array for two “users” based on two locations.

An important step is catching the information from Open Weather, changing it into a format JavaScript can make use of, and then setting up variables that the Mentions plugin can use. Do this by using the fetch function on the apiA and apiL variables, combined with then statements, and the response.json function.

let firstUser = fetch(apiA).then(response => response.json()).then((data) => {}

The weather data is currently in the firstUser variable, but it needs some exact information provided by Open Weather to send on to TinyMCE.

Looking at the structure of the incoming weather data (you can do this yourself by running a for example), there’s a description that can stand in place of the name, and a sunrise time that works for a substitute user id.

You can then set up a user variable. Because “name” and “id” are already configured, you don’t need to set up new variables inside the user array. You can retype the constants “name” and “id”.

let firstUser = fetch(apiA)
  .then((response) => response.json())
  .then((data) => {
    const name = data.current.weather[0].description;
    const id = String(data.current.sunrise);
    const user = {
      id,
      name,
    };
    return user;
  });

let secondUser = fetch(apiL)
  .then((response) => response.json())
  .then((data) => {
    const name = data.current.weather[0].description;
    const id = String(data.current.sunrise);
    const user = {
      id,
      name,
    };
    return user;
  });

6. Binding the formatted information to a local variable

With information from Open Weather transformed into user information, the next step is binding the user information to a local variable. Complete this with a Promise.all([]); method:

const fetchUsers = () => {
  let firstUser = fetch(apiA).then(response => response.json()).then((data) => {
  ...
  }
  return user;
  })

  let secondUser = fetch(apiL).then(response => response.json()).then((data) => {
  ...
  }
  return user;
  })

return Promise.all([firstUser,secondUser]); //binding user information to a local variable

7. Initialize TinyMCE, and include mentions_fetch

Add in the tinymce.init script, specifying the textarea tag (this example uses the class “.mytextarea”). Include the Mentions plugin, and specify the minimum characters as 0, so that the Mentions plugin will fetch user information as soon as the “@” character appears.

Finally, set up the mentions_fetch option. This demo includes a console.log so that you can open the developer tools, and make sure the fetchUsers function worked.

tinymce.init({
  selector: ".mytextarea",
  plugins: "mentions",
  mentions_min_chars: 0,
  mentions_fetch: function (query, success) {
    fetchUsers().then(function (users) {
      console.log(users);
      users = users.slice(0, 10);
      success(users);
    });
  },
});

And that’s it – your index.html file with Mentions plugin demo set up can now run on local host.

There are a few methods to do this: try the Node.js server for serving static files, or run a server with Python3 using the python3 -m http.server command in the same directory as your index.html file, if you have Python installed.

Here’s the demo in action:
Type the trigger character

And here is the complete project JavaScript, with the filter() method, and the accompanying return function with indexOf() for further expansion:

<script>
const apiA = https://api.openweathermap.org/data/2.5/onecall?lat=23.6980&lon=133.8807&appid=api-key';
const apiL = https://api.openweathermap.org/data/2.5/onecall?lat=51.5072&lon=0.1276&appid=api-key';
const fetchUsers = () => {
  let firstUser = fetch(apiA).then(response => response.json()).then((data) => {
    const name = data.current.weather[0].description;
    const id = String(data.current.sunrise);
    const user = {
        id: id,
        name: name
        }
        return user;
        })

  let secondUser = fetch(apiL).then(response => response.json()).then((data) => {
    const name = data.current.weather[0].description;
    const id = String(data.current.sunrise);
    const user = {
        id,
        name
        }
        return user;
        })
        
return Promise.all([firstUser,secondUser]);
        }
  selector: 'textarea',
  plugins: 'mentions',
  mentions_min_chars: 0,
  mentions_fetch: function (query, success) {
                    
  fetchUsers().then(function(users) {
      console.log(users);
      //users = users.filter(function (user) {
      //    return user.name.indexOf(query.term.toLowerCase()) !== -1;
      //});
      users = users.slice(0, 10);
      success(users);
         })
        },
     });
</script>

Take the next step for your web application

With the Mentions plugin setup, you can mention the weather, but that’s only the first iteration in getting started with the Mentions plugin. 

The next step you can try is changing out the novel Open Weather API for some actual user information. Then you can introduce the filter() method, and the accompanying return function with the indexOf() method mentioned in the documentation.

The documentation makes use of the Faker.js project to create realistic, false user data, which is helpful if you don’t want to use actual user information.

Remember to sign up for a free TinyMCE API key if you’d like to try out our premium plugins for a 14-day trial, or check on the TinyMCE pricing page

CollaborationPlugins
byJoe Robinson

Technical and creative writer, editor, and a TinyMCE advocate. An enthusiast for teamwork, open source software projects, and baking. Can often be found puzzling over obscure history, cryptic words, and lucid writing.

Related Articles

  • How-tos & Tutorials

    Add an emoji picker to text fields in your React apps

    by Ben Long in How-tos & Tutorials
  • How-tos & Tutorials

    HTML spell check

    by Ben Long in How-tos & Tutorials
Subscribe for the latest insights served straight to your inbox every month.

Deploy TinyMCE in just 6 lines of code

Built to scale. Developed in open source. Designed to innovate.

Begin with your FREE API Key
Tiny Editor
Tiny logo
Privacy Policy - Terms of Use© 2021 Tiny Technologies Inc.TinyMCE® and Tiny® are registered trademarks of Tiny Technologies, Inc.

Products

  • TinyMCE
  • Tiny Drive
  • Customer Stories
  • Pricing