Skip to content

Commit

Permalink
Handle selectedObject as object or callback proposed by @nekcih in #6
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiden committed Jun 20, 2014
1 parent 6e85c9e commit 1187518
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 4 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ To see a demo go here: http://ghiden.github.io/angucomplete-alt
* Clear on selection: when you select an item, input field is cleared.
* Blur event handling, thanks to @leejsinclair
* Override suggestions
* You can either bind an object or callback function
* bind an object: it works as regular two-way-data-binding
* callback function: when a selection is made by user, this callback is called with the selected object. Thanks to @nekcih for proposing this feature.

### Getting Started
Download the code, and include the angucomplete-alt.js file in your page. Then add the angucomplete-alt module to your Angular App file, e.g.
Expand Down Expand Up @@ -65,7 +68,7 @@ var app = angular.module('app', ["angucomplete-alt"]);
| id | A unique ID for the field | Yes | members |
| placeholder | Placeholder text for the search field | No | Search members |
| pause | The time to wait (in milliseconds) before searching when the user enters new characters | No | 400 |
| selected-object | Where to store the selected object in your model/controller (like ng-model) | Yes | myObject |
| selected-object | Either an object in your scope or callback function. If you set an object, it will be two-way-bound data as usual. If you set a callback, it gets called when selection is made. | Yes | selectedObject or objectSelectedCallback |
| remote-url | The remote URL to hit to query for results in JSON. angucomplete will automatically append the search string on the end of this, so it must be a GET request | No | http://myserver.com/api/users/find?searchstr= |
| remote-url-data-field | The name of the field in the JSON object returned back that holds the Array of objects to be used for the autocomplete list. | No | results |
| title-field | The name of the field in the JSON objects returned back that should be used for displaying the title in the autocomplete list. Note, if you want to combine fields together, you can comma separate them here (e.g. for a first and last name combined) | Yes | firstName,lastName |
Expand Down
15 changes: 12 additions & 3 deletions angucomplete-alt.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,23 @@ angular.module('angucomplete-alt', [] ).directive('angucompleteAlt', ['$parse',
scope.searching = false;
scope.searchStr = null;

var callOrAssign = function(value) {
if (typeof scope.selectedObject === 'function') {
scope.selectedObject(value);
}
else {
scope.selectedObject = value;
}
};

var returnFunctionOrIdentity = function(fn) {
return fn && typeof fn === 'function' ? fn : function(data) { return data; };
};

var responseFormatter = returnFunctionOrIdentity(scope.remoteUrlResponseFormatter);

var setInputString = function(str) {
scope.selectedObject = {originalObject: str};
callOrAssign({originalObject: str});

if (scope.clearSelected) {
scope.searchStr = null;
Expand Down Expand Up @@ -283,7 +292,7 @@ angular.module('angucomplete-alt', [] ).directive('angucompleteAlt', ['$parse',
else {
scope.searchStr = lastSearchTerm = result.title;
}
scope.selectedObject = result;
callOrAssign(result);
scope.showDropdown = false;
scope.results = [];
};
Expand Down Expand Up @@ -330,7 +339,7 @@ angular.module('angucomplete-alt', [] ).directive('angucompleteAlt', ['$parse',
scope.showDropdown = false;
scope.$apply();
} else if (event.which === KEY_BS || event.which === KEY_DEL) {
scope.selectedObject = null;
callOrAssign(null);
scope.$apply();
}
});
Expand Down
36 changes: 36 additions & 0 deletions test/angucomplete-alt.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -499,4 +499,40 @@ describe('angucomplete-alt', function() {
expect(element.isolateScope().searchStr).toBe(null);
});
});

describe('selectedObject callback', function() {
it('should call selectedObject callback if given', function() {
var element = angular.element('<div angucomplete-alt id="ex1" placeholder="Search countries" selected-object="countrySelected" local-data="countries" search-fields="name" title-field="name" minlength="1"/>');
var selected = false;
$scope.countrySelected = function(value) {
selected = true;
};
$scope.countries = [
{name: 'Afghanistan', code: 'AF'},
{name: 'Aland Islands', code: 'AX'},
{name: 'Albania', code: 'AL'}
];
$compile(element)($scope);
$scope.$digest();

expect(selected).toBe(false);
var inputField = element.find('#ex1_value');
var e = $.Event('keyup');
e.which = 97; // letter: a

inputField.val('a');
inputField.trigger('input');
inputField.trigger(e);
$timeout.flush();
expect(element.find('#ex1_dropdown').length).toBe(1);

e.which = KEY_DW;
inputField.trigger(e);
expect(element.isolateScope().currentIndex).toBe(0);

e.which = KEY_EN;
inputField.trigger(e);
expect(selected).toBe(true);
});
});
});

0 comments on commit 1187518

Please sign in to comment.