jquery.textntags is a small UI component that allows you to "@tag" someone in a text message, just like you are used to on Facebook or Twitter.

This project is written by Daniel Zahariev and is open source to give it a life in the community.

Credit for the code skeleton: Kenneth Auchenberg, and his Mentions Input jQuery plugin


1. Basic example (source) - duplicate tags are allowed

Note: console.log and JSON.stringify are used in this example

Get marked-up value Get tags collection Get tags map Get tags map in Facebook format Copy text'n'tags to next textarea

2. AJAX example. (Getting data by AJAX, and filter in callback - source)

3. Custom tags markup example (source)

Get marked-up value

4. Custom triggers example (source)

Get marked-up value

5. Preload content example

Download and source

You can grab the latest source from the repository on GitHub by clicking here: https://github.com/daniel-zahariev/jquery-textntags.

Getting started

  1. Add a script reference to jquery.textntags.js:
    <script src='jquery.textntags.js' type='text/javascript'></script>
  2. Add a bit of markup:
    <textarea class='tagged_text'></textarea>
  3. Initialise the textntags:

      onDataRequest: function (mode, query, triggerChar, callback) {
        var data = [
          { id:1, name:'Daniel Zahariev',  'img':'http://example.com/img1.jpg', 'type':'contact' },
          { id:2, name:'Daniel Radcliffe', 'img':'http://example.com/img2.jpg', 'type':'contact' },
          { id:3, name:'Daniel Nathans',   'img':'http://example.com/img3.jpg', 'type':'contact' }
        query = query.toLowerCase();
        var found = _.filter(data, function(item) { return item.name.toLowerCase().indexOf(query) > -1; });
       callback.call(this, found);


jquery.textntags does have a number of extra configuration options which you may change to customise the way it behaves.

The meaning of the options and their default values are listed below.

onDataRequest function(mode, query, triggerChar, callback)
This function is a callback function which is used to provide data for the autocomplete. When a search starts this function is called with following arguments: 'search', the query (what's been typed), the trigger character, and a callback function which needs to be called inside onDataRequest with a data collection to be searched on as a first argument.

realValOnSubmit true | false
Wether to hooks to the submit event of the closest form and update the value of the textarea to the one with markup

triggers object
Key/value pairs which define all triggers. The keys are the characters for triggering (example: '@') suggestion list. The value is an options object which controls the behavior. The possible options are listed below.

templates object
Object which contains templates used to render the layout as key/value pairs.


minChars int (2)
The minimum amount of characters after the trigger character necessary to perform a search.

uniqueTags true | false
Toggles whether or not to allow duplicate tags in the text.

showImageOrIcon true | false
Toggles whether or not items within the autocomplete-dropdown will be rendered with an image/icon.

keys_map object
Defines a map of the keys between the items in the tag search results and the item format used inside the plugin. The keys in the object are the keys a tag will have when used inside the plugin.
Default value:

	id: 'id',
	title: 'name',
	description: '',
	img: 'img',
	no_img_class: 'icon',
	type: 'type'

syntax function
This is template function created using Underscore which transforms the tag object to markup. Default value:
_.template('@[[<%= id %>:<%= type %>:<%= title %>]]')

parser RegExp
Regular Expression that matches the markup for this trigger character.
Default value:

parserGroups object
Object that maps the indexes of the parsed groups with the corresponding tag properties. Default value:
{id: 2, type: 3, title: 4}

NB: if you modify this for given trigger be sure to have the max index of a group match a propery.

classes object
Object which contains classes used in the layout as key/value pairs.


jquery.textntags does expose a number of public methods, you can call on an instance.

init function(settings)
Initialises the textntags component on a specific element. And actually you can't invoke it more than once on an element.

reset function
Resets the component, clears all tags.

val function(callbackOrVal)
An async method which accepts a callback function and returns a value of the input field (including markup) as a first parameter of this function.
This is the value you want to send to your server.
The second way to use this method is as a setter - pass string value to be set as value of the textarea. The string can contain markup.

getTags function(callback)
An async method which accepts a callback function and returns a collection of unique tags as hash objects as a first parameter.

getTagsMap function(callback)
An async method which accepts a callback function and returns a map(array) of all tags (non-unique) as array as a first parameter.

The format of each map element is an array [positionInPlainText, lengthOfTitle, triggerChar, tagAsObject]. Example:

$(...).textntags('getTagsMap', function (tagsMap) {
	// tagsMap = [[1, 6, '@', {'id': }]]

getTagsMapFacebook function(callback)
An async method which accepts a callback function and returns a map(object) of all tags (non-unique) as object as a first parameter.

The format is specified by Facebook for message_tags. Example:

  "0": [{
    "id": "1", 
    "name": "Daniel Zahariev", 
    "type": "user", 
    "offset": 0, 
    "length": 15

parseTaggedText function(tagged_text, callback)
An async method which accepts a tagged_text (text with tags markup) and a callback function and returns a parsed version of the text in form of object with the following properties:


The plugin supports custom events so that dependency can be implemented

tagsAdded callback(e, addedTagsList)
Triggered when tagging occured, and also in 2 special cases:

  1. When the plugin initializes on a field and tags are found
  2. When the method val of the plugin is used as a setter and tags are found in the new text
Passes 2 arguments to a callback function:
  1. The event created by jQuery
  2. An array with the added tags

tagsRemoved callback(e, removedTagsList)
Triggered when tag removal occured, and also in a special case:

  1. When the method val of the plugin is used as a setter and the current tags are removed
Passes 2 arguments to a callback function:
  1. The event created by jQuery
  2. An array with the removed tags

Example binding to the event:

  .bind('tagsAdded.textntags', function (e, addedTagsList) {
    console.log('tagsAdded:' + JSON.stringify(addedTagsList));

Query data structure

When the component is preforming a "query" on the data specified through the onDataRequest-callback, it's expecting a specific data structure to be returned.

  'id'    : 1,
  'name'  : 'Daniel Zahariev',
  'img'   : 'http://profile.ak.fbcdn.net/hprofile-ak-snc4/174073_1704423938_6732585_q.jpg',
  'icon'  : 'icon-16 icon-person',
  'type'  : 'contact'

Markup format

When tags are being added to the input, a marked-up version of the value is generated, to allow the tags to be extracted, parsed and stored later.
Example markup: @[id:type:title]
And in action: This is a message for @[1:contact:Daniel Zahariev]
You can define your own markup format for the tags by exploiting the settings `syntax`, `parser` and `parserGroups` which you can define per trigger.
Using the following settings for triggers: syntax, parser and parserGroups you can define your own markup.
Example (#4 in Examples):

  triggers: {'#': {
    uniqueTags   : false,
    syntax       : _.template('#[<%= id %>:<%= type %>:<%= title %>]'),
    parser       : /(#)\[(\d+):([\w\s\.\-]+):([\w\s@\.,-\/#!$%\^&\*;:{}=\-_`~()]+)\]/gi,
    parserGroups : {id: 2, type: 3, title: 4},

Browser support

jquery.textntags is still being tested for browser support.


jquery.textntags is written as a jQuery extension, so it naturally requires jQuery. In addition to jQuery, it also depends on underscore.js, which is used to simplify stuff a bit.

The component is also using the new HTML5 "input" event. This means older browsers like IE8 need a polyfill which emulates the event (it is bundled).


MIT License - http://www.opensource.org/licenses/mit-license.php

Change Log

Fixed selection of tag from the suggestion list with return and tab keys.
Added the method getTagsMapFacebook and example for it.

Multi-char triggers supported, bugfixed a case when Return key is clicked

Initial release.