Skip to content

Commit

Permalink
feat(Input): support date locales
Browse files Browse the repository at this point in the history
Also, supported through date range and cohort date range components

ISSUES CLOSED: #2108
  • Loading branch information
benjamincharity committed Apr 7, 2020
1 parent 78ddeee commit 0e92b52
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ <h3 tsCardTitle tsVerticalSpacing>Demo Controls</h3>
<button (click)="updateStartDate()">Update start date</button>
<br>
<button (click)="printRange(myForm.value)">Print Range</button>
<br>
<button (click)="changeLocale()">Toggle locale to {{ locale === 'fr' ? 'en-US' : 'fr' }}</button>
</ts-card>


Expand All @@ -19,6 +21,7 @@ <h3 tsCardTitle tsVerticalSpacing>Demo Controls</h3>

<ts-date-range
[dateFormGroup]="myForm.get('dateRange')"
[dateLocale]="locale"
(dateRangeChange)="printRange(myForm.value)"
></ts-date-range>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ date2.setDate(date2.getDate() + 5);
templateUrl: './date-range.component.html',
})
export class DateRangeComponent implements OnInit {
locale = 'en-US';
myMin: Date = new Date(2017, 4, 2);
/*
*initialStart: Date = new Date(2017, 4, 5);
Expand Down Expand Up @@ -79,4 +80,8 @@ export class DateRangeComponent implements OnInit {
}
}

changeLocale(): void {
this.locale = (this.locale === 'en-US') ? 'fr' : 'en-US';
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<ts-date-range
class="ts-cohort-date-range__date-range"
[dateFormGroup]="dateRangeFormGroup"
[dateLocale]="dateLocale"
[isDisabled]="!allowCustomDates || isDisabled"
(dateRangeChange)="cohortDateRangeChange($event)"
[startMinDate]="startMinDate"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ let nextUniqueId = 0;
* <ts-cohort-date-range
* [allowCustomDates]="true"
* [cohorts]="myCohorts"
* dateLocale="fr"
* endMaxDate="{{ new Date(2017, 4, 30) }}"
* endMinDate="{{ new Date(2017, 4, 1) }}"
* id="myID"
Expand Down Expand Up @@ -193,6 +194,12 @@ export class TsCohortDateRangeComponent implements OnInit, OnDestroy {
private _cohorts: TsDateCohort[];
private originalCohorts: ReadonlyArray<TsDateCohort>;

/**
* Define the date locale
*/
@Input()
public dateLocale: string | undefined;

/**
* Define the max date for the end date
*/
Expand Down
2 changes: 2 additions & 0 deletions projects/library/date-range/src/date-range.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
>
<ts-input
class="c-date-range--start qa-date-range-start-datepicker"
[dateLocale]="dateLocale"
[formControl]="internalStartControl"
[label]="startLabel"
[maxDate]="startMaxDate$ | async"
Expand All @@ -26,6 +27,7 @@

<ts-input
class="c-date-range--end qa-date-range-end-datepicker"
[dateLocale]="dateLocale"
[formControl]="internalEndControl"
[label]="endLabel"
[maxDate]="endMaxDate"
Expand Down
140 changes: 67 additions & 73 deletions projects/library/date-range/src/date-range.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export interface TsDateRange {
* The start date of the range
*/
start: Date | undefined;

/**
* The end date of the range
*/
Expand All @@ -41,6 +40,7 @@ export interface TsDateRange {
* @example
* <ts-date-range
* [dateFormGroup]="myForm.get('dateRange')"
* dateLocale="fr"
* endMaxDate="{{ new Date(2017, 4, 30) }}"
* endMinDate="{{ new Date(2017, 4, 1) }}"
* [isDisabled]="true"
Expand Down Expand Up @@ -134,6 +134,12 @@ export class TsDateRangeComponent implements OnInit, OnDestroy {
*/
public startLabel = 'Start date';

/**
* Define the date locale
*/
@Input()
public dateLocale: string | undefined;

/**
* Define the form group to attach the date range to
*/
Expand Down Expand Up @@ -209,7 +215,7 @@ export class TsDateRangeComponent implements OnInit, OnDestroy {

constructor(
private changeDetectorRef: ChangeDetectorRef,
) { }
) {}


/**
Expand All @@ -234,80 +240,15 @@ export class TsDateRangeComponent implements OnInit, OnDestroy {
this.setUpFormControlSync();
}


/**
* Needed for untilComponentDestroyed
*/
public ngOnDestroy(): void {}


/**
* Set up subscriptions to sync the internat FormControl to the external FormControl
*/
private setUpFormControlSync(): void {
if (!this.dateFormGroup) {
return;
}

const startCtrl = this.dateFormGroup.get('startDate');
const endCtrl = this.dateFormGroup.get('endDate');

if (!startCtrl || !endCtrl) {
return;
}

this.changeDetectorRef.detectChanges();

// HACK: This is to fix on an initial load, date range value isn't populating correctly.

this.internalStartControl.setValue(startCtrl.value);
this.internalEndControl.setValue(endCtrl.value);

// START DATE
startCtrl.valueChanges.pipe(untilComponentDestroyed(this)).subscribe(value => {
this.internalStartControl.setValue(value);
this.endMinDate$.next(value);
});
startCtrl.statusChanges.pipe(untilComponentDestroyed(this)).subscribe(() => {
this.internalStartControl.setErrors(startCtrl.errors);
});

// END DATE
endCtrl.valueChanges.pipe(untilComponentDestroyed(this)).subscribe(value => {
this.internalEndControl.setValue(value);
this.startMaxDate$.next(value);
});
endCtrl.statusChanges.pipe(untilComponentDestroyed(this)).subscribe(() => {
this.internalEndControl.setErrors(endCtrl.errors);
});

this.changeDetectorRef.detectChanges();
}


/**
* Set up initial min and max dates
*
* @param formGroup - The date form group
*/
private initializeMinAndMax(formGroup: FormGroup | AbstractControl): void {
const startControl: AbstractControl | null = formGroup.get('startDate');
const endControl: AbstractControl | null = formGroup.get('endDate');
const startControlValue: Date | undefined = startControl ? startControl.value /* istanbul ignore next - Unreachable */ : undefined;
const endControlValue: Date | undefined = endControl ? endControl.value /* istanbul ignore next - Unreachable */ : undefined;
const startValueToUse = startControlValue || this.endMinDate;
const endValueToUse = endControlValue || this.endMinDate;

this.endMinDate$.next(startValueToUse);
this.startMaxDate$.next(endValueToUse);
}


/**
* Emit the selected start date and date range
*
* @param datepickerEvent - The event received from the range start event
* {@link TsDatepickerComponent}
* @param date
*/
public startDateSelected(date: Date): void {
if (date) {
Expand All @@ -327,12 +268,10 @@ export class TsDateRangeComponent implements OnInit, OnDestroy {
}
}


/**
* Emit the selected end date and date range
*
* @param datepickerEvent - The event received from the range end event
* {@link TsDatepickerComponent}
* @param date
*/
public endDateSelected(date: Date): void {
if (date) {
Expand All @@ -352,7 +291,6 @@ export class TsDateRangeComponent implements OnInit, OnDestroy {
}
}


/**
* Update dates when the start date input receives a blur event
*
Expand All @@ -375,7 +313,6 @@ export class TsDateRangeComponent implements OnInit, OnDestroy {
}
}


/**
* Update dates when the end date input receives a blur event
*
Expand All @@ -398,4 +335,61 @@ export class TsDateRangeComponent implements OnInit, OnDestroy {
}
}

/**
* Set up subscriptions to sync the internal FormControl to the external FormControl
*/
private setUpFormControlSync(): void {
if (!this.dateFormGroup) {
return;
}
const startCtrl = this.dateFormGroup.get('startDate');
const endCtrl = this.dateFormGroup.get('endDate');

if (!startCtrl || !endCtrl) {
return;
}

this.changeDetectorRef.detectChanges();

// HACK: This is to fix on an initial load, date range value isn't populating correctly.
this.internalStartControl.setValue(startCtrl.value);
this.internalEndControl.setValue(endCtrl.value);

// START DATE
startCtrl.valueChanges.pipe(untilComponentDestroyed(this)).subscribe(value => {
this.internalStartControl.setValue(value);
this.endMinDate$.next(value);
});
startCtrl.statusChanges.pipe(untilComponentDestroyed(this)).subscribe(() => {
this.internalStartControl.setErrors(startCtrl.errors);
});

// END DATE
endCtrl.valueChanges.pipe(untilComponentDestroyed(this)).subscribe(value => {
this.internalEndControl.setValue(value);
this.startMaxDate$.next(value);
});
endCtrl.statusChanges.pipe(untilComponentDestroyed(this)).subscribe(() => {
this.internalEndControl.setErrors(endCtrl.errors);
});

this.changeDetectorRef.detectChanges();
}

/**
* Set up initial min and max dates
*
* @param formGroup - The date form group
*/
private initializeMinAndMax(formGroup: FormGroup | AbstractControl): void {
const startControl: AbstractControl | null = formGroup.get('startDate');
const endControl: AbstractControl | null = formGroup.get('endDate');
const startControlValue: Date | undefined = startControl ? startControl.value /* istanbul ignore next - Unreachable */ : undefined;
const endControlValue: Date | undefined = endControl ? endControl.value /* istanbul ignore next - Unreachable */ : undefined;
const startValueToUse = startControlValue || this.endMinDate;
const endValueToUse = endControlValue || this.endMinDate;

this.endMinDate$.next(startValueToUse);
this.startMaxDate$.next(endValueToUse);
}
}
23 changes: 23 additions & 0 deletions projects/library/input/src/input.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,29 @@ describe(`TsInputComponent`, function() {

});

describe(`locale`, () {
test(`should default to US locale`, () => {
const fixture = createComponent(TestComponents.DateLocale);
fixture.detectChanges();
const button = document.getElementsByTagName('mat-datepicker-toggle')[0].getElementsByTagName('button')[0];
button.click();
fixture.detectChanges();
const month = document.getElementsByClassName('mat-calendar-body-label')[0];
expect(month.textContent).toEqual('APR');
});

test.todo(`should be able to change the locale`);
// NOTE: This works perfectly IRL, but in tests I only ever get en-US values
// test(`should be able to change the locale`, () => {
// const fixture = createComponent(TestComponents.DateLocaleForeign);
// fixture.detectChanges();
// const button = document.getElementsByTagName('mat-datepicker-toggle')[0].getElementsByTagName('button')[0];
// button.click();
// fixture.detectChanges();
// const month = document.getElementsByClassName('mat-calendar-body-label')[0];
// expect(month.textContent).not.toEqual('APR');
// });
});
});


Expand Down
Loading

0 comments on commit 0e92b52

Please sign in to comment.