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

Commit

Permalink
feat(config): Add support for global configuration
Browse files Browse the repository at this point in the history
Add support for global configuration so multiple directives sharing the
same configuration can be set up only once and in one place. That
configuration is achieved by using a provider within the module .config
function.

Closes #48.
  • Loading branch information
mbenford committed Jan 10, 2014
1 parent c32f598 commit e48be11
Show file tree
Hide file tree
Showing 10 changed files with 224 additions and 374 deletions.
1 change: 1 addition & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module.exports = function(grunt) {
js: {
src: [
'src/keycodes.js',
'src/init.js',
'src/tags-input.js',
'src/auto-complete.js',
'src/transclude-append.js',
Expand Down
2 changes: 1 addition & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module.exports = function(config) {
'test/lib/angular.js',
'test/lib/angular-mocks.js',
'test/*.spec.js',
'src/tags-input.js',
'src/init.js',
'src/*.js',
'templates/*.html'
],
Expand Down
12 changes: 6 additions & 6 deletions src/auto-complete.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* suggestions list.
* @param {number=} [maxResultsToShow=10] Maximum number of results to be displayed at a time.
*/
tagsInput.directive('autoComplete', function($document, $timeout, $sce, tiConfiguration) {
tagsInput.directive('autoComplete', function($document, $timeout, $sce, tagsInputConfig) {
function SuggestionList(loadFn, options) {
var self = {}, debouncedLoadId, getDifference, lastPromise;

Expand Down Expand Up @@ -114,11 +114,11 @@ tagsInput.directive('autoComplete', function($document, $timeout, $sce, tiConfig
var hotkeys = [KEYS.enter, KEYS.tab, KEYS.escape, KEYS.up, KEYS.down],
suggestionList, tagsInput, markdown;

tiConfiguration.load(scope, attrs, {
debounceDelay: { type: Number, defaultValue: 100 },
minLength: { type: Number, defaultValue: 3 },
highlightMatchedText: { type: Boolean, defaultValue: true },
maxResultsToShow: { type: Number, defaultValue: 10 }
tagsInputConfig.load('autoComplete', scope, attrs, {
debounceDelay: [Number, 100],
minLength: [Number, 3],
highlightMatchedText: [Boolean, true],
maxResultsToShow: [Number, 10]
});

tagsInput = tagsInputCtrl.registerAutocomplete();
Expand Down
45 changes: 33 additions & 12 deletions src/configuration.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,48 @@
'use strict';

/**
* @ngdoc service
* @name tagsInput.service:tiConfiguration
* @ngdoc provider
* @name tagsInput.provider:tagsInputConfig
*
* @description
* Loads and initializes options from HTML attributes. Used internally by tagsInput and autoComplete directives.
* Sets global default configuration options for tagsInput and autoComplete directives. It's also used internally to parse and
* initialize options from HTML attributes.
*/
tagsInput.service('tiConfiguration', function($interpolate) {
this.load = function(scope, attrs, options) {
tagsInput.provider('tagsInputConfig', function() {
var globalDefaults = {};

/**
* @ngdoc function
* @name setDefaults
* @description Sets the default configuration option for a directive.
*
* @param {string} directive Name of the directive to be configured. Must be either 'tagsInput' or 'autoComplete'.
* @param {object} defaults Object containing options and their values.
*/
this.setDefaults = function(directive, defaults) {
globalDefaults[directive] = defaults;
return this;
};

this.$get = function($interpolate) {
var converters = {};
converters[String] = function(value) { return value; };
converters[Number] = function(value) { return parseInt(value, 10); };
converters[Boolean] = function(value) { return value === 'true'; };
converters[Boolean] = function(value) { return value.toLowerCase() === 'true'; };
converters[RegExp] = function(value) { return new RegExp(value); };

scope.options = {};
return {
load: function(directive, scope, attrs, options) {
scope.options = {};

angular.forEach(options, function(value, key) {
var interpolatedValue = attrs[key] && $interpolate(attrs[key])(scope.$parent),
converter = converters[options[key].type];
angular.forEach(options, function(value, key) {
var interpolatedValue = attrs[key] && $interpolate(attrs[key])(scope.$parent),
converter = converters[value[0]],
getDefault = function(key) { return globalDefaults[directive] ? globalDefaults[directive][key] : value[1]; };

scope.options[key] = interpolatedValue ? converter(interpolatedValue) : options[key].defaultValue;
});
scope.options[key] = interpolatedValue ? converter(interpolatedValue) : getDefault(key);
});
}
};
};
});
3 changes: 3 additions & 0 deletions src/init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
'use strict';

var tagsInput = angular.module('ngTagsInput', []);
36 changes: 17 additions & 19 deletions src/tags-input.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
'use strict';

var tagsInput = angular.module('ngTagsInput', []);

/**
* @ngdoc directive
* @name tagsInput.directive:tagsInput
Expand Down Expand Up @@ -30,7 +28,7 @@ var tagsInput = angular.module('ngTagsInput', []);
* @param {expression} onTagAdded Expression to evaluate upon adding a new tag. The new tag is available as $tag.
* @param {expression} onTagRemoved Expression to evaluate upon removing an existing tag. The removed tag is available as $tag.
*/
tagsInput.directive('tagsInput', function($timeout, $document, tiConfiguration) {
tagsInput.directive('tagsInput', function($timeout, $document, tagsInputConfig) {
function SimplePubSub() {
var events = {};

Expand Down Expand Up @@ -63,22 +61,22 @@ tagsInput.directive('tagsInput', function($timeout, $document, tiConfiguration)
controller: function($scope, $attrs, $element) {
var shouldRemoveLastTag;

tiConfiguration.load($scope, $attrs, {
customClass: { type: String, defaultValue: '' },
placeholder: { type: String, defaultValue: 'Add a tag' },
tabindex: { type: Number },
removeTagSymbol: { type: String, defaultValue: String.fromCharCode(215) },
replaceSpacesWithDashes: { type: Boolean, defaultValue: true },
minLength: { type: Number, defaultValue: 3 },
maxLength: { type: Number },
addOnEnter: { type: Boolean, defaultValue: true },
addOnSpace: { type: Boolean, defaultValue: false },
addOnComma: { type: Boolean, defaultValue: true },
addOnBlur: { type: Boolean, defaultValue: true },
allowedTagsPattern: { type: RegExp, defaultValue: /^[a-zA-Z0-9\s]+$/ },
enableEditingLastTag: { type: Boolean, defaultValue: false },
minTags: { type: Number },
maxTags: { type: Number }
tagsInputConfig.load('tagsInput', $scope, $attrs, {
customClass: [String],
placeholder: [String, 'Add a tag'],
tabindex: [Number],
removeTagSymbol: [String, String.fromCharCode(215)],
replaceSpacesWithDashes: [Boolean, true],
minLength: [Number, 3],
maxLength: [Number],
addOnEnter: [Boolean, true],
addOnSpace: [Boolean, false],
addOnComma: [Boolean, true],
addOnBlur: [Boolean, true],
allowedTagsPattern: [RegExp, /^[a-zA-Z0-9\s]+$/],
enableEditingLastTag: [Boolean, false],
minTags: [Number],
maxTags: [Number]
});

$scope.events = new SimplePubSub();
Expand Down
68 changes: 0 additions & 68 deletions test/auto-complete.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -590,23 +590,6 @@ describe('autocomplete-directive', function() {
expect(isolateScope.options.debounceDelay).toBe(100);
});

it('sets the option given a static string', function() {
// Arrange/Act
compile('debounce-delay="1000"');

// Assert
expect(isolateScope.options.debounceDelay).toBe(1000);
});

it('sets the option given an interpolated string', function() {
// Arrange/Act
$scope.value = 1000;
compile('debounce-delay="{{ value }}"');

// Assert
expect(isolateScope.options.debounceDelay).toBe(1000);
});

it('doesn\'t call the load function immediately', function() {
// Arrange
compile('debounce-delay="100"');
Expand Down Expand Up @@ -658,23 +641,6 @@ describe('autocomplete-directive', function() {
expect(isolateScope.options.minLength).toBe(3);
});

it('sets the option given a static string', function() {
// Arrange/Act
compile('min-length="5"');

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

it('sets the option given an interpolated string', function() {
// Arrange/Act
$scope.value = 5;
compile('min-length="{{ value }}"');

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

it('calls the load function only after the minimum amount of characters has been entered', function() {
// Arrange
compile('min-length="3"');
Expand Down Expand Up @@ -727,23 +693,6 @@ describe('autocomplete-directive', function() {
expect(isolateScope.options.highlightMatchedText).toBe(true);
});

it('sets the option given a static string', function() {
// Arrange/Act
compile('highlight-matched-text="false"');

// Assert
expect(isolateScope.options.highlightMatchedText).toBe(false);
});

it('sets the option given an interpolated string', function() {
// Arrange/Act
$scope.value = false;
compile('highlight-matched-text="{{ value }}"');

// Assert
expect(isolateScope.options.highlightMatchedText).toBe(false);
});

it('highlights the matched text in the suggestions list', function() {
// Arrange
compile('highlight-matched-text="true"', 'min-length="1"');
Expand Down Expand Up @@ -808,23 +757,6 @@ describe('autocomplete-directive', function() {
expect(isolateScope.options.maxResultsToShow).toBe(10);
});

it('sets the option given a static string', function() {
// Arrange/Act
compile('max-results-to-show="5"');

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

it('sets the option given an interpolated string', function() {
// Arrange/Act
$scope.value = 5;
compile('max-results-to-show="{{ value }}"');

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

it('limits the number of results to be displayed at a time', function() {
// Arrange
compile('max-results-to-show="3"');
Expand Down
Loading

0 comments on commit e48be11

Please sign in to comment.