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

Commit

Permalink
feat(tagsInput): Add max-tags option
Browse files Browse the repository at this point in the history
Add a max-tags option so the user can set how many tags should be added
before the control is deemed invalid. The user won't be prevented from
adding tags; she will have to check the control's validity state in order
to determine whether it's valid or not.

Closes #24.
  • Loading branch information
mbenford committed Jan 4, 2014
1 parent a912920 commit 2bc02ec
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/tags-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ tagsInput.directive('tagsInput', function($timeout, $document, tiConfiguration)

return {
restrict: 'E',
require: 'ngModel',
scope: {
tags: '=ngModel',
onTagAdded: '&',
Expand All @@ -73,7 +74,8 @@ tagsInput.directive('tagsInput', function($timeout, $document, tiConfiguration)
addOnComma: { type: Boolean, defaultValue: true },
addOnBlur: { type: Boolean, defaultValue: true },
allowedTagsPattern: { type: RegExp, defaultValue: /^[a-zA-Z0-9\s]+$/ },
enableEditingLastTag: { type: Boolean, defaultValue: false }
enableEditingLastTag: { type: Boolean, defaultValue: false },
maxTags: { type: Number }
});

$scope.events = new SimplePubSub();
Expand Down Expand Up @@ -172,7 +174,7 @@ tagsInput.directive('tagsInput', function($timeout, $document, tiConfiguration)
};
};
},
link: function(scope, element) {
link: function(scope, element, attrs, ngModelCtrl) {
var hotkeys = [KEYS.enter, KEYS.comma, KEYS.space, KEYS.backspace];
var input = element.find('input');

Expand Down Expand Up @@ -233,6 +235,10 @@ tagsInput.directive('tagsInput', function($timeout, $document, tiConfiguration)
element.find('div').on('click', function() {
input[0].focus();
});

scope.$watch('tags.length', function() {
ngModelCtrl.$setValidity('maxTags', angular.isUndefined(scope.options.maxTags) || scope.tags.length <= scope.options.maxTags);
});
}
};
});
77 changes: 77 additions & 0 deletions test/tags-input.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ describe('tags-input-directive', function() {
isolateScope = element.isolateScope();
}

function compileWithForm() {
var options = jQuery.makeArray(arguments).join(' ');
var template = '<form name="form"><tags-input ng-model="tags" ' + options + '></tags-input></form>';

element = $compile(template)($scope);
$scope.$digest();
isolateScope = element.isolateScope();
}

function getTags() {
return element.find('li');
}
Expand Down Expand Up @@ -863,6 +872,74 @@ describe('tags-input-directive', function() {
});
});

describe('max-tags option', function() {
it('initializes the option to undefined', function() {
// Arrange/Act
compile();

// Assert
expect(isolateScope.options.maxTags).toBeUndefined();
});

it('sets the option given a static string', function() {
// Arrange/Act
compile('max-tags="3"');

// Assert
expect(isolateScope.options.maxTags).toBe(3);
});

it('sets the option given an interpolated string', function() {
// Arrange
$scope.value = 5;

// Act
compile('max-tags="{{ value }}"');

// Assert
expect(isolateScope.options.maxTags).toBe(5);
});

it('makes the element invalid when the number of tags is greater than the max-tags option', function() {
// Arrange
compileWithForm('max-tags="2"', 'name="tags"');

// Act
$scope.tags = ['Tag1', 'Tag2', 'Tag3'];
$scope.$digest();

// Assert
expect($scope.form.tags.$invalid).toBe(true);
expect($scope.form.tags.$error.maxTags).toBe(true);
});

it('makes the element valid when the number of tags is not greater than the max-tags option', function() {
// Arrange
compileWithForm('max-tags="2"', 'name="tags"');

// Act
$scope.tags = ['Tag1', 'Tag2'];
$scope.$digest();

// Assert
expect($scope.form.tags.$valid).toBe(true);
expect($scope.form.tags.$error.maxTags).toBe(false);
});

it('makes the element valid when the max-tags option is undefined', function() {
// Arrange
compileWithForm('name="tags"');

// Act
$scope.tags = ['Tag1', 'Tag2', 'Tags3', 'Tags4', 'Tags5'];
$scope.$digest();

// Assert
expect($scope.form.tags.$valid).toBe(true);
expect($scope.form.tags.$error.maxTags).toBe(false);
});
});

describe('on-tag-added option', function() {
it('calls the provided callback when a new tag is added', function() {
// Arrange
Expand Down

0 comments on commit 2bc02ec

Please sign in to comment.