Skip to content
This repository has been archived by the owner. It is now read-only.
Facebook-like @mentions for text inputs built around composability
JavaScript CSS HTML
Branch: master
Clone or download

Latest commit

dependabot and biggieman Bump mixin-deep from 1.3.1 to 1.3.2 (#61)
Bumps [mixin-deep](https://github.com/jonschlinkert/mixin-deep) from 1.3.1 to 1.3.2.
- [Release notes](https://github.com/jonschlinkert/mixin-deep/releases)
- [Commits](jonschlinkert/mixin-deep@1.3.1...1.3.2)

Signed-off-by: dependabot[bot] <support@github.com>
Latest commit 4808ed4 Aug 29, 2019

Files

Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
dist fix specific code Mar 1, 2019
example fix specific code Mar 1, 2019
src fix specific code Mar 1, 2019
test Choose one mention twice (#56) Jan 31, 2019
.gitignore update dependencies (#55) Jan 10, 2019
.travis.yml Create .travis.yml (#37) Nov 4, 2016
LICENSE
README.md fix(docs): remove non-code text from code block in readme (#43) Dec 20, 2016
bower.json bower version Mar 1, 2019
gulpfile.js update dependencies (#55) Jan 10, 2019
karma.conf.js Add fn.bind polyfill for PhantomJS Oct 19, 2015
package-lock.json Bump mixin-deep from 1.3.1 to 1.3.2 (#61) Aug 29, 2019
package.json version Mar 1, 2019

README.md

ui-mention

Facebook-like @mentions for text inputs built around composability

Installation Methods

npm

$ npm install angular-ui-mention

bower

$ bower install angular-ui-mention

Usage

For now, you should create a child-directive to customize (API probably going to change)

.directive('myMention', function($http){
  return {
    require: 'uiMention',
    link: function($scope, $element, $attrs, uiMention) {
      /**
       * Converts a choice object to a human-readable string
       *
       * @param  {mixed|object} choice The choice to be rendered
       * @return {string}              Human-readable string version of choice
       */
       uiMention.label = function(choice) {
         return choice.first_name + " " + choice.last_name;
       };

      /**
       * Retrieves choices
       *
       * @param  {regex.exec()} match    The trigger-text regex match object
       * @return {array[choice]|Promise} The list of possible choices
       */
      uiMention.findChoices = function(match, mentions) {
        return $http.get(...).then(...);
      };
    }
  };
});

You have to build the HTML yourself:

<div class="ui-mention-container">

  <textarea ng-model="data" ui-mention my-mention></textarea>

  <div class="ui-mention-highlight"></div>

  <ul class="dropdown" ng-if="$mention.choices.length">
    <li ng-repeat="choice in $mention.choices"
      ng-class="{active:$mention.activeChoice==choice}"
      ng-click="$mention.select(choice)">
      {{::choice.first_name}} {{::choice.last_name}}
    </li>
  </ul>

</div>

And the CSS:

.ui-mention-container {
  position: relative;
  [ui-mention] {
    min-height: 100px;
    background: none;
    position: relative;
    z-index: 2;
    box-sizing: content-box; // Prevent scrollbar for autogrow
  }
  .ui-mention-highlight {
      white-space: pre-wrap;
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      background: white;
      color: rgba(0,0,0,0);
      z-index: 1;
      span {
        border-radius: 2px;
        background-color: lightblue;
        border: 1px solid blue;
        padding: 0 2px;
        margin: -1px -3px;
      }
  }
  .dropdown {
    position: absolute;
    top: 100%;
    left: 0;
  }
}

Amazing Features!

All these features come at the amazingly low price of DO IT YOURSELF and $0.00. YMMV.

User your own patterns:

mention.delimiter = '/* delimiter */';

mention.searchPattern = new RegExp("/* pattern */");

mention.decodePattern = new RegExp("/* pattern */");

Find things!:

mention.findChoices = function(match) {
  // Matches items from search query
  return [/* choices */].filter(function(choice) {
    return ~this.label(choice).indexOf(match[1]);
  });
}

Type too freakin' fast? Throttle that sucker:

mention.findChoices = _.throttle(function(match) {
  return [/* choices */];
}, 300);

Minimum characters to trigger:

mention.findChoices = function(match) {
  if (match[1].length > 2)
    return [/* choices */];
};

Hate redundancy? De-dupe that shiznizzle:

mention.findChoices = function(match, mentions) {
  return [ /* choices */ ].filter(function(choice) {
    return !mentions.some(function(mention) {
      return mention.id === choice.id;
    });
  });
};

Use the awesome power of the internet:

mention.findChoices = function(match) {
  return $http.get('/users', { params: { q: match[1] } })
    .then(function(response) {
      return response.data;
    });
}

Your servers are slow? Mama please.

mention.findChoices = function(match) {
  mention.loading = true;
  return $http.get(...)
    .finally(function(response) {
      mention.loading = false;
    });
}

Dropdown that list like it's hot:

<ul ng-if="$mention.choices.length" class="dropdown">
  <li ng-repeat="choice in choice" ng-click="$mention.select(choice)">
    {{::choice.name}}
  </li>
</ul>

SPINNIES!

<ul ng-if="$mention.choices.length" class="dropdown">
  <li ng-show="$mention.loading">Hacking the gibson...</li>
  <li ng-repeat=...>...</li>
</ul>

Contribute

  1. npm install
  2. npm install -g gulp bower
  3. bower install
  4. gulp [watch]
  5. Compiling the example code: gulp example [watch]
You can’t perform that action at this time.