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

Commit

Permalink
feat(configProvider): Make options optionally data-bound
Browse files Browse the repository at this point in the history
Make all options from both tagsInput and autoComplete directives optionally
data-bound. Introduce a new method, setActiveInterpolation, on
tagsInputConfigurationProvider so one can set which options should have
interpolation active at all times.

Closes #73.
  • Loading branch information
mbenford committed Mar 26, 2014
1 parent 90f075c commit 390380b
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 16 deletions.
51 changes: 41 additions & 10 deletions src/configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
* @name tagsInput.service:tagsInputConfig
*
* @description
* Sets global default configuration options for tagsInput and autoComplete directives. It's also used internally to parse and
* Sets global configuration settings for both tagsInput and autoComplete directives. It's also used internally to parse and
* initialize options from HTML attributes.
*/
tagsInput.provider('tagsInputConfig', function() {
var globalDefaults = {};
var globalDefaults = {}, interpolationStatus = {};

/**
* @ngdoc method
Expand All @@ -27,6 +27,22 @@ tagsInput.provider('tagsInputConfig', function() {
return this;
};

/***
* @ngdoc method
* @name setActiveInterpolation
* @description Sets active interpolation for a set of options.
* @methodOf tagsInput.service:tagsInputConfig
*
* @param {string} directive Name of the directive to be configured. Must be either 'tagsInput' or 'autoComplete'.
* @param {object} options Object containing which options should have interpolation turned on at all times.
*
* @returns {object} The service itself for chaining purposes.
*/
this.setActiveInterpolation = function(directive, options) {
interpolationStatus[directive] = options;
return this;
};

this.$get = function($interpolate) {
var converters = {};
converters[String] = function(value) { return value; };
Expand All @@ -39,14 +55,29 @@ tagsInput.provider('tagsInputConfig', function() {
scope.options = {};

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

scope.options[key] = interpolatedValue ? converter(interpolatedValue) : getDefault(key);
var type, localDefault, converter, getDefault, updateValue;

type = value[0];
localDefault = value[1];
converter = converters[type];

getDefault = function() {
var globalValue = globalDefaults[directive] && globalDefaults[directive][key];
return angular.isDefined(globalValue) ? globalValue : localDefault;
};

updateValue = function(value) {
scope.options[key] = value ? converter(value) : getDefault();
};

if (interpolationStatus[directive] && interpolationStatus[directive][key]) {
attrs.$observe(key, function(value) {
updateValue(value);
});
}
else {
updateValue(attrs[key] && $interpolate(attrs[key])(scope.$parent));
}
});
}
};
Expand Down
36 changes: 36 additions & 0 deletions test/configuration.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,41 @@ describe('configuration service', function() {
});
});

it('loads interpolated values from attributes as they change', function() {
// Arrange
provider.setActiveInterpolation('foo', { prop2: true, prop4: true });

$scope.$parent.prop1 = 'barfoo';
$scope.$parent.prop3 = false;

attrs.prop1 = '{{ prop1 }}';
attrs.prop3 = '{{ prop3 }}';

var callbacks = [];
attrs.$observe = jasmine.createSpy().and.callFake(function(name, cb) {
callbacks.push(cb);
});

// Act
service.load('foo', $scope, attrs, {
prop1: [String],
prop2: [Number],
prop3: [Boolean],
prop4: [RegExp, /.*/]
});

callbacks[0](42);
callbacks[1](null);

// Assert
expect($scope.options).toEqual({
prop1: 'barfoo',
prop2: 42,
prop3: false,
prop4: /.*/
});
});

it('loads default values when attributes are missing', function() {
// Act
service.load('foo', $scope, attrs, {
Expand Down Expand Up @@ -146,5 +181,6 @@ describe('configuration service', function() {

it('returns the same object so calls can be chained', function() {
expect(provider.setDefaults('foo', {})).toBe(provider);
expect(provider.setActiveInterpolation('foo', {})).toBe(provider);
});
});
20 changes: 14 additions & 6 deletions test/test-page.html
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,12 @@
</tags-input>
<form name="form">
<tags-input name="tags" ng-init="tags2=['item1', 'item2', 'item3']" ng-model="tags2" display-property="label"
add-on-enter="{{addOnEnter}}"
add-on-blur="true"
placeholder="Add a superhero"
placeholder="{{placeholder}}"
remove-tag-symbol="{{removeTagSymbol}}"
max-length="5"
add-from-autocomplete-only="true">
add-from-autocomplete-only="false">
<auto-complete source="loadItems2($query)"
debounce-delay="0"
min-length="1"
Expand All @@ -70,8 +72,9 @@
<p>Errors: {{form.tags.$error}}</p>
</form>

<input type="text"/>
<input type="text"/>
<input type="text" ng-model="placeholder"/><span>{{placeholder}}</span>
<input type="text" ng-model="removeTagSymbol"/>
<input type="checkbox" ng-model="addOnEnter"/><span>{{addOnEnter}}</span>

<script type="text/javascript">
angular.module('app', ['ngTagsInput'])
Expand All @@ -89,7 +92,7 @@
];

$scope.tags = [{ text: 'Batman' }, { text: 'Superman' }, { text:'Flash' }];
$scope.placeholder = {value: "New tag" };
$scope.placeholder = 'New tag';
$scope.loadItems = function(query) {
console.log(query);
var deferred = $q.defer();
Expand Down Expand Up @@ -128,10 +131,15 @@
.config(function(tagsInputConfigProvider) {
tagsInputConfigProvider
.setDefaults('tagsInput', {
placeholder: ''
placeholder: 'New tag'
})
.setDefaults('autoComplete', {
highlightMatchedText: true
})
.setActiveInterpolation('tagsInput', {
placeholder: true,
removeTagSymbol: true,
addOnEnter: true
});
});
</script>
Expand Down

0 comments on commit 390380b

Please sign in to comment.