Skip to content
This repository has been archived by the owner on Nov 22, 2021. It is now read-only.

Commit

Permalink
Merge a0f3fb8 into 315f3a2
Browse files Browse the repository at this point in the history
  • Loading branch information
JAndritsch committed Feb 6, 2015
2 parents 315f3a2 + a0f3fb8 commit 2288370
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 10 deletions.
42 changes: 32 additions & 10 deletions src/tags-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,18 @@
* When this flag is true, addOnEnter, addOnComma, addOnSpace, addOnBlur and
* allowLeftoverText values are ignored.
* @param {boolean=} [spellcheck=true] Flag indicating whether the browser's spellcheck is enabled for the input field or not.
* @param {expression} shouldAddTag A reference to a method in scope that will be invoked before adding a new tag. This is an option for additional, custom validations or a general way to prevent a tag from being added. The new tag is passed to the function for evaluation. This method must return either true or false. If false, the tag will not be added.
* @param {expression} onTagAdded Expression to evaluate upon adding a new tag. The new tag is available as $tag.
* @param {expression} onInvalidTag Expression to evaluate when a tag is invalid. The invalid tag is available as $tag.
* @param {expression} shouldRemoveTag A reference to a method in scope that will be invoked before removing a tag. This can be used to prevent a tag from being added. The tag is passed to the function for evaluation. This method must return either true or false. If false, the tag will not be removed.
* @param {expression} onTagRemoved Expression to evaluate upon removing an existing tag. The removed tag is available as $tag.
*/
tagsInput.directive('tagsInput', function($timeout, $document, tagsInputConfig) {
function TagList(options, events) {

function TagList(scope) {
var options = scope.options;
var events = scope.events;

var self = {}, getTagText, setTagText, tagIsValid;

getTagText = function(tag) {
Expand All @@ -53,12 +59,17 @@ tagsInput.directive('tagsInput', function($timeout, $document, tagsInputConfig)

tagIsValid = function(tag) {
var tagText = getTagText(tag);
var valid = tagText &&
tagText.length >= options.minLength &&
tagText.length <= options.maxLength &&
options.allowedTagsPattern.test(tagText) &&
!findInObjectArray(self.items, tag, options.displayProperty);

if (scope.shouldAddTag()) {
valid = valid && scope.shouldAddTag()(tag);
}

return tagText &&
tagText.length >= options.minLength &&
tagText.length <= options.maxLength &&
options.allowedTagsPattern.test(tagText) &&
!findInObjectArray(self.items, tag, options.displayProperty);
return valid;
};

self.items = [];
Expand Down Expand Up @@ -90,9 +101,18 @@ tagsInput.directive('tagsInput', function($timeout, $document, tagsInputConfig)
};

self.remove = function(index) {
var tag = self.items.splice(index, 1)[0];
events.trigger('tag-removed', { $tag: tag });
return tag;
var tag = self.items[index];
var shouldRemove = true;

if (scope.shouldRemoveTag()) {
shouldRemove = scope.shouldRemoveTag()(tag);
}

if (shouldRemove) {
self.items.splice(index, 1);
events.trigger('tag-removed', { $tag: tag });
return tag;
}
};

self.removeLast = function() {
Expand Down Expand Up @@ -121,8 +141,10 @@ tagsInput.directive('tagsInput', function($timeout, $document, tagsInputConfig)
require: 'ngModel',
scope: {
tags: '=ngModel',
shouldAddTag: '&',
onTagAdded: '&',
onInvalidTag: '&',
shouldRemoveTag: '&',
onTagRemoved: '&'
},
replace: false,
Expand Down Expand Up @@ -155,7 +177,7 @@ tagsInput.directive('tagsInput', function($timeout, $document, tagsInputConfig)
spellcheck: [Boolean, true]
});

$scope.tagList = new TagList($scope.options, $scope.events);
$scope.tagList = new TagList($scope);

this.registerAutocomplete = function() {
var input = $element.find('input');
Expand Down
36 changes: 36 additions & 0 deletions test/tags-input.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,42 @@ describe('tags-input directive', function() {
expect($scope.tags).toEqual([{ text: 'foo' }]);
});

it('will not add a tag based on custom logic specified by the should-add-tag option', function() {
// Arrange
$scope.tagIsNotInvalid = function(newTag) {
return (newTag.text !== 'INVALID');
};

compile('should-add-tag="tagIsNotInvalid"');

// Act
newTag('foo');
newTag('bar');
newTag('INVALID');

// Assert
expect($scope.tags).toEqual([{ text: 'foo' }, { text: 'bar' }]);
});

it('will not remove a tag based on custom logic specified by the should-remove-tag option', function() {
// Arrange
$scope.tagIsNotPermanent = function(newTag) {
return (newTag.text !== 'PERMANENT');
};

compile('should-remove-tag="tagIsNotPermanent"');

// Act
newTag('foo');
newTag('PERMANENT');
newTag('bar');

getRemoveButton(1).click();

// Assert
expect($scope.tags).toEqual([{ text: 'foo' }, { text: 'PERMANENT' }, { text: 'bar' }]);
});

it('makes the input field invalid when a duplicate tag is tried to be added', function() {
// Arrange
compile();
Expand Down

0 comments on commit 2288370

Please sign in to comment.