Search code examples
angularjsangularjs-directivejquery-tokeninput

tokenInput as angular.js directive


I'm attempting to create an angular.js directive from James Smith's tokenInput Jquery plugin: http://loopj.com/jquery-tokeninput

Here is what I have so far:

antdna = angular.module('Communication', []);

antdna.factory('autoCompleteService', [function() {
    return {
      getSource: function() {
      return [{"id":1, "name":"John Doe"}, {"id":2, "name":"Jane Smith"}];
    }
  }
}]);

antdna.directive('autoComplete', function(autoCompleteService) {
    return {
        restrict: 'A',
        link: function(scope, elem) {
            elem.tokenInput(autoCompleteService.getSource(), {
                crossDomain:false,
                theme: "facebook",
                hintText: "Enter User Name",

                preventDuplicates: true
            });
            }
    };
});

With the following markup:

<input type="text" name="recipient" ng-model="conversation.recipients" class="messageComposeTextField" auto-complete placeholder="To :" required />

TokenInput works perfectly but my issue is that I cannot bind to the model.

{{conversation.recipients}} 

is blank.

The tokenInput plugin generates it's own markup using list elements (ul and li). So upon inspecting the element I get:

<ul class="token-input-list-facebook">
  <li class="token-input-token-facebook"><p>John Doe</p><span class="token-input-delete-token-facebook">×</span></li><li class="token-input-input-token-facebook"><input type="text" autocomplete="off" autocapitalize="off" id="token-input-" style="outline: none; width: 30px;"><tester style="position: absolute; top: -9999px; left: -9999px; width: auto; font-size: 12px; font-family: Ubuntu, 'Ubuntu Beta', UbuntuBeta, Ubuntu, 'Bitstream Vera Sans', 'DejaVu Sans', Tahoma, sans-serif; font-weight: 400; letter-spacing: 0px; white-space: nowrap;"></tester>    </li>
</ul>

<input type="text" name="recipient" ng-model="conversation.recipients" class="messageComposeTextField ng-pristine ng-invalid ng-invalid-required" auto-complete="" placeholder="To :" required="" style="display: none;">

Notice that the generated tokenInput markup is not part of the directive. So the real question here is how do I encapsulate a jquery plugin that generates its own markup within an angularjs directive?


Solution

  • I suggest you to use ui-select2 ready to use directive for similar functionality @ https://github.com/angular-ui/ui-select2, it provides "simple tagging mode" similar to your requirement

    Check the new example. The old example can be found here.

    $scope.tagsSelection = [
        { "id": "01", "text": "Perl" },
        { "id": "03", "text": "JavaScript" }
    ];       
    
    $timeout(function(){
        $scope.tagsSelection.push({ 'id': '02', 'text': 'Java' });
    }, 3000);
    
    $scope.tagData = [
        {
            "id": "01",
            "text": "Perl"
        },
        {
            "id": "02",
            "text": "Java"
        },
        {
            "id": "03",
            "text": "JavaScript"
        },
        {
            "id": "04",
            "text": "Scala"
        }
    ];
    
    $scope.tagAllOptions = {
        multiple: true,
        data: $scope.tagData
    };
    

    You can check details for options and documentation at: http://ivaynberg.github.io/select2/