Skip to content

fix(datepicker): add max/min filter to multi year and year views #9727

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

Merged
merged 5 commits into from
Feb 6, 2018
Merged

fix(datepicker): add max/min filter to multi year and year views #9727

merged 5 commits into from
Feb 6, 2018

Conversation

julianobrasil
Copy link
Contributor

Improves the performance when open multi year and year view with max and/or min dates specified.

Closes #9725.

@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Feb 1, 2018
@@ -36,6 +36,8 @@
[activeDate]="_activeDate"
[selected]="selected"
[dateFilter]="_dateFilterForViews"
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you can remove _dateFilterForViews now and just use the date filter that was passed to the calendar

this._dateAdapter.getYear(this.activeDate), month, 1);
const activeYear = this._dateAdapter.getYear(this.activeDate);

let firstOfMonth = this._dateAdapter.createDate(activeYear, month, 1);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: const

return true;
}

_yearAndMonthAfterMin(year: number, month: number) {
Copy link
Contributor

Choose a reason for hiding this comment

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

private

@@ -346,7 +338,7 @@ export class MatCalendar<D> implements AfterContentInit, OnDestroy, OnChanges {
this._dateAdapter.addCalendarMonths(this._activeDate, 1);
break;
case ENTER:
if (this._dateFilterForViews(this._activeDate)) {
if (this.dateFilter(this._activeDate)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

do we need to check the min and max here too? or will we never wind up in that situation?

Copy link
Contributor Author

@julianobrasil julianobrasil Feb 1, 2018

Choose a reason for hiding this comment

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

I'll check it more carefully. I've just replaced it without considering this possibility.

Copy link
Contributor Author

@julianobrasil julianobrasil Feb 2, 2018

Choose a reason for hiding this comment

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

In fact I couldn't imagine a scenario where the user is able to select a disabled date with keyboard.... as soon as I set max and min dates inside <month-view>, and I've just noticed that I forgot to do it. 😳

One option would be keeping the _dateFilterForViews and don't pass maxDate and minDate to <month-view>, but it would be potentially confusing in the future (why only the filters of month-view would be in calendar.ts?) To keep it consistent, all of filtering logic should follow the same rule. So each view has all its filtering logic inside itself.

I can go on the other way if you think it's better: keep all the filtering logic in calendar.ts (and don't pass maxDate and minDate to the views components). Let me know if you prefer this option.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh wait this is coming back to me now, I think what happened is that I allowed people to navigate to disabled dates with the keyboard for the following reason: imagine someone created a date filter that returns date < 1/1/2018, now if I try to arrow forward from 2017 and go to the next enabled date... my application hangs forever. So instead I just made it impossible to select the date if the active date is disabled.

So I think we do need to make sure we somehow check the min and max dates. We should actually be doing it for year and multi-year view too, I think it's a bug that we're currently not. I feel like the way this should work is that the calendar should delegate the keyboard handling to the appropriate view rather than having the code for all of the views hardcoded in the calendar, but its already kind of set up weird, so however you want to make it work is fine...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moving each keyboard handler to its own view would be nice, but it would also add a delay to this PR, so what if we do it in a separate one? I think the performance issue that lead to this PR is really anoying and should be merged ASAP.

Copy link
Contributor

@mmalerba mmalerba Feb 2, 2018

Choose a reason for hiding this comment

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

Edit: ok after looking over the code some more you've convinced me that this is actually right. It looks like dates that are disabled via the date filter can be activated by the keyboard, but dates beyond the min and max can't so this should be safe. And as you pointed out we intentionally allow selecting disabled dates in year/multi-year view, so those ones should be right too. Sorry for the confusion.

Copy link
Contributor Author

@julianobrasil julianobrasil Feb 2, 2018

Choose a reason for hiding this comment

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

We have @Input() allowDisabledSelection in mat-calendar-body. It's used in <year-view> and in <multi-year-view>. We could see whether it can be used in <month-view> too, and get rid of the ENTER key filter logic... in a future PR.

@mmalerba mmalerba added pr: lgtm action: merge The PR is ready for merge by the caretaker target: patch This PR is targeted for the next patch release perf This issue is related to performance labels Feb 2, 2018
@julianobrasil
Copy link
Contributor Author

julianobrasil commented Feb 3, 2018

@mmalerba, I'll start the refactoring that takes each keyboard event handler to inside of the appropriate view. It will be a new PR that I'll start on top of this one.

I likely could finish it and add to this PR, but I prefer to wait for #9678 to be merged before submiting it, because I think the refactoring work is gonna benefit from @Output() yearSelected and @Output() monthSelected.

edit: little mod => I had forgotten to add a protection to an undefined filter. Just fixed.

@mmalerba mmalerba merged commit d062ccb into angular:master Feb 6, 2018
@julianobrasil julianobrasil deleted the slowDateFilter branch February 7, 2018 09:52
mmalerba pushed a commit that referenced this pull request Feb 8, 2018
* add max/min filter to multi year and year views

* address @mmalerba's comments

* fix and tighten up logic

* possibility to have a null filter in month view
@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 8, 2019
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 cla: yes PR author has agreed to Google's Contributor License Agreement perf This issue is related to performance target: patch This PR is targeted for the next patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Datepicker] Opening year view with filter slow
3 participants