@imihai/angular-datetime-picker 21.0.0 → 21.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/style/picker.min.css +1 -0
- package/fesm2022/imihai-angular-datetime-picker.mjs +5845 -0
- package/fesm2022/imihai-angular-datetime-picker.mjs.map +1 -0
- package/imihai-angular-datetime-picker-21.0.2.tgz +0 -0
- package/package.json +33 -77
- package/types/imihai-angular-datetime-picker.d.ts +2193 -0
- package/.browserslistrc +0 -9
- package/.editorconfig +0 -13
- package/.eslintrc.js +0 -208
- package/.github/workflows/ci_test.yml +0 -35
- package/.prettierrc +0 -2
- package/.travis.yml +0 -16
- package/LICENSE +0 -22
- package/README.md +0 -194
- package/angular.json +0 -221
- package/e2e/protractor.conf.js +0 -28
- package/e2e/src/app.e2e-spec.ts +0 -14
- package/e2e/src/app.po.ts +0 -11
- package/e2e/tsconfig.e2e.json +0 -13
- package/projects/picker/karma.conf.js +0 -62
- package/projects/picker/ng-package.json +0 -7
- package/projects/picker/package.json +0 -28
- package/projects/picker/src/lib/date-time/adapter/date-time-adapter.class.ts +0 -313
- package/projects/picker/src/lib/date-time/adapter/date-time-format.class.ts +0 -18
- package/projects/picker/src/lib/date-time/adapter/luxon-date-time-adapter.class.ts +0 -307
- package/projects/picker/src/lib/date-time/adapter/luxon-date-time-format.class.ts +0 -11
- package/projects/picker/src/lib/date-time/adapter/luxon-date-time.module.ts +0 -31
- package/projects/picker/src/lib/date-time/adapter/unix-timestamp-adapter/unix-timestamp-date-time-adapter.class.ts +0 -356
- package/projects/picker/src/lib/date-time/adapter/unix-timestamp-adapter/unix-timestamp-date-time-format.class.ts +0 -14
- package/projects/picker/src/lib/date-time/adapter/unix-timestamp-adapter/unix-timestamp-date-time.module.ts +0 -26
- package/projects/picker/src/lib/date-time/calendar-body.component.html +0 -38
- package/projects/picker/src/lib/date-time/calendar-body.component.scss +0 -0
- package/projects/picker/src/lib/date-time/calendar-body.component.spec.ts +0 -120
- package/projects/picker/src/lib/date-time/calendar-body.component.ts +0 -190
- package/projects/picker/src/lib/date-time/calendar-month-view.component.html +0 -47
- package/projects/picker/src/lib/date-time/calendar-month-view.component.scss +0 -16
- package/projects/picker/src/lib/date-time/calendar-month-view.component.spec.ts +0 -394
- package/projects/picker/src/lib/date-time/calendar-month-view.component.ts +0 -705
- package/projects/picker/src/lib/date-time/calendar-multi-year-view.component.html +0 -44
- package/projects/picker/src/lib/date-time/calendar-multi-year-view.component.scss +0 -0
- package/projects/picker/src/lib/date-time/calendar-multi-year-view.component.spec.ts +0 -343
- package/projects/picker/src/lib/date-time/calendar-multi-year-view.component.ts +0 -465
- package/projects/picker/src/lib/date-time/calendar-year-view.component.html +0 -16
- package/projects/picker/src/lib/date-time/calendar-year-view.component.scss +0 -0
- package/projects/picker/src/lib/date-time/calendar-year-view.component.spec.ts +0 -381
- package/projects/picker/src/lib/date-time/calendar-year-view.component.ts +0 -549
- package/projects/picker/src/lib/date-time/calendar.component.html +0 -169
- package/projects/picker/src/lib/date-time/calendar.component.scss +0 -0
- package/projects/picker/src/lib/date-time/calendar.component.spec.ts +0 -592
- package/projects/picker/src/lib/date-time/calendar.component.ts +0 -496
- package/projects/picker/src/lib/date-time/date-time-inline.component.html +0 -1
- package/projects/picker/src/lib/date-time/date-time-inline.component.scss +0 -4
- package/projects/picker/src/lib/date-time/date-time-inline.component.ts +0 -365
- package/projects/picker/src/lib/date-time/date-time-picker-animation-event.ts +0 -4
- package/projects/picker/src/lib/date-time/date-time-picker-container.component.html +0 -126
- package/projects/picker/src/lib/date-time/date-time-picker-container.component.scss +0 -0
- package/projects/picker/src/lib/date-time/date-time-picker-container.component.ts +0 -631
- package/projects/picker/src/lib/date-time/date-time-picker-input.directive.ts +0 -851
- package/projects/picker/src/lib/date-time/date-time-picker-intl.service.ts +0 -76
- package/projects/picker/src/lib/date-time/date-time-picker-trigger.directive.ts +0 -88
- package/projects/picker/src/lib/date-time/date-time-picker.component.html +0 -0
- package/projects/picker/src/lib/date-time/date-time-picker.component.scss +0 -0
- package/projects/picker/src/lib/date-time/date-time-picker.component.spec.ts +0 -2648
- package/projects/picker/src/lib/date-time/date-time-picker.component.ts +0 -731
- package/projects/picker/src/lib/date-time/date-time.class.ts +0 -256
- package/projects/picker/src/lib/date-time/date-time.module.ts +0 -61
- package/projects/picker/src/lib/date-time/numberedFixLen.pipe.ts +0 -28
- package/projects/picker/src/lib/date-time/options-provider.ts +0 -44
- package/projects/picker/src/lib/date-time/timer-box.component.html +0 -79
- package/projects/picker/src/lib/date-time/timer-box.component.scss +0 -0
- package/projects/picker/src/lib/date-time/timer-box.component.ts +0 -175
- package/projects/picker/src/lib/date-time/timer.component.html +0 -58
- package/projects/picker/src/lib/date-time/timer.component.scss +0 -0
- package/projects/picker/src/lib/date-time/timer.component.spec.ts +0 -399
- package/projects/picker/src/lib/date-time/timer.component.ts +0 -371
- package/projects/picker/src/lib/dialog/dialog-config.class.ts +0 -220
- package/projects/picker/src/lib/dialog/dialog-container.component.html +0 -1
- package/projects/picker/src/lib/dialog/dialog-container.component.scss +0 -0
- package/projects/picker/src/lib/dialog/dialog-container.component.ts +0 -231
- package/projects/picker/src/lib/dialog/dialog-ref.class.ts +0 -178
- package/projects/picker/src/lib/dialog/dialog.module.ts +0 -25
- package/projects/picker/src/lib/dialog/dialog.service.ts +0 -353
- package/projects/picker/src/lib/utils/array.utils.ts +0 -12
- package/projects/picker/src/lib/utils/constants.ts +0 -59
- package/projects/picker/src/lib/utils/date.utils.ts +0 -97
- package/projects/picker/src/lib/utils/index.ts +0 -5
- package/projects/picker/src/lib/utils/object.utils.ts +0 -29
- package/projects/picker/src/public_api.ts +0 -56
- package/projects/picker/src/sass/picker.scss +0 -743
- package/projects/picker/src/test-helpers.ts +0 -125
- package/projects/picker/src/test.ts +0 -52
- package/projects/picker/tsconfig.lib.json +0 -18
- package/projects/picker/tsconfig.lib.prod.json +0 -7
- package/projects/picker/tsconfig.spec.json +0 -17
- package/projects/picker/tslint.json +0 -8
- package/src/app/app.component.html +0 -77
- package/src/app/app.component.scss +0 -32
- package/src/app/app.component.spec.ts +0 -16
- package/src/app/app.component.ts +0 -35
- package/src/assets/.gitkeep +0 -0
- package/src/environments/environment.prod.ts +0 -3
- package/src/environments/environment.ts +0 -16
- package/src/favicon.ico +0 -0
- package/src/index.html +0 -14
- package/src/karma.conf.js +0 -31
- package/src/main.ts +0 -16
- package/src/polyfills.ts +0 -53
- package/src/styles.scss +0 -7
- package/src/test.ts +0 -50
- package/src/tsconfig.app.json +0 -16
- package/src/tsconfig.spec.json +0 -18
- package/src/tslint.json +0 -17
- package/tsconfig.base.json +0 -29
- package/tsconfig.json +0 -30
- package/tslint.json +0 -130
|
@@ -1,731 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* date-time-picker.component
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
ChangeDetectionStrategy,
|
|
7
|
-
ChangeDetectorRef,
|
|
8
|
-
Component,
|
|
9
|
-
ComponentRef,
|
|
10
|
-
EventEmitter,
|
|
11
|
-
Inject,
|
|
12
|
-
InjectionToken,
|
|
13
|
-
Input,
|
|
14
|
-
NgZone,
|
|
15
|
-
OnDestroy,
|
|
16
|
-
OnInit,
|
|
17
|
-
Optional,
|
|
18
|
-
Output,
|
|
19
|
-
untracked,
|
|
20
|
-
ViewContainerRef
|
|
21
|
-
} from '@angular/core';
|
|
22
|
-
import { DOCUMENT } from '@angular/common';
|
|
23
|
-
import { ComponentPortal } from '@angular/cdk/portal';
|
|
24
|
-
import {
|
|
25
|
-
BlockScrollStrategy,
|
|
26
|
-
Overlay,
|
|
27
|
-
OverlayConfig,
|
|
28
|
-
OverlayRef,
|
|
29
|
-
PositionStrategy,
|
|
30
|
-
ScrollStrategy
|
|
31
|
-
} from '@angular/cdk/overlay';
|
|
32
|
-
import { ESCAPE, UP_ARROW } from '@angular/cdk/keycodes';
|
|
33
|
-
import { coerceArray, coerceBooleanProperty } from '@angular/cdk/coercion';
|
|
34
|
-
import { merge, Subscription } from 'rxjs';
|
|
35
|
-
import { filter, take } from 'rxjs/operators';
|
|
36
|
-
import { OwlDialogRef } from '../dialog/dialog-ref.class';
|
|
37
|
-
import { OwlDialogService } from '../dialog/dialog.service';
|
|
38
|
-
import { DateTimeAdapter } from './adapter/date-time-adapter.class';
|
|
39
|
-
import { OWL_DATE_TIME_FORMATS, OwlDateTimeFormats } from './adapter/date-time-format.class';
|
|
40
|
-
import { OwlDateTimeContainerComponent } from './date-time-picker-container.component';
|
|
41
|
-
import { OwlDateTimeInputDirective } from './date-time-picker-input.directive';
|
|
42
|
-
import { OwlDateTime, PickerMode, PickerType, SelectMode } from './date-time.class';
|
|
43
|
-
|
|
44
|
-
/** Injection token that determines the scroll handling while the dtPicker is open. */
|
|
45
|
-
export const OWL_DTPICKER_SCROLL_STRATEGY = new InjectionToken<
|
|
46
|
-
() => ScrollStrategy
|
|
47
|
-
>('owl-dtpicker-scroll-strategy');
|
|
48
|
-
|
|
49
|
-
/** @docs-private */
|
|
50
|
-
export function OWL_DTPICKER_SCROLL_STRATEGY_PROVIDER_FACTORY(
|
|
51
|
-
overlay: Overlay
|
|
52
|
-
): () => BlockScrollStrategy {
|
|
53
|
-
const fn = () => overlay.scrollStrategies.block();
|
|
54
|
-
return fn;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/** @docs-private */
|
|
58
|
-
export const OWL_DTPICKER_SCROLL_STRATEGY_PROVIDER = {
|
|
59
|
-
provide: OWL_DTPICKER_SCROLL_STRATEGY,
|
|
60
|
-
deps: [Overlay],
|
|
61
|
-
useFactory: OWL_DTPICKER_SCROLL_STRATEGY_PROVIDER_FACTORY
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
@Component({
|
|
65
|
-
selector: 'owl-date-time',
|
|
66
|
-
exportAs: 'owlDateTime',
|
|
67
|
-
templateUrl: './date-time-picker.component.html',
|
|
68
|
-
styleUrls: ['./date-time-picker.component.scss'],
|
|
69
|
-
standalone: false,
|
|
70
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
71
|
-
preserveWhitespaces: false
|
|
72
|
-
})
|
|
73
|
-
export class OwlDateTimeComponent<T> extends OwlDateTime<T>
|
|
74
|
-
implements OnInit, OnDestroy {
|
|
75
|
-
/** Custom class for the picker backdrop. */
|
|
76
|
-
@Input()
|
|
77
|
-
public backdropClass: string | string[] = [];
|
|
78
|
-
|
|
79
|
-
/** Custom class for the picker overlay pane. */
|
|
80
|
-
@Input()
|
|
81
|
-
public panelClass: string | string[] = [];
|
|
82
|
-
|
|
83
|
-
/** The date to open the calendar to initially. */
|
|
84
|
-
private _startAt: T | null;
|
|
85
|
-
@Input()
|
|
86
|
-
get startAt(): T | null {
|
|
87
|
-
// If an explicit startAt is set we start there, otherwise we start at whatever the currently
|
|
88
|
-
// selected value is.
|
|
89
|
-
if (this._startAt) {
|
|
90
|
-
return this._startAt;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (this._dtInput) {
|
|
94
|
-
if (this._dtInput.selectMode === 'single') {
|
|
95
|
-
return this._dtInput.value || null;
|
|
96
|
-
} else if (
|
|
97
|
-
this._dtInput.selectMode === 'range' ||
|
|
98
|
-
this._dtInput.selectMode === 'rangeFrom'
|
|
99
|
-
) {
|
|
100
|
-
return this._dtInput.values[0] || null;
|
|
101
|
-
} else if (this._dtInput.selectMode === 'rangeTo') {
|
|
102
|
-
return this._dtInput.values[1] || null;
|
|
103
|
-
}
|
|
104
|
-
} else {
|
|
105
|
-
return null;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
set startAt(date: T | null) {
|
|
110
|
-
this._startAt = this.getValidDate(
|
|
111
|
-
this.dateTimeAdapter.deserialize(date)
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/** The end date to set for range calendar. */
|
|
116
|
-
private _endAt: T | null;
|
|
117
|
-
@Input()
|
|
118
|
-
get endAt(): T | null {
|
|
119
|
-
if (this._endAt) {
|
|
120
|
-
return this._endAt;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (this._dtInput) {
|
|
124
|
-
if (this._dtInput.selectMode === 'single') {
|
|
125
|
-
return this._dtInput.value || null;
|
|
126
|
-
} else if (
|
|
127
|
-
this._dtInput.selectMode === 'range' ||
|
|
128
|
-
this._dtInput.selectMode === 'rangeFrom'
|
|
129
|
-
) {
|
|
130
|
-
return this._dtInput.values[1] || null;
|
|
131
|
-
}
|
|
132
|
-
} else {
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
set endAt(date: T | null) {
|
|
138
|
-
this._endAt = this.getValidDate(
|
|
139
|
-
this.dateTimeAdapter.deserialize(date)
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Set the type of the dateTime picker
|
|
145
|
-
* 'both' -- show both calendar and timer
|
|
146
|
-
* 'calendar' -- show only calendar
|
|
147
|
-
* 'timer' -- show only timer
|
|
148
|
-
*/
|
|
149
|
-
private _pickerType: PickerType = 'both';
|
|
150
|
-
@Input()
|
|
151
|
-
get pickerType(): PickerType {
|
|
152
|
-
return this._pickerType;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
set pickerType(val: PickerType) {
|
|
156
|
-
if (val !== this._pickerType) {
|
|
157
|
-
this._pickerType = val;
|
|
158
|
-
if (this._dtInput) {
|
|
159
|
-
this._dtInput.formatNativeInputValue();
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Whether the picker open as a dialog
|
|
166
|
-
*/
|
|
167
|
-
_pickerMode: PickerMode = 'popup';
|
|
168
|
-
@Input()
|
|
169
|
-
get pickerMode() {
|
|
170
|
-
return this._pickerMode;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
set pickerMode(mode: PickerMode) {
|
|
174
|
-
if (mode === 'popup') {
|
|
175
|
-
this._pickerMode = mode;
|
|
176
|
-
} else {
|
|
177
|
-
this._pickerMode = 'dialog';
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/** Whether the date time picker should be disabled. */
|
|
182
|
-
private _disabled: boolean;
|
|
183
|
-
@Input()
|
|
184
|
-
get disabled(): boolean {
|
|
185
|
-
return this._disabled === undefined && this._dtInput
|
|
186
|
-
? this._dtInput.disabled
|
|
187
|
-
: !!this._disabled;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
set disabled(value: boolean) {
|
|
191
|
-
value = coerceBooleanProperty(value);
|
|
192
|
-
if (value !== this._disabled) {
|
|
193
|
-
this._disabled = value;
|
|
194
|
-
this.disabledChange.next(value);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/** Whether the calendar is open. */
|
|
199
|
-
private _opened = false;
|
|
200
|
-
@Input()
|
|
201
|
-
get opened(): boolean {
|
|
202
|
-
return this._opened;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
set opened(val: boolean) {
|
|
206
|
-
val ? this.open() : this.close();
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* The scroll strategy when the picker is open
|
|
211
|
-
* Learn more this from https://material.angular.io/cdk/overlay/overview#scroll-strategies
|
|
212
|
-
* */
|
|
213
|
-
@Input()
|
|
214
|
-
public scrollStrategy: ScrollStrategy;
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Callback when the picker is closed
|
|
218
|
-
* */
|
|
219
|
-
@Output()
|
|
220
|
-
afterPickerClosed = new EventEmitter<any>();
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Callback before the picker is open
|
|
224
|
-
* */
|
|
225
|
-
@Output()
|
|
226
|
-
beforePickerOpen = new EventEmitter<any>();
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Callback when the picker is open
|
|
230
|
-
* */
|
|
231
|
-
@Output()
|
|
232
|
-
afterPickerOpen = new EventEmitter<any>();
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Emits selected year in multi-year view
|
|
236
|
-
* This doesn't imply a change on the selected date.
|
|
237
|
-
* */
|
|
238
|
-
@Output()
|
|
239
|
-
yearSelected = new EventEmitter<T>();
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Emits selected month in year view
|
|
243
|
-
* This doesn't imply a change on the selected date.
|
|
244
|
-
* */
|
|
245
|
-
@Output()
|
|
246
|
-
monthSelected = new EventEmitter<T>();
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Emits selected date
|
|
250
|
-
* */
|
|
251
|
-
@Output()
|
|
252
|
-
dateSelected = new EventEmitter<T>();
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Emit when the selected value has been confirmed
|
|
256
|
-
* */
|
|
257
|
-
public confirmSelectedChange = new EventEmitter<T[] | T>();
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* Emits when the date time picker is disabled.
|
|
261
|
-
* */
|
|
262
|
-
public disabledChange = new EventEmitter<boolean>();
|
|
263
|
-
|
|
264
|
-
private pickerContainerPortal: ComponentPortal<
|
|
265
|
-
OwlDateTimeContainerComponent<T>
|
|
266
|
-
>;
|
|
267
|
-
private pickerContainer: OwlDateTimeContainerComponent<T>;
|
|
268
|
-
private popupRef: OverlayRef;
|
|
269
|
-
private dialogRef: OwlDialogRef<OwlDateTimeContainerComponent<T>>;
|
|
270
|
-
private dtInputSub = Subscription.EMPTY;
|
|
271
|
-
private hidePickerStreamSub = Subscription.EMPTY;
|
|
272
|
-
private confirmSelectedStreamSub = Subscription.EMPTY;
|
|
273
|
-
private pickerOpenedStreamSub = Subscription.EMPTY;
|
|
274
|
-
private pickerBeforeOpenedStreamSub = Subscription.EMPTY;
|
|
275
|
-
|
|
276
|
-
/** The element that was focused before the date time picker was opened. */
|
|
277
|
-
private focusedElementBeforeOpen: HTMLElement | null = null;
|
|
278
|
-
|
|
279
|
-
private _dtInput: OwlDateTimeInputDirective<T>;
|
|
280
|
-
get dtInput() {
|
|
281
|
-
return this._dtInput;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
private _selected: T | null;
|
|
285
|
-
get selected() {
|
|
286
|
-
return this._selected;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
set selected(value: T | null) {
|
|
290
|
-
this._selected = value;
|
|
291
|
-
this.changeDetector.markForCheck();
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
private _selecteds: T[] = [];
|
|
295
|
-
get selecteds() {
|
|
296
|
-
return this._selecteds;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
set selecteds(values: T[]) {
|
|
300
|
-
this._selecteds = values;
|
|
301
|
-
this.changeDetector.markForCheck();
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/** The minimum selectable date. */
|
|
305
|
-
get minDateTime(): T | null {
|
|
306
|
-
return this._dtInput && this._dtInput.min;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/** The maximum selectable date. */
|
|
310
|
-
get maxDateTime(): T | null {
|
|
311
|
-
return this._dtInput && this._dtInput.max;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
get dateTimeFilter(): (date: T | null) => boolean {
|
|
315
|
-
return this._dtInput && this._dtInput.dateTimeFilter;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
get selectMode(): SelectMode {
|
|
319
|
-
return this._dtInput.selectMode;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
get isInSingleMode(): boolean {
|
|
323
|
-
return this._dtInput.isInSingleMode;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
get isInRangeMode(): boolean {
|
|
327
|
-
return this._dtInput.isInRangeMode;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
private readonly defaultScrollStrategy: () => ScrollStrategy;
|
|
331
|
-
|
|
332
|
-
constructor(
|
|
333
|
-
public overlay: Overlay,
|
|
334
|
-
private viewContainerRef: ViewContainerRef,
|
|
335
|
-
private dialogService: OwlDialogService,
|
|
336
|
-
private ngZone: NgZone,
|
|
337
|
-
protected changeDetector: ChangeDetectorRef,
|
|
338
|
-
@Optional() protected dateTimeAdapter: DateTimeAdapter<T>,
|
|
339
|
-
@Inject(OWL_DTPICKER_SCROLL_STRATEGY) defaultScrollStrategy: any,
|
|
340
|
-
@Optional()
|
|
341
|
-
@Inject(OWL_DATE_TIME_FORMATS)
|
|
342
|
-
protected dateTimeFormats: OwlDateTimeFormats,
|
|
343
|
-
@Optional()
|
|
344
|
-
@Inject(DOCUMENT)
|
|
345
|
-
private document: any
|
|
346
|
-
) {
|
|
347
|
-
super(dateTimeAdapter, dateTimeFormats);
|
|
348
|
-
this.defaultScrollStrategy = defaultScrollStrategy;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
public ngOnInit() {}
|
|
352
|
-
|
|
353
|
-
public ngOnDestroy(): void {
|
|
354
|
-
this.close();
|
|
355
|
-
this.dtInputSub.unsubscribe();
|
|
356
|
-
this.disabledChange.complete();
|
|
357
|
-
|
|
358
|
-
if (this.popupRef) {
|
|
359
|
-
this.popupRef.dispose();
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
public registerInput(input: OwlDateTimeInputDirective<T>): void {
|
|
364
|
-
if (this._dtInput) {
|
|
365
|
-
throw Error(
|
|
366
|
-
'A Owl DateTimePicker can only be associated with a single input.'
|
|
367
|
-
);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
this._dtInput = input;
|
|
371
|
-
this.dtInputSub = this._dtInput.valueChange.subscribe(
|
|
372
|
-
(value: T[] | T | null) => {
|
|
373
|
-
if (Array.isArray(value)) {
|
|
374
|
-
this.selecteds = value;
|
|
375
|
-
} else {
|
|
376
|
-
this.selected = value;
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
public open(): void {
|
|
383
|
-
if (this._opened || this.disabled) {
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
if (!this._dtInput) {
|
|
388
|
-
throw Error(
|
|
389
|
-
'Attempted to open an DateTimePicker with no associated input.'
|
|
390
|
-
);
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
if (this.document) {
|
|
394
|
-
this.focusedElementBeforeOpen = this.document.activeElement;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
// reset the picker selected value
|
|
398
|
-
if (this.isInSingleMode) {
|
|
399
|
-
this.selected = this._dtInput.value;
|
|
400
|
-
} else if (this.isInRangeMode) {
|
|
401
|
-
this.selecteds = this._dtInput.values;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
// when the picker is open , we make sure the picker's current selected time value
|
|
405
|
-
// is the same as the _startAt time value.
|
|
406
|
-
if (this.selected && this.pickerType !== 'calendar' && this._startAt) {
|
|
407
|
-
this.selected = this.dateTimeAdapter.createDate(
|
|
408
|
-
this.dateTimeAdapter.getYear(this.selected),
|
|
409
|
-
this.dateTimeAdapter.getMonth(this.selected),
|
|
410
|
-
this.dateTimeAdapter.getDate(this.selected),
|
|
411
|
-
this.dateTimeAdapter.getHours(this._startAt),
|
|
412
|
-
this.dateTimeAdapter.getMinutes(this._startAt),
|
|
413
|
-
this.dateTimeAdapter.getSeconds(this._startAt)
|
|
414
|
-
);
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
this.pickerMode === 'dialog' ? this.openAsDialog() : this.openAsPopup();
|
|
418
|
-
|
|
419
|
-
this.pickerContainer.picker = this;
|
|
420
|
-
|
|
421
|
-
// Listen to picker container's hidePickerStream
|
|
422
|
-
this.hidePickerStreamSub = this.pickerContainer.hidePickerStream.subscribe(
|
|
423
|
-
() => {
|
|
424
|
-
this.close();
|
|
425
|
-
}
|
|
426
|
-
);
|
|
427
|
-
|
|
428
|
-
// Listen to picker container's confirmSelectedStream
|
|
429
|
-
this.confirmSelectedStreamSub = this.pickerContainer.confirmSelectedStream.subscribe(
|
|
430
|
-
(event: any) => {
|
|
431
|
-
this.confirmSelect(event);
|
|
432
|
-
}
|
|
433
|
-
);
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
/**
|
|
437
|
-
* Selects the given date
|
|
438
|
-
*/
|
|
439
|
-
public select(date: T[] | T): void {
|
|
440
|
-
if (Array.isArray(date)) {
|
|
441
|
-
this.selecteds = [...date];
|
|
442
|
-
} else {
|
|
443
|
-
this.selected = date;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
/**
|
|
447
|
-
* Cases in which automatically confirm the select when date or dates are selected:
|
|
448
|
-
* 1) picker mode is NOT 'dialog'
|
|
449
|
-
* 2) picker type is 'calendar' and selectMode is 'single'.
|
|
450
|
-
* 3) picker type is 'calendar' and selectMode is 'range' and
|
|
451
|
-
* the 'selecteds' has 'from'(selecteds[0]) and 'to'(selecteds[1]) values.
|
|
452
|
-
* 4) selectMode is 'rangeFrom' and selecteds[0] has value.
|
|
453
|
-
* 5) selectMode is 'rangeTo' and selecteds[1] has value.
|
|
454
|
-
* */
|
|
455
|
-
if (
|
|
456
|
-
this.pickerMode !== 'dialog' &&
|
|
457
|
-
this.pickerType === 'calendar' &&
|
|
458
|
-
((this.selectMode === 'single' && this.selected) ||
|
|
459
|
-
(this.selectMode === 'rangeFrom' && this.selecteds[0]) ||
|
|
460
|
-
(this.selectMode === 'rangeTo' && this.selecteds[1]) ||
|
|
461
|
-
(this.selectMode === 'range' &&
|
|
462
|
-
this.selecteds[0] &&
|
|
463
|
-
this.selecteds[1]))
|
|
464
|
-
) {
|
|
465
|
-
this.confirmSelect();
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* Emits the selected year in multi-year view
|
|
471
|
-
* */
|
|
472
|
-
public selectYear(normalizedYear: T): void {
|
|
473
|
-
this.yearSelected.emit(normalizedYear);
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
/**
|
|
477
|
-
* Emits selected month in year view
|
|
478
|
-
* */
|
|
479
|
-
public selectMonth(normalizedMonth: T): void {
|
|
480
|
-
this.monthSelected.emit(normalizedMonth);
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
/**
|
|
484
|
-
* Emits the selected date
|
|
485
|
-
* */
|
|
486
|
-
public selectDate(normalizedDate: T): void {
|
|
487
|
-
this.dateSelected.emit(normalizedDate);
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
/**
|
|
491
|
-
* Hide the picker
|
|
492
|
-
*/
|
|
493
|
-
public close(): void {
|
|
494
|
-
if (!this._opened) {
|
|
495
|
-
return;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
if (this.popupRef && this.popupRef.hasAttached()) {
|
|
499
|
-
this.popupRef.detach();
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
if (
|
|
503
|
-
this.pickerContainerPortal &&
|
|
504
|
-
this.pickerContainerPortal.isAttached
|
|
505
|
-
) {
|
|
506
|
-
this.pickerContainerPortal.detach();
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
if (this.hidePickerStreamSub) {
|
|
510
|
-
this.hidePickerStreamSub.unsubscribe();
|
|
511
|
-
this.hidePickerStreamSub = null;
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
if (this.confirmSelectedStreamSub) {
|
|
515
|
-
this.confirmSelectedStreamSub.unsubscribe();
|
|
516
|
-
this.confirmSelectedStreamSub = null;
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
if (this.pickerBeforeOpenedStreamSub) {
|
|
520
|
-
this.pickerBeforeOpenedStreamSub.unsubscribe();
|
|
521
|
-
this.pickerBeforeOpenedStreamSub = null;
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
if (this.pickerOpenedStreamSub) {
|
|
525
|
-
this.pickerOpenedStreamSub.unsubscribe();
|
|
526
|
-
this.pickerOpenedStreamSub = null;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
if (this.dialogRef) {
|
|
530
|
-
this.dialogRef.close();
|
|
531
|
-
this.dialogRef = null;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
const completeClose = () => {
|
|
535
|
-
if (this._opened) {
|
|
536
|
-
this._opened = false;
|
|
537
|
-
const selected = this.selected || this.selecteds;
|
|
538
|
-
this.afterPickerClosed.emit(selected);
|
|
539
|
-
this.focusedElementBeforeOpen = null;
|
|
540
|
-
}
|
|
541
|
-
};
|
|
542
|
-
|
|
543
|
-
if (
|
|
544
|
-
this.focusedElementBeforeOpen &&
|
|
545
|
-
typeof this.focusedElementBeforeOpen.focus === 'function'
|
|
546
|
-
) {
|
|
547
|
-
// Because IE moves focus asynchronously, we can't count on it being restored before we've
|
|
548
|
-
// marked the datepicker as closed. If the event fires out of sequence and the element that
|
|
549
|
-
// we're refocusing opens the datepicker on focus, the user could be stuck with not being
|
|
550
|
-
// able to close the calendar at all. We work around it by making the logic, that marks
|
|
551
|
-
// the datepicker as closed, async as well.
|
|
552
|
-
this.focusedElementBeforeOpen.focus();
|
|
553
|
-
setTimeout(completeClose);
|
|
554
|
-
} else {
|
|
555
|
-
completeClose();
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
/**
|
|
560
|
-
* Confirm the selected value
|
|
561
|
-
*/
|
|
562
|
-
public confirmSelect(event?: any): void {
|
|
563
|
-
if (this.isInSingleMode) {
|
|
564
|
-
const selected =
|
|
565
|
-
this.selected || this.startAt || this.dateTimeAdapter.now();
|
|
566
|
-
this.confirmSelectedChange.emit(selected);
|
|
567
|
-
} else if (this.isInRangeMode) {
|
|
568
|
-
this.confirmSelectedChange.emit(this.selecteds);
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
this.close();
|
|
572
|
-
return;
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
/**
|
|
576
|
-
* Open the picker as a dialog
|
|
577
|
-
*/
|
|
578
|
-
private openAsDialog(): void {
|
|
579
|
-
this.dialogRef = this.dialogService.open(
|
|
580
|
-
OwlDateTimeContainerComponent,
|
|
581
|
-
{
|
|
582
|
-
autoFocus: false,
|
|
583
|
-
backdropClass: [
|
|
584
|
-
'cdk-overlay-dark-backdrop',
|
|
585
|
-
...coerceArray(this.backdropClass)
|
|
586
|
-
],
|
|
587
|
-
paneClass: ['owl-dt-dialog', ...coerceArray(this.panelClass)],
|
|
588
|
-
viewContainerRef: this.viewContainerRef,
|
|
589
|
-
scrollStrategy:
|
|
590
|
-
this.scrollStrategy || this.defaultScrollStrategy()
|
|
591
|
-
}
|
|
592
|
-
);
|
|
593
|
-
this.pickerContainer = untracked(this.dialogRef.componentInstance);
|
|
594
|
-
|
|
595
|
-
this.dialogRef.beforeOpen().subscribe(() => {
|
|
596
|
-
this.beforePickerOpen.emit(null);
|
|
597
|
-
});
|
|
598
|
-
this.dialogRef.afterOpen().subscribe(() => {
|
|
599
|
-
this.afterPickerOpen.emit(null);
|
|
600
|
-
this._opened = true;
|
|
601
|
-
});
|
|
602
|
-
this.dialogRef.afterClosed().subscribe(() => this.close());
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
/**
|
|
606
|
-
* Open the picker as popup
|
|
607
|
-
*/
|
|
608
|
-
private openAsPopup(): void {
|
|
609
|
-
if (!this.pickerContainerPortal) {
|
|
610
|
-
this.pickerContainerPortal = new ComponentPortal<
|
|
611
|
-
OwlDateTimeContainerComponent<T>
|
|
612
|
-
>(OwlDateTimeContainerComponent, this.viewContainerRef);
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
if (!this.popupRef) {
|
|
616
|
-
this.createPopup();
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
if (!this.popupRef.hasAttached()) {
|
|
620
|
-
const componentRef: ComponentRef<
|
|
621
|
-
OwlDateTimeContainerComponent<T>
|
|
622
|
-
> = this.popupRef.attach(this.pickerContainerPortal);
|
|
623
|
-
this.pickerContainer = componentRef.instance;
|
|
624
|
-
|
|
625
|
-
// Update the position once the calendar has rendered.
|
|
626
|
-
this.ngZone.onStable
|
|
627
|
-
.asObservable()
|
|
628
|
-
.pipe(take(1))
|
|
629
|
-
.subscribe(() => {
|
|
630
|
-
this.popupRef.updatePosition();
|
|
631
|
-
});
|
|
632
|
-
|
|
633
|
-
this.pickerBeforeOpenedStreamSub = this.pickerContainer.beforePickerOpenedStream
|
|
634
|
-
.pipe(take(1))
|
|
635
|
-
.subscribe(() => {
|
|
636
|
-
this.beforePickerOpen.emit(null);
|
|
637
|
-
});
|
|
638
|
-
|
|
639
|
-
// emit open stream
|
|
640
|
-
this.pickerOpenedStreamSub = this.pickerContainer.pickerOpenedStream
|
|
641
|
-
.pipe(take(1))
|
|
642
|
-
.subscribe(() => {
|
|
643
|
-
this.afterPickerOpen.emit(null);
|
|
644
|
-
this._opened = true;
|
|
645
|
-
});
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
private createPopup(): void {
|
|
650
|
-
const overlayConfig = new OverlayConfig({
|
|
651
|
-
positionStrategy: this.createPopupPositionStrategy(),
|
|
652
|
-
hasBackdrop: true,
|
|
653
|
-
backdropClass: [
|
|
654
|
-
'cdk-overlay-transparent-backdrop',
|
|
655
|
-
...coerceArray(this.backdropClass)
|
|
656
|
-
],
|
|
657
|
-
scrollStrategy: this.scrollStrategy || this.defaultScrollStrategy(),
|
|
658
|
-
panelClass: ['owl-dt-popup', ...coerceArray(this.panelClass)]
|
|
659
|
-
});
|
|
660
|
-
|
|
661
|
-
this.popupRef = this.overlay.create(overlayConfig);
|
|
662
|
-
|
|
663
|
-
merge(
|
|
664
|
-
this.popupRef.backdropClick(),
|
|
665
|
-
this.popupRef.detachments(),
|
|
666
|
-
this.popupRef
|
|
667
|
-
.keydownEvents()
|
|
668
|
-
.pipe(
|
|
669
|
-
filter(
|
|
670
|
-
event =>
|
|
671
|
-
event.keyCode === ESCAPE ||
|
|
672
|
-
(this._dtInput &&
|
|
673
|
-
event.altKey &&
|
|
674
|
-
event.keyCode === UP_ARROW)
|
|
675
|
-
)
|
|
676
|
-
)
|
|
677
|
-
).subscribe(() => this.close());
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
/**
|
|
681
|
-
* Create the popup PositionStrategy.
|
|
682
|
-
* */
|
|
683
|
-
private createPopupPositionStrategy(): PositionStrategy {
|
|
684
|
-
return this.overlay
|
|
685
|
-
.position()
|
|
686
|
-
.flexibleConnectedTo(this._dtInput.elementRef)
|
|
687
|
-
.withTransformOriginOn('.owl-dt-container')
|
|
688
|
-
.withFlexibleDimensions(false)
|
|
689
|
-
.withPush(false)
|
|
690
|
-
.withPositions([
|
|
691
|
-
{
|
|
692
|
-
originX: 'start',
|
|
693
|
-
originY: 'bottom',
|
|
694
|
-
overlayX: 'start',
|
|
695
|
-
overlayY: 'top'
|
|
696
|
-
},
|
|
697
|
-
{
|
|
698
|
-
originX: 'start',
|
|
699
|
-
originY: 'top',
|
|
700
|
-
overlayX: 'start',
|
|
701
|
-
overlayY: 'bottom'
|
|
702
|
-
},
|
|
703
|
-
{
|
|
704
|
-
originX: 'end',
|
|
705
|
-
originY: 'bottom',
|
|
706
|
-
overlayX: 'end',
|
|
707
|
-
overlayY: 'top'
|
|
708
|
-
},
|
|
709
|
-
{
|
|
710
|
-
originX: 'end',
|
|
711
|
-
originY: 'top',
|
|
712
|
-
overlayX: 'end',
|
|
713
|
-
overlayY: 'bottom'
|
|
714
|
-
},
|
|
715
|
-
{
|
|
716
|
-
originX: 'start',
|
|
717
|
-
originY: 'top',
|
|
718
|
-
overlayX: 'start',
|
|
719
|
-
overlayY: 'top',
|
|
720
|
-
offsetY: -176
|
|
721
|
-
},
|
|
722
|
-
{
|
|
723
|
-
originX: 'start',
|
|
724
|
-
originY: 'top',
|
|
725
|
-
overlayX: 'start',
|
|
726
|
-
overlayY: 'top',
|
|
727
|
-
offsetY: -352
|
|
728
|
-
}
|
|
729
|
-
]);
|
|
730
|
-
}
|
|
731
|
-
}
|