Reputation: 11221
I've created a text input with some suggestions appearing while typing (just like on Google - you are writing something and it suggests you some text).
<input id="smartBar" ng-focus="showSuggestions=true" ng-blur="showSuggestions=false" ng-model="smartBar" ng-keydown="smartBarKeyDown($event)" focus-on="smartBar" />
<table class="suggestionList" ng-show="showSuggestions">
<tr ng-repeat="sg in suggestions" ng-class="{highlighedSuggestion: $index == highlightedSuggestion}" ng-click="suggestionClicked($index)">
<td ng-repeat="nt in sg.NoteTags" style="padding: 0rem 1rem">
{{nt.Tag.Name}}
</td>
</tr>
</table>
I want to add possibility to click on one of "suggestions" (there is ng-click attribute in < TR> html attribute). Unfortunately, ng-blur seems to work earlier than ng-click, so when I click on one of options, input loses focus and suggestionList becomes invisible before click is detected.
How can I detect click before hiding suggestionList?
Upvotes: 4
Views: 2488
Reputation: 3637
Had exactly the same problem while developing my own autocomplete dropdown list. Both $timeout and ng-mousedown solutions were too dirty for me and had negative UX side-effects. This is what I figured out eventually:
var suppressInputFocusedChange = false;
$scope.onBlur = function() {
if(suppressInputFocusedChange === true) {
suppressInputFocusedChange = false;
return false;
}
$scope.showSuggestions = false;
};
$scope.onFocus = function() {
$scope.showSuggestions = true;
};
$scope.suggestionMouseDown = function() {
suppressInputFocusedChange = true;
};
$scope.suggestionClicked = function() {
$scope.showSuggestions = false;
};
So basically, when you start to click on the item (ng-mousedown) you set the suppressInputFocusedChange flag to true. When this flag is up 'onBlur' method will do nothing and the list will be hidden by the suggestionClicked method.
Upvotes: 1
Reputation: 48968
One of your options is use a $timeout
to delay the removal of the suggestion list, and $cancel
the timeout from the click event.
var suggestionTimeout = $timeout(angular.noop);
function setSuggestionFalse = function() {
vm.showSuggestions = false;
};
vm.onSmartBarBlur = function () {
//delay the removal
suggestionTimeout = $timeout(setSuggestionFalse, 50);
};
vm.onSuggestionClick = function () {
//cancel the removal
$timeout.cancel(suggestionTimeout);
//show suggestion
};
For more information in $timeout see the AngularJS $timeout API Reference.
Upvotes: 0
Reputation: 8971
You cannot. However, you can use ngMousedown
instead of ngClick
to achieve the desired functionality:
HTML:
ng-mousedown="suggestionClicked($index, $event)
JS:
$scope.suggestionClicked = function(index, evt) {
//detect left click
if(evt.which === 1) {
//your code
}
}
Upvotes: 2