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

Commit f84cf2b

Browse files
author
miiihi
committed
feat(typeahead): access to $item in typeahead-input-formatter and item resolver
1 parent b4832c4 commit f84cf2b

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

src/typeahead/typeahead.js

+45-2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
6161

6262
var focusFirst = originalScope.$eval(attrs.typeaheadFocusFirst) !== false;
6363

64+
// a callback executed on initialization and on setting model value programatically, called with modelValue and should return item object or promise of it
65+
var resolveItemCallback = attrs.typeaheadResolveItem ? $parse(attrs.typeaheadResolveItem) : undefined;
66+
6467
//INTERNAL VARIABLES
6568

6669
//model setter executed upon match selection
@@ -172,6 +175,38 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
172175
//we need to propagate user's query so we can higlight matches
173176
scope.query = undefined;
174177

178+
//we need last item to be available in formatters
179+
scope.lastItem = undefined;
180+
181+
//we need lastModel for sync checking last item
182+
scope.lastModel = undefined;
183+
184+
//resolve item, store it to lastItem and rerun modelCtrl formatters
185+
var getItem = function (modelValue) {
186+
if (!resolveItemCallback) {
187+
return;
188+
}
189+
// call the callback
190+
var itemCallbackResult = resolveItemCallback(originalScope, { $model: modelValue });
191+
// handle result
192+
$q.when(itemCallbackResult).then(function (item) {
193+
// discard results, if model value changed or another selection was made
194+
if (modelValue !== modelCtrl.$modelValue || modelValue !== scope.lastModel) {
195+
return;
196+
}
197+
198+
// store resolved item
199+
scope.lastItem = item;
200+
// and rerun formatters
201+
var viewValue = modelCtrl.$modelValue;
202+
for (var i in modelCtrl.$formatters) {
203+
viewValue = modelCtrl.$formatters[i](viewValue);
204+
}
205+
modelCtrl.$viewValue = viewValue;
206+
modelCtrl.$render();
207+
});
208+
};
209+
175210
//Declare the timeout promise var outside the function scope so that stacked calls can be cancelled later
176211
var timeoutPromise;
177212

@@ -228,6 +263,14 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
228263
if (inputFormatter) {
229264

230265
locals.$model = modelValue;
266+
// if we have correct item, use it in formatter, otherwise, get it...
267+
if (modelValue === scope.lastModel) {
268+
locals.$item = scope.lastItem;
269+
} else {
270+
scope.lastModel = modelValue;
271+
scope.lastItem = undefined;
272+
getItem(modelValue);
273+
}
231274
return inputFormatter(originalScope, locals);
232275

233276
} else {
@@ -248,8 +291,8 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
248291
var locals = {};
249292
var model, item;
250293

251-
locals[parserResult.itemName] = item = scope.matches[activeIdx].model;
252-
model = parserResult.modelMapper(originalScope, locals);
294+
locals[parserResult.itemName] = item = scope.lastItem = scope.matches[activeIdx].model;
295+
model = scope.lastModel = parserResult.modelMapper(originalScope, locals);
253296
$setModelValue(originalScope, model);
254297
modelCtrl.$setValidity('editable', true);
255298

0 commit comments

Comments
 (0)