Skip to content

Commit

Permalink
feat: (Core) Custom Messages in pickers (#4361)
Browse files Browse the repository at this point in the history
* fix: (Core) Create new message service, introduce it into datepicker

* add change detection handling

* add tests, add change detection for triggerEvents

* Add new form messages to time/datetime pickers, add tests

* remove leftovers

* add missing module

* remove console.logs / tmp variables

* apply PR comments

* apply PR comments

* remove leftovers

* apply changes into platform

* fix platform tests

* fix platform tests

* fix platform test
  • Loading branch information
JKMarkowski committed Jan 26, 2021
1 parent 431cf3a commit 857eba6
Show file tree
Hide file tree
Showing 25 changed files with 579 additions and 166 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,16 @@
<label fd-form-label>Date Picker</label>
<fd-date-picker
[disableFunction]="disableFunction"
[message]="isValid() ? 'This is valid(success) DatePicker' : 'This is invalid(error) DatePicker'"
[state]="isValid() ? 'success' : 'error'"
formControlName="date"
>
</fd-date-picker>
<fd-form-message
*ngIf="isValid()"
[type]="'success'"
>This is valid(success) DatePicker</fd-form-message>
<fd-form-message
*ngIf="!isValid()"
[type]="'error'"
>This is invalid(error) DatePicker</fd-form-message>
</div>
<br />
Touched: {{ customForm.controls.date.touched }}<br />
Dirty: {{ customForm.controls.date.dirty }}<br />
Valid: {{ customForm.controls.date.valid }}<br />
Selected Date: {{ customForm.controls.date.value?.toDateString() || 'null' }}
</div>
</form>
</form>
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ import { FdDate } from '@fundamental-ngx/core';
<div>
<div fd-form-item>
<label fd-form-label>Date Picker</label>
<fd-date-picker [state]="isValid() ? 'success' : 'error'" formControlName="date"> </fd-date-picker>
<fd-form-message *ngIf="isValid()" [type]="'success'"
>This is valid(success) DatePicker</fd-form-message
>
<fd-form-message *ngIf="!isValid()" [type]="'error'"
>This is invalid(error) DatePicker</fd-form-message
>
<fd-date-picker
[state]="isValid() ? 'success' : 'error'"
[message]="isValid() ? 'This is valid(success) DatePicker' : 'This is invalid(error) DatePicker'"
formControlName="date">
</fd-date-picker>
</div>
<br />
Touched: {{ customForm.controls.date.touched }}<br />
Expand All @@ -29,8 +27,11 @@ import { FdDate } from '@fundamental-ngx/core';
<div fd-form-item>
<label fd-form-label>Disabled Date Picker</label>
<fd-date-picker [state]="'information'" formControlName="disabledDate"></fd-date-picker>
<fd-form-message [type]="'information'">This is disabled DatePicker</fd-form-message>
<fd-date-picker
state="information"
message="This is disabled DatePicker"
formControlName="disabledDate">
</fd-date-picker>
<br />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
style="width: 300px"
formControlName="dates"
[state]="isValid() ? 'success' : 'error'"
[message]="!isValid() ? 'Format is not valid' : ''"
[disableRangeEndFunction]="disabledEndFunction"
[disableRangeStartFunction]="disabledStartFunction"
></fd-date-picker>
Expand All @@ -19,4 +20,4 @@
<br />
Range End Date:
{{ customForm.controls.dates.value.end?.toDateString() || 'null' }}
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { FdDate } from '@fundamental-ngx/core';
@Component({
selector: 'fd-date-picker-single-example',
changeDetection: ChangeDetectionStrategy.OnPush,
template: ` <fd-date-picker type="single" [(ngModel)]="date"></fd-date-picker>
<br />
template: `
<fd-date-picker type="single" [(ngModel)]="date"></fd-date-picker>
<br/>
<div>Selected Date: {{ date?.toDateString() || 'null' }}</div>
<br />
<br/>
<fd-date-picker type="single" [(ngModel)]="date" compact="true"></fd-date-picker>
<div>Selected Date: {{ date?.toDateString() }}</div>`
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,11 @@
<label fd-form-label>Valid Date Picker</label>
<fd-datetime-picker
[state]="isValid() ? 'success' : 'error'"
[message]="isValid() ? 'This is valid DateTimePicker' : 'This is invalid DateTimePicker'"
formControlName="date"
[disableFunction]="disableFunction"
>
</fd-datetime-picker>
<fd-form-message
*ngIf="isValid()"
[type]="'success'"
>This is valid DateTimePicker</fd-form-message>
<fd-form-message
*ngIf="!isValid()"
[type]="'error'"
>This is invalid DateTimePicker</fd-form-message>
<br />
Touched: {{ customForm.controls.date.touched }}<br />
Dirty: {{ customForm.controls.date.dirty }}<br />
Expand All @@ -29,10 +22,10 @@
<div fd-form-item>
<label fd-form-label>Disabled Date Picker</label>
<fd-datetime-picker
[state]="'information'"
state="information"
message="This is disabled DateTimePicker"
formControlName="disabledDate"
></fd-datetime-picker>
<fd-form-message [type]="'information'">This is disabled DateTimePicker</fd-form-message>
<br />
Touched: {{ customForm.controls.date.touched }}<br />
Dirty: {{ customForm.controls.date.dirty }}<br />
Expand All @@ -41,4 +34,4 @@
Selected Date:
{{ customForm.controls.date.value || 'null' }}
</div>
</form>
</form>
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<form [formGroup]="customForm" class="flex-form">
<div fd-form-item>
<label fd-form-label>TimePicker</label>
<fd-time-picker formControlName="time"></fd-time-picker>
<fd-form-message [type]="'success'" *ngIf="isValid()">Valid Time</fd-form-message>
<fd-form-message [type]="'error'" *ngIf="!isValid()">Invalid Time</fd-form-message>
<fd-time-picker formControlName="time"
[state]="isValid() ? 'success' : 'error'"
[message]="isValid() ? 'Valid Time' : 'Invalid Time'">
</fd-time-picker>
<br />
Selected Time:
<span *ngIf="customForm.controls.time.value">
Expand All @@ -13,8 +14,7 @@
</div>
<div fd-form-item>
<label fd-form-label>Disabled TimePicker</label>
<fd-time-picker formControlName="disabledTime"></fd-time-picker>
<fd-form-message [type]="'information'">More Information</fd-form-message>
<fd-time-picker formControlName="disabledTime" state="information" message="More Information"></fd-time-picker>
<br />
Selected Time:
<span *ngIf="customForm.controls.disabledTime.value">
Expand Down
12 changes: 8 additions & 4 deletions libs/core/src/lib/date-picker/date-picker.component.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<fd-popover
[(isOpen)]="isOpen"
(isOpenChange)="isOpenChange.emit($event)"
(isOpenChange)="isOpenChange.emit($event); _changeMessageVisibility()"
[triggers]="[]"
[placement]="placement"
[disabled]="disabled"
Expand All @@ -9,17 +9,17 @@
[appendTo]="appendTo"
>
<fd-popover-control>
<fd-input-group [compact]="compact" [state]="state" [disabled]="disabled">
<fd-input-group [compact]="compact" [state]="state" [disabled]="disabled" #inputGroupComponent>
<input
type="text"
class="fd-input"
fd-input-group-input
[compact]="compact"
[disabled]="disabled"
[placeholder]="placeholder"
[class.is-error]="isInvalidDateInput && useValidation"
[class.is-error]="_isInvalidDateInput && useValidation"
[attr.aria-label]="dateInputLabel"
[(ngModel)]="inputFieldDate"
[(ngModel)]="_inputFieldDate"
(ngModelChange)="handleInputChange($event)"
/>
<span fd-input-group-addon [button]="true" [compact]="compact">
Expand All @@ -38,7 +38,11 @@
</fd-input-group>
</fd-popover-control>
<fd-popover-body [style.display]="'block'" [attr.aria-expanded]="isOpen" [attr.aria-hidden]="!isOpen">
<fd-form-message [embedded]="true" *ngIf="_message" [type]="state">
{{ _message }}
</fd-form-message>
<ng-content></ng-content>

<fd-calendar
(closeCalendar)="closeFromCalendar()"
[activeView]="activeView"
Expand Down
65 changes: 40 additions & 25 deletions libs/core/src/lib/date-picker/date-picker.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ describe('DatePickerComponent', () => {

it('should open the calendar', () => {
component.isOpen = false;
component.isInvalidDateInput = true;
component._isInvalidDateInput = true;
component.openCalendar();
expect(component.isOpen).toBeTruthy();
expect(component.inputFieldDate).toBeNull();
expect(component._inputFieldDate).toBeNull();
});

it('should not open the calendar if the component is disabled', () => {
Expand All @@ -63,9 +63,9 @@ describe('DatePickerComponent', () => {

it('should close the calendar', () => {
component.isOpen = true;
component.isInvalidDateInput = true;
component._isInvalidDateInput = true;
component.closeCalendar();
expect(component.inputFieldDate).toBeNull();
expect(component._inputFieldDate).toBeNull();
expect(component.isOpen).not.toBeTruthy();
});

Expand All @@ -74,9 +74,9 @@ describe('DatePickerComponent', () => {
spyOn(component.selectedDateChange, 'emit');
const date = adapter.today();
const dateStr = (<any>component)._formatDate(date);
component.inputFieldDate = '';
component._inputFieldDate = '';
component.handleSingleDateChange(date);
expect(component.inputFieldDate).toEqual(dateStr);
expect(component._inputFieldDate).toEqual(dateStr);
expect(component.onChange).toHaveBeenCalledWith(date);
expect(component.selectedDateChange.emit).toHaveBeenCalledWith(date);
});
Expand All @@ -88,9 +88,9 @@ describe('DatePickerComponent', () => {
const dateLast = adapter.addCalendarDays(dateStart, 10);
const dateStrStart = (<any>component)._formatDate(dateStart);
const dateStrLast = (<any>component)._formatDate(dateLast);
component.inputFieldDate = '';
component._inputFieldDate = '';
component.handleRangeDateChange({ start: dateStart, end: dateLast });
expect(component.inputFieldDate).toBe(dateStrStart + component.rangeDelimiter + dateStrLast);
expect(component._inputFieldDate).toBe(dateStrStart + component.rangeDelimiter + dateStrLast);
expect(component.onChange).toHaveBeenCalledWith({ start: dateStart, end: dateLast });
expect(component.selectedRangeDateChange.emit).toHaveBeenCalledWith({ start: dateStart, end: dateLast });
});
Expand All @@ -100,13 +100,13 @@ describe('DatePickerComponent', () => {
const dateStr = (<any>component)._formatDate(date);
component.writeValue(date);
expect(component.selectedDate).toEqual(date);
expect(component.inputFieldDate).toBe(dateStr);
expect(component._inputFieldDate).toBe(dateStr);
});

it('Should handle null write value for single mode', () => {
component.writeValue(null);
expect(component.selectedDate).toBeUndefined();
expect(component.inputFieldDate).toBe('');
expect(component._inputFieldDate).toBe('');
});

it('Should handle correct write value for range mode', () => {
Expand All @@ -123,15 +123,15 @@ describe('DatePickerComponent', () => {
const dateEnd = null;
component.writeValue({ start: dateStart, end: dateEnd });
expect(component.selectedRangeDate).toEqual({ start: dateStart, end: dateEnd });
expect(component.inputFieldDate).toBe('');
expect(component._inputFieldDate).toBe('');
});

it('Should register invalid string date and not call event for single mode', () => {
spyOn(component.selectedDateChange, 'emit');
component.type = 'single';
component.dateStringUpdate('hello');
const date: FdDate = adapter.parse('hello');
expect(component.isInvalidDateInput).toBe(true);
expect(component._isInvalidDateInput).toBe(true);
expect(component.selectedDateChange.emit).toHaveBeenCalledWith(date);
expect(component.isModelValid()).toBe(false);
});
Expand All @@ -142,7 +142,7 @@ describe('DatePickerComponent', () => {
component.dateStringUpdate('start - end');
const start: FdDate = adapter.parse('start');
const end: FdDate = adapter.parse('end');
expect(component.isInvalidDateInput).toBe(true);
expect(component._isInvalidDateInput).toBe(true);
expect(component.selectedRangeDateChange.emit).toHaveBeenCalledWith({ start: start, end: end });
expect(component.isModelValid()).toBe(false);
});
Expand All @@ -167,9 +167,9 @@ describe('DatePickerComponent', () => {
component.type = 'range';
component.dateStringUpdate(strDate1 + ' - ' + strDate2);

expect(component.isInvalidDateInput).toBe(false);
expect(component.calendarComponent.currentlyDisplayed.month).toBe(date2.month);
expect(component.calendarComponent.currentlyDisplayed.year).toBe(date2.year);
expect(component._isInvalidDateInput).toBe(false);
expect(component._calendarComponent.currentlyDisplayed.month).toBe(date2.month);
expect(component._calendarComponent.currentlyDisplayed.year).toBe(date2.year);
expect(component.selectedRangeDateChange.emit).toHaveBeenCalledWith({ start: date2, end: date1 });
expect(component.onChange).toHaveBeenCalledWith({ start: date2, end: date1 });
});
Expand All @@ -184,9 +184,9 @@ describe('DatePickerComponent', () => {
component.type = 'single';
spyOn(adapter, 'parse').and.returnValue(date);
component.dateStringUpdate(strDate);
expect(component.isInvalidDateInput).toBe(true);
expect(component.calendarComponent.currentlyDisplayed.month).toBe(todayDate.month);
expect(component.calendarComponent.currentlyDisplayed.year).toBe(todayDate.year);
expect(component._isInvalidDateInput).toBe(true);
expect(component._calendarComponent.currentlyDisplayed.month).toBe(todayDate.month);
expect(component._calendarComponent.currentlyDisplayed.year).toBe(todayDate.year);
expect(component.selectedDateChange.emit).toHaveBeenCalledWith(date);
expect(component.onChange).toHaveBeenCalledWith(date);
});
Expand Down Expand Up @@ -214,9 +214,9 @@ describe('DatePickerComponent', () => {
});
component.dateStringUpdate(strDate1 + ' - ' + strDate2);

expect(component.isInvalidDateInput).toBe(true);
expect(component.calendarComponent.currentlyDisplayed.month).toBe(todayDate.month);
expect(component.calendarComponent.currentlyDisplayed.year).toBe(todayDate.year);
expect(component._isInvalidDateInput).toBe(true);
expect(component._calendarComponent.currentlyDisplayed.month).toBe(todayDate.month);
expect(component._calendarComponent.currentlyDisplayed.year).toBe(todayDate.year);
expect(component.selectedRangeDateChange.emit).toHaveBeenCalledWith(rangeDateInvalidObject);
expect(component.onChange).toHaveBeenCalledWith(rangeDateInvalidObject);
});
Expand All @@ -243,10 +243,25 @@ describe('DatePickerComponent', () => {
});
component.dateStringUpdate(strDate1 + ' - ' + strDate2);

expect(component.isInvalidDateInput).toBe(true);
expect(component.calendarComponent.currentlyDisplayed.month).toBe(date1.month);
expect(component.calendarComponent.currentlyDisplayed.year).toBe(date1.year);
expect(component._isInvalidDateInput).toBe(true);
expect(component._calendarComponent.currentlyDisplayed.month).toBe(date1.month);
expect(component._calendarComponent.currentlyDisplayed.year).toBe(date1.year);
expect(component.selectedRangeDateChange.emit).toHaveBeenCalledWith(rangeDateInvalidObject);
expect(component.onChange).toHaveBeenCalledWith(rangeDateInvalidObject);
});

it('should hide message on open', () => {
const hideSpy = spyOn((<any>component)._popoverFormMessage, 'hide').and.callThrough();
component.openCalendar();
fixture.detectChanges();
expect(hideSpy).toHaveBeenCalled();
})

it('should show message on close', () => {
component.isOpen = true;
const showSpy = spyOn((<any>component)._popoverFormMessage, 'show').and.callThrough();
component.closeCalendar();
fixture.detectChanges();
expect(showSpy).toHaveBeenCalled();
});
});

0 comments on commit 857eba6

Please sign in to comment.