Skip to content
This repository has been archived by the owner on Sep 13, 2021. It is now read-only.

Commit

Permalink
Added 'since' and 'until' selection modes
Browse files Browse the repository at this point in the history
  • Loading branch information
theonelucas committed Jul 17, 2019
1 parent a44856c commit 90d17c7
Show file tree
Hide file tree
Showing 22 changed files with 13,302 additions and 430 deletions.
12,566 changes: 12,566 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"publish": "(cd dist; npm publish)",
"test": "ng test",
"lint": "ng lint",
"lintFix": "prettier --write 'src/**/*.ts' && tslint --fix 'src/**/*.ts'",
"e2e": "ng e2e"
},
"dependencies": {
Expand All @@ -25,6 +26,7 @@
"@angular/platform-browser": "7.1.0",
"@angular/platform-browser-dynamic": "7.1.0",
"core-js": "^2.6.5",
"prettier": "^1.17.1",
"rxjs": "^6.4.0",
"zone.js": "0.8.26"
},
Expand Down
21 changes: 14 additions & 7 deletions saturn-datepicker/src/datepicker/calendar-body.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,11 @@ export class SatCalendarBody implements OnChanges {
/** Whether to mark all dates as semi-selected. */
@Input() rangeFull: boolean;

/** Whether to use date range selection behaviour.*/
@Input() rangeMode = false;
/** Selection mode */
@Input() selectionMode = '';

/** Possible selection modes, in the order that they should appear */
@Input() selectionModes = [];

/** The minimum number of free cells needed to fit the label in the first row. */
@Input() labelMinRequiredCells: number;
Expand Down Expand Up @@ -167,7 +170,11 @@ export class SatCalendarBody implements OnChanges {

/** Whenever to mark cell as semi-selected (inside dates interval). */
_isSemiSelected(date: number) {
if (!this.rangeMode) {
if (
!['range', 'since', 'until'].includes(this.selectionMode) &&
this.begin === null &&
this.end === null
) {
return false;
}
if (this.rangeFull) {
Expand All @@ -188,7 +195,7 @@ export class SatCalendarBody implements OnChanges {

/** Whenever to mark cell as semi-selected before the second date is selected (between the begin cell and the hovered cell). */
_isBetweenOverAndBegin(date: number): boolean {
if (!this._cellOver || !this.rangeMode || !this.beginSelected) {
if (!this._cellOver || !['range', 'since', 'until'].includes(this.selectionMode) || !this.beginSelected) {
return false;
}
if (this.isBeforeSelected && !this.begin) {
Expand All @@ -205,7 +212,7 @@ export class SatCalendarBody implements OnChanges {

/** Whenever to mark cell as begin of the range. */
_isBegin(date: number): boolean {
if (this.rangeMode && this.beginSelected && this._cellOver) {
if (['range', 'since', 'until'].includes(this.selectionMode) && this.beginSelected && this._cellOver) {
if (this.isBeforeSelected && !this.begin) {
return this._cellOver === date;
} else {
Expand All @@ -218,7 +225,7 @@ export class SatCalendarBody implements OnChanges {

/** Whenever to mark cell as end of the range. */
_isEnd(date: number): boolean {
if (this.rangeMode && this.beginSelected && this._cellOver) {
if (['range', 'since', 'until'].includes(this.selectionMode) && this.beginSelected && this._cellOver) {
if (this.isBeforeSelected && !this.begin) {
return false;
} else {
Expand All @@ -245,6 +252,6 @@ export class SatCalendarBody implements OnChanges {

/** Whenever to highlight the target cell when selecting the second date in range mode */
_previewCellOver(date: number): boolean {
return this._cellOver === date && this.rangeMode && this.beginSelected;
return this._cellOver === date && ['range', 'since', 'until'].includes(this.selectionMode) && this.beginSelected;
}
}
2 changes: 1 addition & 1 deletion saturn-datepicker/src/datepicker/calendar.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 14 additions & 1 deletion saturn-datepicker/src/datepicker/calendar.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
<div class="selection-wrapper" *ngIf="selectionModes && selectionModes.length > 1">
<mat-button-toggle-group
name="fontStyle"
aria-label="Selection type"
[(value)]="selectionMode"
>
<mat-button-toggle *ngFor="let sm of selectionModes;" [value]="sm">
<span class="selection-mode-title">{{ sm }}</span>
</mat-button-toggle>
</mat-button-toggle-group>
</div>

<ng-template [cdkPortalOutlet]="_calendarHeaderPortal"></ng-template>

Expand All @@ -8,7 +19,9 @@
[selected]="selected"
[beginDate]="beginDate"
[endDate]="endDate"
[rangeMode]="rangeMode"
[selectionMode]="selectionMode"
[selectionModes]="selectionModes"
[initialSelectionMode]="initialSelectionMode"
[closeAfterSelection]="closeAfterSelection"
[dateFilter]="dateFilter"
[maxDate]="maxDate"
Expand Down
149 changes: 108 additions & 41 deletions saturn-datepicker/src/datepicker/calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ import {MAT_DATE_FORMATS, MatDateFormats} from '../datetime/date-formats';
* Possible views for the calendar.
* @docs-private
*/
export enum SelectionModeType {
Date = 'date',
Range = 'range',
Since = 'since',
Until = 'until',

Default = Date
};
export type SatCalendarView = 'month' | 'year' | 'multi-year';

/** Default header for SatCalendar */
Expand Down Expand Up @@ -204,24 +212,25 @@ export class SatCalendarFooter<D> {
})
export class SatCalendar<D> implements AfterContentInit, AfterViewChecked, OnDestroy, OnChanges {

/** Beginning of date range. */
@Input()
get beginDate(): D | null { return this._beginDate; }
set beginDate(value: D | null) {
this._beginDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));
}
private _beginDate: D | null;

/** Date range end. */
@Input()
get endDate(): D | null { return this._endDate; }
set endDate(value: D | null) {
this._endDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));
}
private _endDate: D | null;
/** Beginning of date range. */
@Input()
get beginDate() {
return this._beginDate;
}
set beginDate(value) {
this._beginDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));
}
private _beginDate;

/** Whenever datepicker is for selecting range of dates. */
@Input() rangeMode = false;
/** Date range end. */
@Input()
get endDate() {
return this._endDate;
}
set endDate(value) {
this._endDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));
}
private _endDate;

/** Enables datepicker closing after selection */
@Input() closeAfterSelection = true;
Expand Down Expand Up @@ -259,11 +268,11 @@ export class SatCalendar<D> implements AfterContentInit, AfterViewChecked, OnDes

/** A date representing the period (month or year) to start the calendar in. */
@Input()
get startAt(): D | null { return this._startAt; }
set startAt(value: D | null) {
get startAt(): D | number | null { return this._startAt; }
set startAt(value: D | number | null) {
this._startAt = this._getValidDateOrNull(this._dateAdapter.deserialize(value));
}
private _startAt: D | null;
private _startAt: D | number | null;

/** Whether the calendar should be started in month or year view. */
@Input() startView: SatCalendarView = 'month';
Expand Down Expand Up @@ -301,6 +310,33 @@ export class SatCalendar<D> implements AfterContentInit, AfterViewChecked, OnDes
/** Order the views when clicking on period label button */
@Input() orderPeriodLabel: 'multi-year' | 'month' = 'multi-year';

/** Initial selectiom mode */
@Input()
get initialSelectionMode(): SelectionModeType { return this._initialSelectionMode; }
set initialSelectionMode(mode: SelectionModeType) {
if (mode) {
this._initialSelectionMode = mode;
}
}
_initialSelectionMode = SelectionModeType.Default;

/** Selection mode */
@Input()
set selectionMode(mode) {
this._selectionMode = mode;
}
get selectionMode() {
if (!this._selectionMode) {
this._selectionMode = this.initialSelectionMode;
}

return this._selectionMode;
}
_selectionMode: SelectionModeType = this.initialSelectionMode;

/** Possible selection modes, in the order that they should appear */
@Input() selectionModes = [];

/** Emits when the currently selected date changes. */
@Output() readonly selectedChange: EventEmitter<D> = new EventEmitter<D>();

Expand Down Expand Up @@ -332,13 +368,13 @@ export class SatCalendar<D> implements AfterContentInit, AfterViewChecked, OnDes
* The current active date. This determines which time period is shown and which date is
* highlighted when using keyboard navigation.
*/
get activeDate(): D { return this._clampedActiveDate; }
set activeDate(value: D) {
get activeDate() { return this._clampedActiveDate; }
set activeDate(value) {
this._clampedActiveDate = this._dateAdapter.clampDate(value, this.minDate, this.maxDate);
this.stateChanges.next();
this._changeDetectorRef.markForCheck();
}
private _clampedActiveDate: D;
private _clampedActiveDate;

/** Whether the calendar is in month view. */
get currentView(): SatCalendarView { return this._currentView; }
Expand Down Expand Up @@ -419,29 +455,60 @@ export class SatCalendar<D> implements AfterContentInit, AfterViewChecked, OnDes
/** Updates today's date after an update of the active date */
updateTodaysDate() {
let view = this.currentView == 'month' ? this.monthView :
(this.currentView == 'year' ? this.yearView : this.multiYearView);
(this.currentView == 'year' ? this.yearView : this.multiYearView);

view.ngAfterContentInit();
}

/** Handles date selection in the month view. */
_dateSelected(date: D): void {
if (this.rangeMode) {
if (!this.beginDateSelected) {
this.beginDateSelected = date;
this.beginDate = date;
this.endDate = date;
this.beginDateSelectedChange.emit(date);
} else {
this.beginDateSelected = false;
if (this._dateAdapter.compareDate(<D>this.beginDate, date) <= 0) {
this.endDate = date;
} else {
this.endDate = this.beginDate;
this.beginDate = date;
}
this.dateRangesChange.emit({begin: <D>this.beginDate, end: this.endDate});
_dateSelected(date): void {
if (this.selectionMode == 'range') {

if (!this.beginDateSelected) {
this.beginDateSelected = date;
this.beginDate = date;
this.endDate = date;
this.beginDateSelectedChange.emit(date);
} else {
/*
Problem: Assign each date from the range accordingly with the user
selection, knowing that each "Date" assignment has to be cloned before,
preventing assigning a variable to a variable's reference.
Compare the two dates selected and if they are different,
clone them into new consts isolated in this iteration.
If they are equal just set both dates to
the "date" variable, as it only exists in this current iteration
Emit the change in the end
*/

this.beginDateSelected = false;
const sumDates = this._dateAdapter.compareDate(this.beginDate, date);

if (sumDates < 0) { // Seconds date is greater than first date
const start = new Date(this.beginDate.getTime());
const end = new Date(date.getTime());

this.beginDate = start;
this.endDate = end;
} else if (sumDates > 0) { // First date is greater than second date
const start = new Date(date.getTime());
const end = new Date(this.beginDate.getTime());

this.beginDate = start;
this.endDate = end;
} else { // Dates are equal
this.beginDate = this.endDate = date;
}

this.dateRangesChange.emit({begin: this.beginDate, end: this.endDate});
}
} else if (this.selectionMode === 'since') {
this.dateRangesChange.emit({begin: date, end: Infinity});
} else if (this.selectionMode === 'until') {
this.dateRangesChange.emit({begin: Infinity, end: date});
} else if (!this._dateAdapter.sameDate(date, this.selected)) {
this.selectedChange.emit(date);
}
Expand Down Expand Up @@ -472,7 +539,7 @@ export class SatCalendar<D> implements AfterContentInit, AfterViewChecked, OnDes
* @returns The given object if it is both a date instance and valid, otherwise null.
*/
private _getValidDateOrNull(obj: any): D | null {
return (this._dateAdapter.isDateInstance(obj) && this._dateAdapter.isValid(obj)) ? obj : null;
return (obj === Infinity || (this._dateAdapter.isDateInstance(obj) && this._dateAdapter.isValid(obj))) ? obj : null;
}

/** Returns the component instance that corresponds to the current calendar view. */
Expand Down
2 changes: 1 addition & 1 deletion saturn-datepicker/src/datepicker/datepicker-content.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion saturn-datepicker/src/datepicker/datepicker-content.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
(monthSelected)="datepicker._selectMonth($event)"
[beginDate]="datepicker._beginDate"
[endDate]="datepicker._endDate"
[rangeMode]="datepicker.rangeMode"
[selectionMode]="datepicker.selectionMode"
[selectionModes]="datepicker.selectionModes"
[initialSelectionMode]="datepicker.initialSelectionMode"
[closeAfterSelection]="datepicker.closeAfterSelection"
[orderPeriodLabel]="datepicker.orderPeriodLabel"
(dateRangesChange)="datepicker._selectRange($event)"
Expand Down
Loading

0 comments on commit 90d17c7

Please sign in to comment.