@@ -37,24 +37,34 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
3737 require :'ngModel' ,
3838 link :function ( originalScope , element , attrs , modelCtrl ) {
3939
40- var $setModelValue = $parse ( attrs . ngModel ) . assign ;
40+ //SUPPORTED ATTRIBUTES (OPTIONS)
4141
4242 //minimal no of characters that needs to be entered before typeahead kicks-in
4343 var minSearch = originalScope . $eval ( attrs . typeaheadMinLength ) || 1 ;
4444
4545 //minimal wait time after last character typed before typehead kicks-in
4646 var waitTime = originalScope . $eval ( attrs . typeaheadWaitMs ) || 0 ;
4747
48- //expressions used by typeahead
49- var parserResult = typeaheadParser . parse ( attrs . typeahead ) ;
50-
5148 //should it restrict model values to the ones selected from the popup only?
5249 var isEditable = originalScope . $eval ( attrs . typeaheadEditable ) !== false ;
5350
51+ //binding to a variable that indicates if matches are being retrieved asynchronously
5452 var isLoadingSetter = $parse ( attrs . typeaheadLoading ) . assign || angular . noop ;
5553
54+ //a callback executed when a match is selected
5655 var onSelectCallback = $parse ( attrs . typeaheadOnSelect ) ;
5756
57+ var inputFormatter = attrs . typeaheadInputFormatter ? $parse ( attrs . typeaheadInputFormatter ) : undefined ;
58+
59+ //INTERNAL VARIABLES
60+
61+ //model setter executed upon match selection
62+ var $setModelValue = $parse ( attrs . ngModel ) . assign ;
63+
64+ //expressions used by typeahead
65+ var parserResult = typeaheadParser . parse ( attrs . typeahead ) ;
66+
67+
5868 //pop-up element used to display matches
5969 var popUpEl = angular . element ( '<typeahead-popup></typeahead-popup>' ) ;
6070 popUpEl . attr ( {
@@ -147,16 +157,25 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
147157 } ) ;
148158
149159 modelCtrl . $formatters . push ( function ( modelValue ) {
160+
150161 var candidateViewValue , emptyViewValue ;
151162 var locals = { } ;
152- locals [ parserResult . itemName ] = modelValue ;
153163
154- //it might happen that we don't have enough info to properly render input value
155- //we need to check for this
156- candidateViewValue = parserResult . viewMapper ( originalScope , locals ) ;
157- emptyViewValue = parserResult . viewMapper ( originalScope , { } ) ;
164+ if ( inputFormatter ) {
158165
159- return candidateViewValue !== emptyViewValue ? candidateViewValue : modelValue ;
166+ locals [ '$model' ] = modelValue ;
167+ return inputFormatter ( originalScope , locals ) ;
168+
169+ } else {
170+ locals [ parserResult . itemName ] = modelValue ;
171+
172+ //it might happen that we don't have enough info to properly render input value
173+ //we need to check for this situation and simply return model value if we can't apply custom formatting
174+ candidateViewValue = parserResult . viewMapper ( originalScope , locals ) ;
175+ emptyViewValue = parserResult . viewMapper ( originalScope , { } ) ;
176+
177+ return candidateViewValue !== emptyViewValue ? candidateViewValue : modelValue ;
178+ }
160179 } ) ;
161180
162181 scope . select = function ( activeIdx ) {
0 commit comments