Skip to content

fix(datepicker): notify cva for any input change #13474

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

alexluecke
Copy link

fixes #13410

@alexluecke alexluecke requested a review from mmalerba as a code owner October 6, 2018 23:16
@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Oct 6, 2018
this._valueChange.emit(date);
this.dateInput.emit(new MatDatepickerInputEvent(this, this._elementRef.nativeElement));
}

this._cvaOnChange(date);
Copy link
Contributor

Choose a reason for hiding this comment

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

We probably want to call _cvaOnChange before emitting. How about doing it like this:

this._value = date;
this._cvaOnChange(date);

if (!this._dateAdapter.sameDate(date, this._value)) {
  this._valueChange.emit(date);
  this.dateInput.emit(new MatDatepickerInputEvent(this, this._elementRef.nativeElement));
}

Copy link
Author

Choose a reason for hiding this comment

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

Sounds good

Copy link
Author

@alexluecke alexluecke Oct 7, 2018

Choose a reason for hiding this comment

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

Actually, this won't work. You will end up never calling the dateInput output since this._value will always be value date.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, yeah you can just move the check before

const shouldEmit = this._dateAdapter.sameDate(date, this._valie);

@mmalerba mmalerba requested a review from crisbeto October 7, 2018 00:50
@alexluecke alexluecke force-pushed the datepicker-input-event-fix branch 2 times, most recently from d26f52c to 0d4474c Compare October 7, 2018 04:53
Copy link
Member

@crisbeto crisbeto left a comment

Choose a reason for hiding this comment

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

The code looks good, but it definitely needs a unit test, otherwise I can see the issue being reintroduced easily by somebody moving the function call a couple of lines down.

@alexluecke
Copy link
Author

@crisbeto I think in order to correctly emit input change events, it needs to keep track of the input value in the component, and emit when that changes. As is, the code will not notify of input changes when the input value changes (i.e. the user types in a value 'bad' 'bad2', the date input event is not fired). As such, I think we should probably do something like:

...
  private previousInputValue: string = '';
...

 _onInput(value: string): void {
    let date = this._dateAdapter.parse(value, this._dateFormats.parse.dateInput);
    this._lastValueValid = !date || this._dateAdapter.isValid(date);
    date = this._getValidDateOrNull(date);

    const previousValue = this._value;

    this._value = date;
    this._cvaOnChange(date);

    if (!this._dateAdapter.sameDate(date, previousValue)) {
      this._valueChange.emit(date);
    }

    if (value !== this.previousInputValue) {
      this.previousInputValue = value;
      this.dateInput.emit(new MatDatepickerInputEvent(this, this._elementRef.nativeElement));
    }
  }

The reason we need to maintain a input value model on the class is because this._elementRef.nativeElement.value will always contain the current value of the input.

Thoughts?

@mmalerba
Copy link
Contributor

mmalerba commented Oct 7, 2018

@alexluecke I do agree with moving the input event outside of that if, it would be consistent with what a native number input does then when you type a string like 'eee' (https://stackblitz.com/edit/angular-material2-issue-xd5q3g?file=app/app.component.ts). Since this is all happening inside the _onInput method, I think you can just always emit an input event and not have to save the previousInputValue.

@alexluecke
Copy link
Author

@mmalerba the reason I am trying to avoid that is @crisbeto had a specific PR for avoiding that behavior. I actually agree that the input should always emit anytime an input event occurs irrespective of whether or not the input value is actually different. At which time it just seems like we should revert the previous PR changes.

@alexluecke
Copy link
Author

  • with the exception of only emiting new dates when they actually change.

@mmalerba
Copy link
Contributor

mmalerba commented Oct 8, 2018

@crisbeto was there a specific bug you were trying to fix with #10952? It does seem like a native type=number input emits an input event when I mark a character and replace it with the same character. Shouldn't our dateInput event work the same way?

@crisbeto
Copy link
Member

crisbeto commented Oct 8, 2018

I don't remember whether there was a specific bug, but aside the thing I mention in the PR description, there's also a bug on IE where the input event gets fired on init if it has a placeholder. AFAIK if we didn't have the check in place, the input would start off as dirty on IE. I think I had another PR that does more or less the same, but it never ended up getting in because of a presubmit issue.

@alexluecke
Copy link
Author

Could I get some steps to reproduce?

@crisbeto
Copy link
Member

crisbeto commented Oct 9, 2018

You can see it by opening this one IE. It'll trigger an alert when the input event fires. Also here's how we've resolved it for MatAutocomplete: https://github.com/angular/material2/blob/master/src/lib/autocomplete/autocomplete-trigger.ts#L405

@alexluecke alexluecke force-pushed the datepicker-input-event-fix branch 2 times, most recently from a9baacd to 0b1ff90 Compare October 17, 2018 04:57
@alexluecke
Copy link
Author

@crisbeto That link in the comment to https://docs.microsoft.com/en-us/collaborate/connect-redirect seems to no longer be viable. I updated the PR to always emit events except when the input is not the active document element.

@alexluecke alexluecke force-pushed the datepicker-input-event-fix branch from 0b1ff90 to a0108f9 Compare October 17, 2018 05:45
crisbeto
crisbeto previously approved these changes Oct 18, 2018
Copy link
Member

@crisbeto crisbeto left a comment

Choose a reason for hiding this comment

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

LGTM. cc @mmalerba for final approval.

@mmalerba mmalerba added the action: merge The PR is ready for merge by the caretaker label Oct 18, 2018
@ngbot
Copy link

ngbot bot commented Oct 18, 2018

I see that you just added the pr: merge ready label, but the following checks are still failing:
    failure status "continuous-integration/travis-ci/pr" is failing
    pending missing required labels: target: *

If you want your PR to be merged, it has to pass all the CI checks.

If you can't get the PR to a green state due to flakes or broken master, please try rebasing to master and/or restarting the CI job. If that fails and you believe that the issue is not due to your change, please contact the caretaker and ask for help.

@mmalerba mmalerba added the target: patch This PR is targeted for the next patch release label Oct 18, 2018
@mmalerba
Copy link
Contributor

Marking this as target: patch for now, but may have to change to minor if it breaks too many unit tests

@ngbot
Copy link

ngbot bot commented Jan 25, 2019

Hi @alexluecke! This PR has merge conflicts due to recent upstream merges.
Please help to unblock it by resolving these conflicts. Thanks!

@alexluecke alexluecke force-pushed the datepicker-input-event-fix branch from a0108f9 to 5b124bd Compare February 7, 2019 06:39
@alexluecke alexluecke force-pushed the datepicker-input-event-fix branch from 66fe875 to 51f2729 Compare February 7, 2019 06:56
@alexluecke
Copy link
Author

@mmalerba added a few commits after needing to rebase a conflict. Any idea when this is going to get merged?

@mmalerba
Copy link
Contributor

mmalerba commented Feb 8, 2019

We test all PRs against Google's codebase before merging. It looks like this one has several failures that will need to be investigated before it can be merged

@mmalerba mmalerba added aaa and removed aaa labels Apr 25, 2019
@andrewseguin andrewseguin added the P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent label May 30, 2019
@mmalerba mmalerba removed the lgtm label Jul 31, 2020
@andrewseguin andrewseguin removed the cla: yes PR author has agreed to Google's Contributor License Agreement label Dec 29, 2021
@andrewseguin andrewseguin removed the P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent label Mar 28, 2022
@andrewseguin
Copy link
Contributor

Closing since the attached issue appears to be fixed and this has not been rebased for a long time. If you find that this is still an issue, please feel free to re-open it with a new pull request

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker target: patch This PR is targeted for the next patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Moment datepicker input emitting old values of input text when invalid
5 participants