Skip to content
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

Add public method to MatCalendar to update today's date #11821

Merged
merged 5 commits into from
Jul 18, 2018
Merged

Add public method to MatCalendar to update today's date #11821

merged 5 commits into from
Jul 18, 2018

Conversation

tobiasschweizer
Copy link
Contributor

@tobiasschweizer tobiasschweizer commented Jun 18, 2018

This PR adds a public method to MatCalendar so today's date is updated correctly after an update of the active date. This is necessary when you do calendar format conversions.

see dhlab-basel/JDNConvertibleCalendarDateAdapter#6 (comment)

@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Jun 18, 2018
@tobiasschweizer
Copy link
Contributor Author

@mmalerba I added a test case for this. However, the test does not really make sense because today's date does not actually change. The test would also pass if the method updateTodaysDate was not called at all.

We would have to switch calendar formats so we could check if today's was updated for the currently active calendar format.

calendarInstance.activeDate = newActiveDate;
fixture.detectChanges();

calendarInstance._dateSelected(newActiveDate);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mmalerba Should this method be publicly accessible?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think so, this is only intended to be called when the user clicks on a date to select it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The problem is that the new active date needs to be selected after a calendar format conversion, otherwise it does appear as the new active date. Shall I add a method that takes the new active date as a parameter and takes care of all the necessary updates?

At the moment, the code would look like this:

// convert the active date
const convertedDate = this._dateAdapter.convertCalendarFormat(this._calendar.activeDate, calendar);

// assign the new active date 
this._calendar.activeDate = convertedDate;

// select the new active date
this._calendar._dateSelected(convertedDate);

// update today's date
this._calendar.updateTodaysDate();

Instead, there could be a method like setActiveDate(date: D) that handles all of this:

// convert the active date
const convertedDate = this._dateAdapter.convertCalendarFormat(this._calendar.activeDate, calendar);

// sets the new active date and takes care of all the necessary updates
this._calendar.setActiveDate(convertedDate);

Copy link
Contributor Author

@tobiasschweizer tobiasschweizer Jun 19, 2018

Choose a reason for hiding this comment

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

see https://stackblitz.com/edit/angular-ncyrjg src/app/app.component.ts

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm I could see it making more sense to add the ability to set the selected date on the mat-datepicker, since that's how most developers would probably interact with it. Would that work for your case? You could probably inject the datepicker similar to how you injected the calendar (probably no @Host though, since datepicker is a few levels up)

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know about automatically calling updateTodaysDate, I would leave that up to the user, but adding a public setter for the selected date should be fine.

Setting the activeDate is probably still necessary in your case. You'll want to update both the selected and the active after changing the calendar system.

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 the combined method sounds kind of specific to your use case, not something that other developers would wind up needing that much, so I'd rather keep it separate in material and just have you call the various bits you need from your code

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Probably I did not understand the difference between the selected and the active date:

  • selected date: date that user selects by clicking and is shown in the input field as text
  • active date: date or date range that is currently shown to the user
  • today's date: marks today's date with a circle

So if I get it correctly, the new public setter would just change the selected date, and the user would still have to care about showing it to the user by updating the active date and today's date.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, that does not seem hard to do :-)

How would we write a test for updateTodaysDate? Since we do not do calendar conversions here, today's date stays the same.

Copy link
Contributor

@mmalerba mmalerba Jul 3, 2018

Choose a reason for hiding this comment

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

You could just extend the NativeDateAdapter for the test, maybe call it FakeNativeDateAdapter or something and give it a method to change today's date

Edit: even easier, just inject the NativeDateAdapter in the test and do:

spyOn(adapter, 'today').and.callFake(() => {...})`

@josephperrott josephperrott added the target: minor This PR is targeted for the next minor release label Jun 26, 2018
@mmalerba
Copy link
Contributor

@tobiasschweizer were you able to get the tests working using this method?

@tobiasschweizer
Copy link
Contributor Author

Not yet. I hope I will find some time to do it this or next week.

@@ -340,6 +340,9 @@ export class MatCalendar<D> implements AfterContentInit, AfterViewChecked, OnDes
(this.currentView == 'year' ? this.yearView : this.multiYearView);

view.ngAfterContentInit();

// to be removed once test works
console.log(view._dateAdapter.today());
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mmalerba I am still getting today's date instead of the fake one. Maybe I missed something.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

test output removed in
cb84cbe

@@ -289,6 +289,11 @@ export class MatDatepicker<D> implements OnDestroy, CanColor {
}
}

/** Public method to select a date in the Datepicker */
select(date: D): void {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mmalerba I added a public setter
(#11821 (comment))

Copy link
Contributor

Choose a reason for hiding this comment

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

You can just remove the underscore on the method below instead

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done in
cb84cbe

Copy link
Contributor

@mmalerba mmalerba left a comment

Choose a reason for hiding this comment

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

I hope you don't mind, I just went ahead and fixed the test and pushed it to this branch :)

@@ -289,6 +289,11 @@ export class MatDatepicker<D> implements OnDestroy, CanColor {
}
}

/** Public method to select a date in the Datepicker */
select(date: D): void {
Copy link
Contributor

Choose a reason for hiding this comment

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

You can just remove the underscore on the method below instead


view.ngAfterContentInit();

// to be removed once test works
Copy link
Contributor

Choose a reason for hiding this comment

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

don't forget to remove this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed in
cb84cbe

@tobiasschweizer
Copy link
Contributor Author

I hope you don't mind, I just went ahead and fixed the test and pushed it to this branch :)

That's great, thanks a lot!

If I understand correctly

spyOn(adapter, 'today').and.callFake(() => fakeToday);

overwrites the today method of the DateAdapter used by MatCalendar so it always returns whatever you define to be returned by the lambda for callFake.

@tobiasschweizer
Copy link
Contributor Author

@mmalerba There is one failing test in Mode=travis_required:

Firefox 61.0.0 (Linux 0.0.0) MatAccordion should ensure only one item is expanded at a time FAILED

I don't think this is related to this PR.

Copy link
Contributor

@mmalerba mmalerba left a comment

Choose a reason for hiding this comment

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

Yeah, failure looks unrelated

@mmalerba mmalerba added pr: lgtm action: merge The PR is ready for merge by the caretaker labels Jul 18, 2018
@josephperrott josephperrott merged commit 37228e5 into angular:master Jul 18, 2018
@tobiasschweizer tobiasschweizer deleted the tobiasschweizer-datepicker-todaysdate branch July 19, 2018 07:18
@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 9, 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 target: minor This PR is targeted for the next minor release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants