Skip to content
This repository was archived by the owner on May 29, 2019. It is now read-only.

Commit ccaa627

Browse files
committed
fix(typeahead): add support for ngModelOptions getterSetter
- Add support for getterSetter with ngModelOptions Closes #3865 Fixes #3823
1 parent 56bdb1c commit ccaa627

File tree

2 files changed

+29
-5
lines changed

2 files changed

+29
-5
lines changed

src/typeahead/test/typeahead.spec.js

+13
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,19 @@ describe('typeahead tests', function() {
809809

810810
expect($scope.test.typeahead.$error.parse).toBeUndefined();
811811
});
812+
813+
it('issue #3823 - should support ng-model-options getterSetter', function() {
814+
function resultSetter(state) {
815+
return state;
816+
}
817+
$scope.result = resultSetter;
818+
var element = prepareInputEl('<div><input name="typeahead" ng-model="result" ng-model-options="{getterSetter: true}" typeahead="state as state.name for state in states | filter:$viewValue" typeahead-editable="false"></div>');
819+
820+
changeInputValueTo(element, 'Alaska');
821+
triggerKeyDown(element, 13);
822+
823+
expect($scope.result).toBe(resultSetter);
824+
});
812825
});
813826

814827
describe('input formatting', function() {

src/typeahead/typeahead.js

+16-5
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
3434
var eventDebounceTime = 200;
3535

3636
return {
37-
require: 'ngModel',
38-
link: function(originalScope, element, attrs, modelCtrl) {
37+
require: ['ngModel', '^?ngModelOptions'],
38+
link: function(originalScope, element, attrs, ctrls) {
39+
var modelCtrl = ctrls[0];
40+
var ngModelOptions = ctrls[1];
3941
//SUPPORTED ATTRIBUTES (OPTIONS)
4042

4143
//minimal no of characters that needs to be entered before typeahead kicks-in
@@ -74,7 +76,16 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
7476
//INTERNAL VARIABLES
7577

7678
//model setter executed upon match selection
77-
var $setModelValue = $parse(attrs.ngModel).assign;
79+
var parsedModel = $parse(attrs.ngModel);
80+
var invokeModelSetter = $parse(attrs.ngModel + '($$$p)');
81+
var $setModelValue = function(scope, newValue) {
82+
if (angular.isFunction(parsedModel(originalScope)) &&
83+
ngModelOptions && ngModelOptions.$options && ngModelOptions.$options.getterSetter) {
84+
return invokeModelSetter(scope, {$$$p: newValue});
85+
} else {
86+
return parsedModel.assign(scope, newValue);
87+
}
88+
};
7889

7990
//expressions used by typeahead
8091
var parserResult = typeaheadParser.parse(attrs.typeahead);
@@ -89,8 +100,8 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
89100
//create a child scope for the typeahead directive so we are not polluting original scope
90101
//with typeahead-specific data (matches, query etc.)
91102
var scope = originalScope.$new();
92-
var offDestroy = originalScope.$on('$destroy', function(){
93-
scope.$destroy();
103+
var offDestroy = originalScope.$on('$destroy', function() {
104+
scope.$destroy();
94105
});
95106
scope.$on('$destroy', offDestroy);
96107

0 commit comments

Comments
 (0)