From 8104ddc3e4e3c439d19e0b4a271610b0f0a0a884 Mon Sep 17 00:00:00 2001 From: Michael Benford Date: Wed, 12 Apr 2017 16:19:32 -0300 Subject: [PATCH] feat(tagsInput): Add experimental support for array of strings Add a new option called useStrings that enables experimental support for array of strings in addiiton to array of objects. This change only affects the way the model bound to the directive is manipulated. Internally an array of objects is still used to store existing tags, and events related to tag operations still expose tags as objects. --- src/tags-input.js | 14 ++++++++++++-- test/tags-input.spec.js | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/tags-input.js b/src/tags-input.js index 4afc66d1..de8e2466 100644 --- a/src/tags-input.js +++ b/src/tags-input.js @@ -9,6 +9,7 @@ * Renders an input box with tag editing support. * * @param {string} ngModel Assignable Angular expression to data-bind to. + * @param {boolean=} [useStrings=false] Flag indicating that the model is an array of strings (EXPERIMENTAL). * @param {string=} [template=NA] URL or id of a custom template for rendering each tag. * @param {string=} [templateScope=NA] Scope to be passed to custom templates - of both tagsInput and * autoComplete directives - as $scope. @@ -150,6 +151,10 @@ tagsInput.directive('tagsInput', function($timeout, $document, $window, $q, tags self.index = -1; }; + self.getItems = function() { + return options.useStrings ? self.items.map(getTagText): self.items; + }; + self.clearSelection(); return self; @@ -203,7 +208,8 @@ tagsInput.directive('tagsInput', function($timeout, $document, $window, $q, tags keyProperty: [String, ''], allowLeftoverText: [Boolean, false], addFromAutocompleteOnly: [Boolean, false], - spellcheck: [Boolean, true] + spellcheck: [Boolean, true], + useStrings: [Boolean, false] }); $scope.tagList = new TagList($scope.options, $scope.events, @@ -302,6 +308,10 @@ tagsInput.directive('tagsInput', function($timeout, $document, $window, $q, tags scope.$watch('tags', function(value) { if (value) { tagList.items = tiUtil.makeObjectArray(value, options.displayProperty); + if (options.useStrings) { + return; + } + scope.tags = tagList.items; } else { @@ -378,7 +388,7 @@ tagsInput.directive('tagsInput', function($timeout, $document, $window, $q, tags scope.newTag.text(''); }) .on('tag-added tag-removed', function() { - scope.tags = tagList.items; + scope.tags = tagList.getItems(); // Ideally we should be able call $setViewValue here and let it in turn call $setDirty and $validate // automatically, but since the model is an array, $setViewValue does nothing and it's up to us to do it. // Unfortunately this won't trigger any registered $parser and there's no safe way to do it. diff --git a/test/tags-input.spec.js b/test/tags-input.spec.js index 3a72d514..129011fb 100644 --- a/test/tags-input.spec.js +++ b/test/tags-input.spec.js @@ -1945,6 +1945,43 @@ describe('tags-input directive', function() { }); }); + describe('use-strings option', function() { + it('initializes the option to false', function() { + // Arrange/Act + compile(); + + // Assert + expect(isolateScope.options.useStrings).toBe(false); + }); + + it('updates the model', function() { + // Arrange + compile('use-strings="true"'); + + // Act + newTag('Tag1'); + newTag('Tag2'); + newTag('Tag3'); + + // Assert + expect($scope.tags).toEqual(['Tag1', 'Tag2', 'Tag3']); + }); + + it('renders the correct number of tags', function() { + // Arrange + $scope.tags = ['Tag1', 'Tag2', 'Tag3']; + + // Act + compile('use-strings="true"'); + + // Assert + expect(getTags().length).toBe(3); + expect(getTagText(0)).toBe('Tag1'); + expect(getTagText(1)).toBe('Tag2'); + expect(getTagText(2)).toBe('Tag3'); + }); + }); + describe('ng-disabled support', function () { it('disables the inner input element', function () { // Arrange/Act