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

Save start and end time in range date-time picker #37

Merged
merged 2 commits into from
Jun 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ Properties for `owl-date-time`
|`pickerMode`|`popup`, `dialog`|Optional|`popup`| The style the picker would open as. |
|`startView`|`month`, `year`, `multi-year`|Optional|`month`| The view that the calendar should start in. |
|`startAt`| T/null |Optional|`null`| The moment to open the picker to initially. |
|`endAt`| T/null |Optional|`null`| The the default selected time for range calendar end time |
|`firstDayOfWeek`|number|Optional|`0`| Set the first day of week. Valid value is from 0 to 6. 0: Sunday - 6: Saturday|
|`showSecondsTimer`|boolean|Optional|`false`| When specify it to true, it would show a timer to configure the second's value |
|`hideOtherMonths`|boolean|Optional|`false`| Whether to hide dates in other months at the start or end of the current month |
Expand Down Expand Up @@ -163,6 +164,7 @@ Properties for `owl-date-time-inline`
|`pickerType`|`both`, `calendar`, `timer`|Optional|`both`| Set the type of the dateTime picker. `both`: show both calendar and timer, `calendar`: only show calendar, `timer`: only show timer. |
|`startView`|`month`, `year`, `multi-year`|Optional|`month`| The view that the calendar should start in. |
|`startAt`| T/null |Optional|`null`| The moment to open the picker to initially. |
|`endAt`| T/null |Optional|`null`| The the default selected time for range calendar end time |
|`firstDayOfWeek`|number|Optional|`0`| Set the first day of week. Valid value is from 0 to 6. 0: Sunday - 6: Saturday|
|`showSecondsTimer`|boolean|Optional|`false`| When specify it to true, it would show a timer to configure the second's value |
|`hideOtherMonths`|boolean|Optional|`false`| Whether to hide dates in other months at the start or end of the current month |
Expand Down
30 changes: 28 additions & 2 deletions projects/picker/src/lib/date-time/date-time-inline.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,32 @@ export class OwlDateTimeInlineComponent<T> extends OwlDateTime<T>
);
}

/** The date to open for range calendar. */
private _endAt: T | null;
@Input()
get endAt(): T | null {
if (this._endAt) {
return this._endAt;
}

if (this.selectMode === 'single') {
return this.value || null;
} else if (
this.selectMode === 'range' ||
this.selectMode === 'rangeFrom'
) {
return this.values[1] || null;
} else {
return null;
}
}

set endAt(date: T | null) {
this._endAt = this.getValidDate(
this.dateTimeAdapter.deserialize(date)
);
}

private _dateTimeFilter: (date: T | null) => boolean;
@Input('owlDateTimeFilter')
get dateTimeFilter() {
Expand Down Expand Up @@ -254,8 +280,8 @@ export class OwlDateTimeInlineComponent<T> extends OwlDateTime<T>
return true;
}

private onModelChange: Function = () => {};
private onModelTouched: Function = () => {};
private onModelChange: Function = () => { };
private onModelTouched: Function = () => { };

constructor(
protected changeDetector: ChangeDetectorRef,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ export class OwlDateTimeContainerComponent<T>
public picker: OwlDateTime<T>;
public activeSelectedIndex = 0; // The current active SelectedIndex in range select mode (0: 'from', 1: 'to')

// retain start and end time
private retainStartTime: T;
private retainEndTime: T;

/**
* Stream emits when try to hide picker
* */
Expand Down Expand Up @@ -203,7 +207,16 @@ export class OwlDateTimeContainerComponent<T>
@Optional() private dateTimeAdapter: DateTimeAdapter<T> ) {
}

public ngOnInit() {}
public ngOnInit() {
if (this.picker.selectMode === 'range') {
if (this.picker.selecteds[0]) {
this.retainStartTime = this.dateTimeAdapter.clone(this.picker.selecteds[0]);
}
if (this.picker.selecteds[1]) {
this.retainEndTime = this.dateTimeAdapter.clone(this.picker.selecteds[1]);
}
}
}

public ngAfterContentInit(): void {
this.initPicker();
Expand Down Expand Up @@ -283,6 +296,12 @@ export class OwlDateTimeContainerComponent<T>
selecteds[this.activeSelectedIndex] = this.pickerMoment;
}

if (selecteds[0]) {
this.retainStartTime = this.dateTimeAdapter.clone(selecteds[0]);
}
if (selecteds[1]) {
this.retainEndTime = this.dateTimeAdapter.clone(selecteds[1]);
}
this.picker.select(selecteds);
}
}
Expand Down Expand Up @@ -409,10 +428,47 @@ export class OwlDateTimeContainerComponent<T>
from &&
this.dateTimeAdapter.differenceInCalendarDays(result, from) >= 0
) {
to = result;
if (this.picker.endAt && !this.retainEndTime) {
to = this.dateTimeAdapter.createDate(
this.dateTimeAdapter.getYear(result),
this.dateTimeAdapter.getMonth(result),
this.dateTimeAdapter.getDate(result),
this.dateTimeAdapter.getHours(this.picker.endAt),
this.dateTimeAdapter.getMinutes(this.picker.endAt),
this.dateTimeAdapter.getSeconds(this.picker.endAt));
} else if (this.retainEndTime) {
to = this.dateTimeAdapter.createDate(
this.dateTimeAdapter.getYear(result),
this.dateTimeAdapter.getMonth(result),
this.dateTimeAdapter.getDate(result),
this.dateTimeAdapter.getHours(this.retainEndTime),
this.dateTimeAdapter.getMinutes(this.retainEndTime),
this.dateTimeAdapter.getSeconds(this.retainEndTime));
} else {
to = result;
}
this.activeSelectedIndex = 1;
} else {
from = result;
if (this.picker.startAt && !this.retainStartTime) {
from = this.dateTimeAdapter.createDate(
this.dateTimeAdapter.getYear(result),
this.dateTimeAdapter.getMonth(result),
this.dateTimeAdapter.getDate(result),
this.dateTimeAdapter.getHours(this.picker.startAt),
this.dateTimeAdapter.getMinutes(this.picker.startAt),
this.dateTimeAdapter.getSeconds(this.picker.startAt)
);
} else if (this.retainStartTime) {
from = this.dateTimeAdapter.createDate(
this.dateTimeAdapter.getYear(result),
this.dateTimeAdapter.getMonth(result),
this.dateTimeAdapter.getDate(result),
this.dateTimeAdapter.getHours(this.retainStartTime),
this.dateTimeAdapter.getMinutes(this.retainStartTime),
this.dateTimeAdapter.getSeconds(this.retainStartTime));
} else {
from = result;
}
to = null;
this.activeSelectedIndex = 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ describe('OwlDateTimeComponent', () => {
it('clicking the dateCell should set the rangeFrom value when both rangeFrom and rangeTo had NO value', fakeAsync(() => {
testComponent.dates = [];
fixture.detectChanges();

testComponent.dateTimePicker.open();
fixture.detectChanges();
flush();
Expand Down Expand Up @@ -804,6 +804,72 @@ describe('OwlDateTimeComponent', () => {
);
}));

it('if startAt value is set, the start time value should be shown in the rangeTo calendar start time', fakeAsync(() => {
testComponent.startAt = new Date('1/19/2020, 09:33 AM');
testComponent.dateTimePicker.open();
fixture.detectChanges();
flush();

const containerDebugElement = fixture.debugElement.query(
By.directive(OwlDateTimeContainerComponent)
);
containerElement = containerDebugElement.nativeElement;
const timeCells = containerElement.querySelectorAll<HTMLInputElement>('.owl-dt-timer-input');

expect(timeCells[0].value).toEqual('09');
expect(timeCells[1].value).toEqual('33');
}));


it('if endAt value is set, the end time value should be shown in the rangeTo calendar end time', fakeAsync(() => {
testComponent.dates = [new Date(2020, JAN, 2), null];
testComponent.endAt = new Date('1/19/2020, 10:55 PM');
fixture.detectChanges();

testComponent.dateTimePicker.open();
fixture.detectChanges();
flush();

const containerDebugElement = fixture.debugElement.query(
By.directive(OwlDateTimeContainerComponent)
);
containerElement = containerDebugElement.nativeElement;
const dateCell = containerElement.querySelector(
'[aria-label="January 20, 2020"]'
);
dispatchMouseEvent(dateCell, 'click');
fixture.detectChanges();
flush();

const timeCells = containerElement.querySelectorAll<HTMLInputElement>('.owl-dt-timer-input');

expect(timeCells[0].value).toEqual('22');
expect(timeCells[1].value).toEqual('55');
}));

it('auto select previous time if dates is selected', fakeAsync(() => {
testComponent.dates = [new Date('1/19/2020, 09:33 AM'), new Date('1/22/2020, 10:44 PM')];
testComponent.dateTimePicker.open();
fixture.detectChanges();

const containerDebugElement = fixture.debugElement.query(
By.directive(OwlDateTimeContainerComponent)
);
containerElement = containerDebugElement.nativeElement;
const dateCell = containerElement.querySelector(
'[aria-label="January 20, 2020"]'
);
dispatchMouseEvent(dateCell, 'click');
fixture.detectChanges();
flush();

const timeInput = containerElement.querySelectorAll<HTMLInputElement>('.owl-dt-timer-input');

expect(timeInput[0].value).toEqual('09');
expect(timeInput[1].value).toEqual('33');

}));

it('should have the container info row', () => {
testComponent.dateTimePicker.open();
fixture.detectChanges();
Expand Down Expand Up @@ -2345,15 +2411,16 @@ class StandardDateTimePickerComponent {
@Component({
template: `
<input [owlDateTime]="dt" [selectMode]="selectMode" [values]="dates">
<owl-date-time [startAt]="startAt"
<owl-date-time [startAt]="startAt" [endAt]="endAt"
[pickerType]="pickerType" #dt></owl-date-time>
`
})
class RangeDateTimePickerComponent {
dates: Date[] | null = [new Date(2020, JAN, 1), new Date(2020, FEB, 1)];
dates: Date[] | null = [new Date(2020, JAN, 1), new Date(2020, FEB, 1)];
selectMode = 'range';
pickerType = 'both';
startAt = new Date(2020, JAN, 1);
endAt = new Date(2020, JAN, 2);
@ViewChild('dt', { static: true })
dateTimePicker: OwlDateTimeComponent<Date>;
@ViewChild(OwlDateTimeInputDirective, { static: true })
Expand Down
28 changes: 28 additions & 0 deletions projects/picker/src/lib/date-time/date-time-picker.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,34 @@ export class OwlDateTimeComponent<T> extends OwlDateTime<T>
);
}

/** The end date to set for range calendar. */
private _endAt: T | null;
@Input()
get endAt(): T | null {
if (this._endAt) {
return this._endAt;
}

if (this._dtInput) {
if (this._dtInput.selectMode === 'single') {
return this._dtInput.value || null;
} else if (
this._dtInput.selectMode === 'range' ||
this._dtInput.selectMode === 'rangeFrom'
) {
return this._dtInput.values[1] || null;
}
} else {
return null;
}
}

set endAt(date: T | null) {
this._endAt = this.getValidDate(
this.dateTimeAdapter.deserialize(date)
);
}

/**
* Set the type of the dateTime picker
* 'both' -- show both calendar and timer
Expand Down
2 changes: 2 additions & 0 deletions projects/picker/src/lib/date-time/date-time.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ export abstract class OwlDateTime<T> {

abstract get startAt(): T | null;

abstract get endAt(): T | null;

abstract get opened(): boolean;

abstract get pickerMode(): PickerMode;
Expand Down
2 changes: 1 addition & 1 deletion src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
[owlDateTimeTrigger]="date_range_component" [owlDateTime]="date_range_component"
style="width: 100%; color: cornflowerblue"
id="daterange" matInput>
<owl-date-time #date_range_component></owl-date-time>
<owl-date-time #date_range_component [startAt]="currentValue" [endAt]="endValue"></owl-date-time>
4 changes: 4 additions & 0 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export class AppComponent implements AfterViewInit {
moment('2019-03-11T15:00:00+11:00').tz('America/Los_Angeles')
];


currentValue: Date = new Date('4/21/2020, 12:00 AM');
endValue: Date = new Date('4/21/2020, 11:59 PM');

open_once = false;

ngAfterViewInit() {
Expand Down