I'm using angular-ui typeahead. How can I trigger the popup items when focus on the input box, not after typing.
-
Here is another typeahead module that does it: http://mgcrea.github.io/angular-strap/##typeaheads – aweibell Mar 20 '14 at 11:16
-
...and the question has been asked by others as well: https://github.com/angular-ui/bootstrap/issues/759 – aweibell Mar 20 '14 at 16:02
-
And seems to be resolved there – Dmitri Zaitsev Apr 25 '15 at 09:05
4 Answers
I can attest to the issues associated with expanding the UX of the typeahead. While @ueq's solution works, it has trouble releasing focus/clicking. I suggest changing things, specifically how you trigger the open UX.
suggested changes
- open on double click - this solves the issue of click-releasing in @ueq's answer
- check for existing values so as not to overwrite the value - we don't want to accidentally overwrite existing data when we open, so check first then set to a non-valid value to trigger the open.
- change the name of the directive.... go with something more descriptive - considering that ui.bootstrap has already changed their namespace moving from 13.x to 14.x it just makes sense to go with your own name. Since directives can represent both UI &/or UX, it makes sense to name your directive to something that other developers can later track down more easily.
why
When working with a typeahead, people have certain expectations of the UX. Clicking into an input and having something popup can be somewhat jarring and misdirecting. A single click or tab-focus into an input traditionally does nothing other than readying the input for keyboard interaction. A double click generally carries the expectation that something more will happen (e.g. double click a file & close from a select dialog vs. single click to select, then click "ok" to close).
In programming we often try to employ the separation of concerns paradigm to our code. But I think this could be applied also to this particular UX and UX in general. Let the single-click & tab-focusing do what they've done for years and utilize the double-click to expand the UX of the typeahead.
plunker - http://plnkr.co/edit/GGl6X4klzVLKLX62Itbh?p=preview
.directive('typeaheadClickOpen', function($parse, $timeout) {
return {
restrict: 'A',
require: 'ngModel',
link: function($scope, elem, attrs) {
triggerFunc = function(evt) {
var ctrl = elem.controller('ngModel'),
prev = ctrl.$modelValue || '';
if (prev) {
ctrl.$setViewValue('');
$timeout(function() {
ctrl.$setViewValue(prev);
});
} else {
ctrl.$setViewValue(' ');
}
}
elem.bind('dblclick', triggerFunc);
}
}
})
-
Editing my answer and changing the name of the directive to `typeaheadClickOpen` wouldn't have made that much of a difference... Or am I missing something? – Boern Dec 17 '15 at 18:55
-
the name would not have made a difference functionally speaking I suppose. But you're triggering something on _click_, if you have an existing value, then you're erasing that value on the model. Also, in your plunkr, click anywhere outside of the dropdown once you've selected a value and note that the input value changes. Your _blur_ handler is erasing the value and is unnecessary. – jusopi Dec 17 '15 at 19:16
-
another reason to rename this @ueq is that not all typeaheads serve data on-demand. In many cases a typeahead fetches it's data asynchronously, and by using a different directive name, you can ensure that those that are asynch don't get the same treatment. – jusopi Dec 17 '15 at 19:29
-
thanks for the explanation! +1 :) I'll update my answer as soon as I find time – Boern Dec 17 '15 at 19:32
Hi I had the same issue and with this github discussion I was able to figure it out: Setup a directive that calls $setViewValue
like
.directive('typeahead', function () {
return {
require: 'ngModel',
link: function (scope, element, attr, ctrl) {
element.bind('click', function () {
ctrl.$setViewValue(' ' );
});
element.bind('blur', function () {
ctrl.$setViewValue('');
});
}
};
});
and add it to your input
:
<input type="text" [...] typeahead>
Result (I created a plkr: http://plnkr.co/edit/Si6tFK2AammZy1HqEQzA):
Hope that helps :)

- 7,233
- 5
- 55
- 86
-
The problem with this is that when the input field loses focus and the user focuses on the input field again, it doesn't show the old results, but starts a new search. – Tom Aug 11 '16 at 09:50
-
Use typeahead-min-length="0" if supported by your angular-ui version. Otherwise this will help you out:
directive('typeaheadOpenOnFocus', function ($timeout) {
return {
require: 'ngModel',
link: function (scope, element, attr, ctrl) {
element.bind('click', function () {
var vv = ctrl.$viewValue;
ctrl.$setViewValue(vv ? vv+' ': ' ' );
$timeout(function(){ctrl.$setViewValue(vv ? vv : '');},10)
});
}
};
})
and add typeahead-open-on-focus as attribute to your input element.
This will open the typeahead onfocus if it already has a value too. And it automatically reverts the viewvalue.

- 11
- 2
Inspired by the answer of Boem
You can try this for avoiding the issue of view rendering
app.directive('typeahead', function () {
return {
restrict: "A",
require: 'ngModel',
link: function (scope, element, attr, ctrl) {
element.bind('click', function () {
ctrl.$setViewValue('');
ctrl.$render();
});
}
};});

- 705
- 10
- 12