diff --git a/examples/assets/app_bs3.js b/examples/assets/app_bs3.js index 571a63cb..f991807b 100644 --- a/examples/assets/app_bs3.js +++ b/examples/assets/app_bs3.js @@ -58,4 +58,14 @@ elt.tagsinput('input').typeahead({ }).bind('typeahead:selected', $.proxy(function (obj, datum) { this.tagsinput('add', datum); this.tagsinput('input').typeahead('setQuery', ''); -}, elt)); \ No newline at end of file +}, elt)); + +angular.module('AngularExample', ['bsTagsInput']) + .controller('Ctrl', + function Ctrl($scope) { + $scope.tags = ['Amsterdam', 'Washington']; + $scope.tagsTypeahead = { + local: ['Sydney', 'Beijing', 'Cairo'] + }; + } + ); diff --git a/examples/assets/bsTagsInput.js b/examples/assets/bsTagsInput.js new file mode 100644 index 00000000..23eae43b --- /dev/null +++ b/examples/assets/bsTagsInput.js @@ -0,0 +1,108 @@ +angular.module('bsTagsInput', []) +/** + * @ngdoc directive + * @name bsTagsInput + * @restrict A + * + * @description + * Sets up an input field for tag inputs, using the bootstrap-tagsinput jQuery plugin. + * + * @element INPUT or SELECT + * @param {Object} options passed to the bootstrap-tagsinput plugin at initialization. + * + * @example + + + +
+ +
{{tags}}
+
+
+
+ */ +.directive('bsTagsInput', function() { + // reference to underscorejs/lodash difference method + var difference; + if (typeof(_) !== 'undefined') { + difference = _.difference; + } else { + // fallback to a naive implementation + difference = function(array, other) { + var results = []; + angular.forEach(array, function(value) { + if (other.indexOf(value) === -1) { + results.push(value); + } + }); + return results; + }; + } + + return { + require: 'ngModel', + controller: function() { + }, + link: function(scope, element, attrs, ngModelCtrl) { + // initialize tagsinput + var options = scope.$eval(attrs.bsTagsInput) || {}; + element.tagsinput(options); + + // handle changes from the underlying model + ngModelCtrl.$render = function() { + var oldVal = element.tagsinput('items'), + newVal = ngModelCtrl.$viewValue; + difference(oldVal, newVal).forEach(function(item) { + element.tagsinput('remove', item, true); + }); + difference(newVal, oldVal).forEach(function(item) { + element.tagsinput('add', item, true); + }); + }; + + // handle changes from the UI + element.on('change', function() { + var items = element.tagsinput('items'); + ngModelCtrl.$setViewValue(items); + }); + + // handle cleanup + scope.$on('$destroy', function() { + element.tagsinput('destroy'); + }); + } + }; +}) +/** + * @ngdoc directive + * @name bsTagsTypeahead + * @restrict A + * + * @description + * Using typeahead.js, adds autocompletion support to a bsTagsInput field. + * + * @element INPUT or SELECT + * @param {Object} options passed to the typeahead.js plugin. + */ +.directive('bsTagsTypeahead', function() { + return { + require: 'bsTagsInput', + link: function(scope, element, attrs, bsTagsInputCtrl) { + // setup typeahead on the 'input' element + var options = scope.$eval(attrs.bsTagsTypeahead) || {}; + element.tagsinput('input') + .typeahead(options) + .bind('typeahead:selected', function(obj, datum) { + element.tagsinput('add', datum.value); + element.tagsinput('input').typeahead('setQuery', ''); + }); + } + } +}); diff --git a/examples/bootstrap3/index.html b/examples/bootstrap3/index.html index 9c946210..63621797 100644 --- a/examples/bootstrap3/index.html +++ b/examples/bootstrap3/index.html @@ -297,19 +297,16 @@

Categorizing tags

statementreturns
$("input").val()
$("input").tagsinput('items')
- +