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

fix(input): re-validate when partially editing date-family inputs #13886

Closed
wants to merge 1 commit into from

Conversation

jbedard
Copy link
Contributor

@jbedard jbedard commented Jan 29, 2016

This checks for changes to the badInput/typeMismatch validity flags on keydown/wheel/mousedown events to try to mark date-like inputs as $dirty when they have been partially entered but are still incomplete/invalid.

This has a couple advantages/disadvantages compared to #12902 explained at #12902 (comment).

Fixes #12207

var validity = this[VALIDITY_STATE_PROPERTY] || {};
var origBadInput = validity.badInput;
var origTypeMismatch = validity.typeMismatch;
timeout = $browser.defer(function() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the timeout for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a keydown event fires the input has not yet changed. This might not be necessary for the other PARTIAL_VALIDATION_EVENTS though. The other option is using keyup but then changes won't be detected if the key is held for a while. Basically the same logic used for the no-input-event case (IE).

@Narretz
Copy link
Contributor

Narretz commented Jan 29, 2016

Definitely simpler.
But I don't particularly like that we move validation logic into the inout. Makes it more compley than it already is.
The $dirty problem could also be solved by calling $setDirty in the new event listener, though.

@jbedard
Copy link
Contributor Author

jbedard commented Jan 29, 2016

That is a good point... but I think this is still more change detection then validation logic, it just happens to detect those changes using the validity state.

@gkalpak gkalpak added this to the 1.5.x - upgrade-facilitation milestone Jan 31, 2016
@jbedard
Copy link
Contributor Author

jbedard commented Feb 4, 2016

The tests are currently failing on all the non-chrome browsers. Anyone have an opinion for how to fix that? Just put a giant if (chrome) around them all? :|

@@ -1918,6 +1918,83 @@ describe('input', function() {
});
});

['month', 'week', 'time', 'date', 'datetime-local'].forEach(function(inputType) {
if (jqLite('<input type="' + inputType + '">').attr('type') !== inputType) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fails to detect the supporting browsers. You should use .prop() instead.
The type attribute will always have the requested type, but the type property will be set to text if the browser doesn't support the type.

@gkalpak
Copy link
Member

gkalpak commented Feb 4, 2016

@jbedard, they are expected to fail on browsers that don't support the input type, but the code fails to properly detect support. See https://github.com/angular/angular.js/pull/13886/files#r51847302.

@gkalpak
Copy link
Member

gkalpak commented Feb 4, 2016

BTW, at the moment only Chrome, Opera and Edge support date inputs.

// check for validity changes on various DOM events.
if (PARTIAL_VALIDATION_TYPES[type] && ctrl.$$hasNativeValidators && type === attr.type) {
element.on(PARTIAL_VALIDATION_EVENTS, function(ev) {
if (!timeout) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fact that we are reusing the same timeout with the else brach above, is not good I think.
Since the callbacks are conditionally calling listener, there might be a timeout registered, so we don't register another one, but that other timeout's callback may end up not calling listener (while our callback would).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've had that concern as well for a while now with keydown vs cut/paste events in the IE case (no input event).

But in this case, with current browser date-like input support, I don't think there will be any issues. I don't think there is any browser that will not have the input event but will have native date-like inputs.

I do think this should change at some point though, even if just for the IE case...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. Having separate timeouts would still be "cleaner", but even the shared timeout isn't indeed expected to create any issues.

@gkalpak
Copy link
Member

gkalpak commented Feb 5, 2016

A couple of minor comments (that could be ignored as well) 😃
LGTM otherwise 👍

@gkalpak
Copy link
Member

gkalpak commented Feb 18, 2016

Backported to v1.5.x (e383804) and v1.4.x (02929f8).

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

Successfully merging this pull request may close these issues.

4 participants