Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Error ng-invalid-date whe then user clicks "X" in Chrome #14740

Open
kimx opened this issue Jun 8, 2016 · 8 comments
Open

Error ng-invalid-date whe then user clicks "X" in Chrome #14740

kimx opened this issue Jun 8, 2016 · 8 comments

Comments

@kimx
Copy link

kimx commented Jun 8, 2016

Hi
I found another problem in Chrome.
1.Key in Month or Date or Year.Dot not use choose.
2.Use the "X" to clear the value -->Now $valid=true -->expect
3.Key in Month or Date or Year again.
4.Use the "X" to clear the value -->Now $valid=false -->error

http://plnkr.co/edit/2HPDq0bjzReyuNbvn7vz?p=preview

Reference Issue
#12853 (comment)

@gkalpak

@gkalpak
Copy link
Member

gkalpak commented Jun 10, 2016

Copying some comments over from #12853 for context:


Interesting facts:

  1. When the mousedown event fires (when clicking on the "X"), it sets up a 0-delay timeout to check if the validity of the input has changed. We expect that by the time the timeout is triggered, the input will have changed (i.e. will have been cleared in this case) and the validity will have been restored. It doesn't.
  2. By trial-and-error, I found out that a delay of 150ms is sufficient for the change to be picked up, but this threshold will probably differ based on browser/OS/device.
  3. The first time you click the "X", an input event is also triggered, thus we are able to detect the change properly. This is why your step (2) above works. For whatever reason, the input event is only triggered the first time 😒

Suggestions:

For users: As a workaround, you can trigger an input event after a short timeout on mousedown (demo).

For Chrome: Always trigger an input event, when the user clicks "X".

For us: Not sure. Listening for mouseup (instead of or in addition to mousedown). Adding a small delay (150-200ms). TBH, I don't remember what mousedown event we expect to change the input. Is it only clicking the "X" or are there other usecases that we need to take into account?


/cc @jbedard (who fixed the previous bug)

@jbedard
Copy link
Collaborator

jbedard commented Jun 11, 2016

The mousedown is also for the up/down arrows to increment/decrement part of the date (which changes on mousedown, if you hold the mouse down it continuously increment/decrements it - so I think keeping mousedown is valuable).

If adding mouseup or click to the list of events listened to works then I think that's fine. I think I'd want to avoid a hardcoded delay though.

@Narretz
Copy link
Contributor

Narretz commented Nov 21, 2017

You can also use ngModelOptions with updateOn and debounce to work around this problem:

{
  updateOn: 'mouseup default', 
  debounce: {
    mouseup: 150
  }
}

http://plnkr.co/edit/5aIQq6blCasCDjpjwTig?p=preview

@Narretz
Copy link
Contributor

Narretz commented Nov 21, 2017

Note that the native Firefox date widget (tested in Dev tools) works completely different, too.
If you use the keyboard, it only fires input once you have filled all fields (no partial updates that would make the control invalid)
It also doesn't fire input if you first fill day, then month, then a four digit year - it only fires when you enter a 6 digit year, or if you blur the control. Must be a bug.

@piotr-dobrogost
Copy link

For Chrome: Always trigger an input event, when the user clicks "X".

Changing input's value without triggering input event is clearly a bug in Chrome.
Has anyone raised it? Do we have a number?

@gkalpak
Copy link
Member

gkalpak commented Mar 21, 2018

Theoretically, it is not a bug, because I don't think there any spec about the x button. It is up to the browsers to implement the UI is whatever way they think is best for their users. (For example Firefox has a different behavior.)

And technically the value does not change, because as long as you have only selected a partial date, the input's value property is set to the empty string.

It is a little weird that the event is fired the first time though.

In any case, I don't know if anyone has raised it in Chrome's bug tracker.

@piotr-dobrogost
Copy link

piotr-dobrogost commented Mar 21, 2018

And technically the value does not change, because as long as you have only selected a partial date, the input's value property is set to the empty string.

That's why we are talking about input event not change event here; the value does not change but there was input from user registered.

Btw, validity state (https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) for input's DOM element is being updated correctly after clicking clear button (every time not just on the first click). Could AngularJS update its $valid state on change in validity state instead of trying to enumerate and listen to all events which might result in changing input's value?

@gkalpak
Copy link
Member

gkalpak commented Mar 21, 2018

We do take Validity into account . But how would we know that Validity has changed? We need an event to trigger that check.

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

No branches or pull requests

5 participants