angular / material

Material design for AngularJS
https://material.angularjs.org/
MIT License
16.55k stars 3.39k forks source link

md-autocomplete: unable to click/focus on anything after a click on the "clear" button #3287

Closed jgoux closed 9 years ago

jgoux commented 9 years ago

Steps to reproduce the bug :

I'm on the master and my browser is Chrome v43

tbock commented 8 years ago

Same issue of browser tab looking like its stuck when using $state.go() inside callback of md-selected-item-change. The $timeout fix worked for me as well. The strange thing is that I'm doing this ($state.go() inside the callback) in a different state in the same site without ill effect. Using version 1.0.5 and Chrome version 48.0.2564.116.

TroodoNmike commented 8 years ago

Still bug in my version 1.0.5 (chrome). When I have autocomplete in dialog, I clear result, select new one, after dialog is minimised/closed it freezes chrome by adding overlay mask.

Work our is adding angular.element('.md-scroll-mask').hide();

$mdDialog.finally(function() {
    angular.element('.md-scroll-mask').hide();
});
TroodoNmike commented 8 years ago

I have also noticed that when bug occurs the scroll on the body is frozen as well (body element position is set to fixed, and its not removed when dialog is closed). As a workaround apart from removing md-scroll-mask I am setting position: inherit on the body element.

TroodoNmike commented 8 years ago

last update from me. I now use a cleaner way for this bug. Angular material provides service called $mdUtil and I when my dialog closes I run $mdUtil.enableScrolling();

Datcam commented 8 years ago

Hello! I have one question about md-autocomplete. Anybody can say me how to click on this button(cross) by my own script ?? I do not have success. I mean that: var button = document.querySelector('md-autocomplete button'); buttons.onclick();

Antariano commented 8 years ago

Also seeing this on 1.0.5. I have an md-autocmplete inside an ng-if. Toggling the ng-if does not remove the .md-scroll-mask

Kasahs commented 8 years ago

+1 seeing this in 1.0.6 when used inside md-chips and location changes when chips are added or removed but the mask remains on location change blocking all user interaction. Changing location after digest cycle completes (i.e is wrapping it in $timeout(fn , 0) solves this. IMO this should not be necessary as this is simply related to focusing the element.

S8nsick66 commented 8 years ago

+1 seeing this in 1.0.6 with $state.go. The fix from @vshanbha fixes the problem with not being able to click on anything on the page BUT I have an md-autocomplete on the page I navigate to and the autocomplete results are not visible.

reachlakstar commented 8 years ago

@vshanbha fixes the problem, when i search again the autocomplete, i lose the drop down ... like @S8nsick66 commented

vshanbha commented 8 years ago

@S8nsick66 , @lakstap Have you checked the comment from @jinyangzhen . Quoting it here. "in my case, the dropdown of md-autocomplete is gone after the state transition. I have to asyn the $state.go in timeout block in order to workaround this issue." Hope this helps.

S8nsick66 commented 8 years ago

Thank you @vshanbha, that works.

setTimeout(
    function(){
        $state.go(state.url, state.params, {
            location: true,
            reload: true,
            inherit: true
        })
    }, 50);

This was my first attempt, it works too.

var url = $state.href(state.name, state.params, {absolute: true});
$window.location.href = url;
mzaarour commented 8 years ago

+1 This happen 1- when you open an element such as auto complete element (can be date picker), 2- then the scroll of the container disapear, which is, i think the "normal" behaviour of the element. 3- Event occurs to hide the element (ie with ng-if which delete it to the dom) before it finishes it closes, the element won't have time to put newer the scroll

Result ==> the app freezes, should refresh the page to make it work again

Hope this can help fix the problem

mzaarour commented 8 years ago

Temp solution : Put this lines into your function which hide the md-autocomplete

//Patch for autocomplete which doesn't remove
angular.element('body')[0].style = '';
if(angular.element('.md-scroll-mask')[0])
    angular.element('.md-scroll-mask')[0].remove();
leibale commented 8 years ago

what about this?

uocnb commented 8 years ago

Got same problem with smDateTimeRangePicker, tried to remove .md-scroll-mask already but it back after open and close another menu 2 or 3 times.

Tried with versions: 1.0.9, 1.0.10, 1.1.1

jlamarr22 commented 8 years ago

What about just hiding the button with css? Seems to be working properly without it there and then you can create a custom button to set the value of the autocomplete back to blank.

md-autocomplete-wrap button[ng-click="$mdAutocompleteCtrl.clear($event)"] { display:none; }

jithureddy commented 7 years ago

Looks like this issue fixed in latest version of angular material for desktops but not for touch devices

10521. How to handle this

madchops1 commented 7 years ago

Where we at with this?

orenagiv commented 7 years ago

I'm using v1.1.4 and I can reproduce this on Safari as well as Chrome (with or without the floating label). On Chrome is causes a double click on the clear-button to release the suggestions container and then clear the search text. On Safari the clear-button does not work at all, unless md-scroll-mask is out of the way.

Workaround - using CSS:

.md-scroll-mask {z-index:0!important}
frame commented 6 years ago

I found the culprit: After the destruction of the autocomplete instance, its queued promises might still be running in the background. Once the promise gets finally resolved, onResultsRetrieved() gets triggered and inserts partially broken markup: div.md-scroll-mask div.md-visually-hidden and md-virtual-repeat-container all end up under <body>, regardless if the user already blurred the element and moved on.

The often mentioned fix to manually delete .md-scroll-mask after a timeout is just a lucky hit because the async call might run for a long time and onResultsRetrieved() will pollute your markup shortly after.

function onResultsRetrieved(matches) {
  cache[term] = matches;

  // Just cache the results if the request is now outdated.
  // The request becomes outdated, when the new searchText has changed during the result fetching.
  if ((searchText || '') !== ($scope.searchText || '')) {
    return;
  }
  // TODO: Also return if the instance was abandoned or destroyed

  handleResults(matches);
}

The proper fix must detect if the original instance was abandoned or destroyed and return, similar if searchText was empty.

In my case I was able to solve this by simply emptying searchText on cleanup(), however this solution might not apply to everyone that's why I didn't create a PR.

--- angular-material.js
+++ angular-material-clearSearchText.js
@@ -25930,6 +25930,7 @@
    * Removes any events or leftover elements created by this controller
    */
   function cleanup () {
+    $scope.searchText = '';
     if (!ctrl.hidden) {
       $mdUtil.enableScrolling();
     }
Splaktar commented 6 years ago

1.1.5 includes some additional fixes for related issues. https://github.com/angular/material/commit/baa869a contains some of these fixes. It comes from PR https://github.com/angular/material/pull/10821.

If you are seeing issues after 1.1.5, please open a new issue with a CodePen reproduction.