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

Commit

Permalink
fix(tagsInput): Fix display of non-string items
Browse files Browse the repository at this point in the history
Fix getDisplayText() function in both tagsInput and autoComplete
directives so that non-string items are correctly displayed.

Closes #150
  • Loading branch information
mbenford committed Jun 21, 2014
1 parent 6bc7894 commit 4973492
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 6 deletions.
1 change: 1 addition & 0 deletions .jshintrc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"SimplePubSub": true,
"makeObjectArray": true,
"findInObjectArray": true,
"safeToString": true,
"replaceAll" : true,
"KEYS": true,
"generateArray": true,
Expand Down
12 changes: 8 additions & 4 deletions src/auto-complete.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ tagsInput.directive('autoComplete', function($document, $timeout, $sce, tagsInpu
templateUrl: 'ngTagsInput/auto-complete.html',
link: function(scope, element, attrs, tagsInputCtrl) {
var hotkeys = [KEYS.enter, KEYS.tab, KEYS.escape, KEYS.up, KEYS.down],
suggestionList, tagsInput, options, getItemText, documentClick;
suggestionList, tagsInput, options, getItem, getDisplayText, documentClick;

tagsInputConfig.load('autoComplete', scope, attrs, {
debounceDelay: [Number, 100],
Expand All @@ -126,10 +126,14 @@ tagsInput.directive('autoComplete', function($document, $timeout, $sce, tagsInpu

suggestionList = new SuggestionList(scope.source, options);

getItemText = function(item) {
getItem = function(item) {
return item[options.tagsInput.displayProperty];
};

getDisplayText = function(item) {
return safeToString(getItem(item));
};

scope.suggestionList = suggestionList;

scope.addSuggestion = function() {
Expand All @@ -146,7 +150,7 @@ tagsInput.directive('autoComplete', function($document, $timeout, $sce, tagsInpu
};

scope.highlight = function(item) {
var text = getItemText(item);
var text = getDisplayText(item);
text = encodeHTML(text);
if (options.highlightMatchedText) {
text = replaceAll(text, encodeHTML(suggestionList.query), '<em>$&</em>');
Expand All @@ -155,7 +159,7 @@ tagsInput.directive('autoComplete', function($document, $timeout, $sce, tagsInpu
};

scope.track = function(item) {
return getItemText(item);
return getItem(item);
};

tagsInput
Expand Down
2 changes: 1 addition & 1 deletion src/tags-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ tagsInput.directive('tagsInput', function($timeout, $document, tagsInputConfig)
scope.newTag = { text: '', invalid: null };

scope.getDisplayText = function(tag) {
return tag[options.displayProperty].trim();
return safeToString(tag[options.displayProperty]);
};

scope.track = function(tag) {
Expand Down
6 changes: 5 additions & 1 deletion src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function findInObjectArray(array, obj, key) {
for (var i = 0; i < array.length; i++) {
// I'm aware of the internationalization issues regarding toLowerCase()
// but I couldn't come up with a better solution right now
if (array[i][key].toLowerCase() === obj[key].toLowerCase()) {
if (safeToString(array[i][key]).toLowerCase() === safeToString(obj[key]).toLowerCase()) {
item = array[i];
break;
}
Expand All @@ -48,4 +48,8 @@ function findInObjectArray(array, obj, key) {
function replaceAll(str, substr, newSubstr) {
var expression = substr.replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');
return str.replace(new RegExp(expression, 'gi'), newSubstr);
}

function safeToString(value) {
return angular.isUndefined(value) || value == null ? '' : value.toString().trim();
}
23 changes: 23 additions & 0 deletions test/auto-complete.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,29 @@ describe('autoComplete directive', function() {
expect(getSuggestionText(1)).toBe('Item2');
});

it('renders all elements returned by the load function that aren\'t already added (non-string items)', function() {
// Act
tagsInput.getTags.and.returnValue([{ text: '1' }]);
loadSuggestions({
data: [
{ text: 1 },
{ text: 1.5 },
{ text: true },
{ text: {} },
{ text: null },
{ text: undefined }
]
});

// Assert
expect(getSuggestions().length).toBe(5);
expect(getSuggestionText(0)).toBe('1.5');
expect(getSuggestionText(1)).toBe('true');
expect(getSuggestionText(2)).toBe('[object Object]');
expect(getSuggestionText(3)).toBe('');
expect(getSuggestionText(4)).toBe('');
});

it('shows the suggestions list when there are items to show', function() {
// Act
loadSuggestions(1);
Expand Down
24 changes: 24 additions & 0 deletions test/tags-input.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,30 @@ describe('tags-input directive', function() {
expect(getTagText(2)).toBe('Tag3');
});

it('renders the correct number of tags (non-string items)', function() {
// Arrange
$scope.tags = [
{ text: 1 },
{ text: true },
{ text: 1.5 },
{ text: {} },
{ text: null },
{ text: undefined }
];

// Act
compile();

// Assert
expect(getTags().length).toBe(6);
expect(getTagText(0)).toBe('1');
expect(getTagText(1)).toBe('true');
expect(getTagText(2)).toBe('1.5');
expect(getTagText(3)).toBe('[object Object]');
expect(getTagText(4)).toBe('');
expect(getTagText(5)).toBe('');
});

it('updates the model', function() {
// Arrange
compile();
Expand Down

0 comments on commit 4973492

Please sign in to comment.