Skip to content
This repository has been archived by the owner on Sep 5, 2024. It is now read-only.

autocomplete: suggestion box not closing on blur #9581

Closed
reppners opened this issue Sep 12, 2016 · 16 comments · Fixed by #11625
Closed

autocomplete: suggestion box not closing on blur #9581

reppners opened this issue Sep 12, 2016 · 16 comments · Fixed by #11625
Assignees
Labels
Milestone

Comments

@reppners
Copy link

Reopening #7419 as suggested by @EladBezalel

Actual Behavior:
Inputs are not blurred when tapping outside of a focussed input element.

The autocomplete suggestion box is not closing when the user taps outside the autocomplete to close the suggestion box without selecting a value.

This only happens on touch devices. Tested on Android/Chrome 52.0.2743.98 and iPhone/Safari 9.

When using the "Done" on iOS keyboard the suggestion box closes.
Hiding the keyboard on Android did not close the suggestion box.

Expected Behavior:
The autocomplete suggestion box should close when the user blurs the control by clicking/touching outside of it.

Additional Info

According to the comments in #7419 it worked in 0.11.4.

The issue might origin from function mouseInputHijacker and a quick-and-dirty fix for the autocomplete may be applying a css rule:

.md-scroll-mask {
  display: none;
}
@devversion
Copy link
Member

Related to the planned gesture improvements - #9362

In meanwhile, disabling the click hijack fixes that issue

$mdGestureProvider.skipClickHijack();

@reppners
Copy link
Author

@devversion Has $mdGestureProvider.skipClickHijack(); any negative side-effects?

@devversion
Copy link
Member

Quote from the source

If hijack clicks is true, we preventDefault any click that wasn't sent by ngMaterial. This is because on older Android & iOS, a false, or 'ghost' click event will be sent ~400ms after a touchend event happens.

The only way to know if this click is real is to prevent any normal click events, and add a flag to events sent by material so we know not to prevent those.

Two exceptions to click events that should be prevented are:

  • click events sent by the keyboard (eg form submit)
  • events that originate from an Ionic app

Basically the Fastclick solution wouldn't be available for older devices anymore.

A very good article about the ghost clicks (and Fastclick)

@devversion devversion self-assigned this Sep 12, 2016
@devversion devversion added the P2: required Issues that must be fixed. label Sep 12, 2016
@clshortfuse
Copy link
Contributor

Possible dupe of #8996

@devversion
Copy link
Member

devversion commented Sep 12, 2016

@clshortfuse Yeah those are kind of the same, but I personally prefer this one, because it includes more information e.g a workaround and why it's happening (also is about the input)

We can close on of both :)

@clshortfuse
Copy link
Contributor

clshortfuse commented Sep 12, 2016

@devversion Yep, I'm tagging gestures to things that will have to be revisited after/with HammerJS.

@clshortfuse
Copy link
Contributor

@devversion I think we can more accurately target devices so click hijacking isn't done on newer devices. It's mix of reading the user agent, browser version and viewport scaling. I have to write it anyway for an app I'm writing. Of this top of my head, Safari Mobile pre-July 2016 need it and Android pre-2013/2014. I can get the exact version numbers later.

@devversion
Copy link
Member

@clshortfuse There is no need for Click hijacking with HammerJS anymore. We should just wait for this and not make any big changes to $mdGesture's yet.

@ThomasBurleson ThomasBurleson modified the milestones: 1.2.0, - Backlog Oct 27, 2016
@devversion
Copy link
Member

Closing this issue into #9362, since it will be solved automatically when HammerJS is used.

@sdawson26
Copy link

sdawson26 commented Jun 5, 2017

I've found a hack that helps me get around this issue on the md-autocomplete suggestion box. This code is shortened to highlight the basics of how I did it:

  1. always use a function to return the items in an array
<md-autocomplete
      md-no-cache="true"
      md-search-text="searchText"
      md-items="i in querySearch(searchText)">
  1. When querySearch gets called in the controller, add an event listener for a click event on .md-scroll-mask, which triggers a blur()
var unFocus = function(){
    document.getElementsByTagName('md-autocomplete-wrap')[0].children[0].blur();
  };

$scope.querySearch = function(q){
    $timeout(function(){
      var mask = document.getElementsByClassName('md-scroll-mask')[0];
      if(mask) mask.addEventListener('click', unFocus, true);
    },250)
   //
   // Return a list of results ....
}

@Splaktar Splaktar changed the title input blur / md-autocomplete suggestion box not closing on outside tap/blur autocomplete: suggestion box not closing on blur Jan 25, 2019
@Splaktar
Copy link
Member

There was no CodePen demo, so I created this one. In this case I called $mdGestureProvider.skipClickHijack(); but it did not help 😞 This is on an iPad with Chrome and iOS 12.1.3.

@Splaktar Splaktar modified the milestones: - Backlog, 1.1.13 Jan 25, 2019
@Splaktar
Copy link
Member

I tried the CSS from the OP to hide the md-scroll-mask but that doesn't appear to help either.

@Splaktar
Copy link
Member

For some reason, on iOS, clicking on the md-scroll-mask causes the autocomplete's input to not get a blur event. On every other platform, a blur event is triggered and handled to provide the proper behavior.

I've looked into adding a click handler on the md-scroll-mask element which will fire a blur event on the element but so far that has been too eager. It often results in the dropdown appearing and then instantly disappearing. I'm investigating further...

@Splaktar
Copy link
Member

OK, so this is caused by iOS Safari not firing blur and click events as you would expect on a desktop browser unless the touched element is a form element. This is due to their custom touch event implementation. In our case, the touched element most usually be a <div class="md-scroll-mask"> which doesn't qualify as a form element and thus Safari will generate no blur or click events.

Angular Material solves this by focusing the input when there is a click outside of the overlay.

AngularJS Material does not have any current way to get access to the input. We may be able to add another argument to $mdUtil.disableScrollAround() to allow passing in the associated form element that should get focus when the md-scroll-mask gets a touchend event.

@Splaktar Splaktar added has: Pull Request A PR has been created to address this issue and removed browser: Android labels Jan 31, 2019
@Splaktar
Copy link
Member

I'm not able to reproduce this issue on recent versions of Chrome for Android.

I've got a PR ready to go that should fix this issue on iOS without any major API changes. It appears that listening on the document.documentElement for click events from the MdAutocompleteCtrl works.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants