@catull/igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
1,241 lines • 141 kB
JavaScript
var IgxDatePickerComponent_1;
import { __decorate, __metadata, __param } from "tslib";
import { CommonModule, formatDate } from '@angular/common';
import { Component, ContentChild, EventEmitter, HostBinding, Input, NgModule, OnDestroy, Output, ViewChild, ElementRef, TemplateRef, Inject, ChangeDetectorRef, HostListener, NgModuleRef, OnInit, AfterViewInit } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { IgxCalendarHeaderTemplateDirective, IgxCalendarModule, IgxCalendarSubheaderTemplateDirective, WEEKDAYS, isDateInRanges } from '../calendar/index';
import { IgxIconModule } from '../icon/index';
import { IgxInputGroupModule, IgxInputDirective, IgxInputGroupComponent } from '../input-group/index';
import { Subject, fromEvent, animationFrameScheduler, interval } from 'rxjs';
import { filter, takeUntil, throttle } from 'rxjs/operators';
import { IgxTextSelectionModule } from '../directives/text-selection/text-selection.directive';
import { OverlaySettings, IgxOverlayService, PositionSettings, AbsoluteScrollStrategy, AutoPositionStrategy, OverlayCancelableEventArgs } from '../services/index';
import { IgxButtonModule } from '../directives/button/button.directive';
import { IgxRippleModule } from '../directives/ripple/ripple.directive';
import { IgxMaskModule } from '../directives/mask/mask.directive';
import { DatePickerUtil } from './date-picker.utils';
import { DatePickerDisplayValuePipe, DatePickerInputValuePipe } from './date-picker.pipes';
import { isIE, isEqual } from '../core/utils';
import { IgxDatePickerTemplateDirective, IgxDatePickerActionsDirective } from './date-picker.directives';
import { IgxCalendarContainerComponent } from './calendar-container.component';
import { InteractionMode } from '../core/enums';
import { fadeIn, fadeOut } from '../animations/fade';
import { DeprecateProperty } from '../core/deprecateDecorators';
let NEXT_ID = 0;
/**
* This enumeration is used to configure the date picker to operate with pre-defined format option used in Angular DatePipe.
* 'https://angular.io/api/common/DatePipe'
* 'shortDate': equivalent to 'M/d/yy' (6/15/15).
* 'mediumDate': equivalent to 'MMM d, y' (Jun 15, 2015).
* 'longDate': equivalent to 'MMMM d, y' (June 15, 2015).
* 'fullDate': equivalent to 'EEEE, MMMM d, y' (Monday, June 15, 2015).
*/
export var PredefinedFormatOptions;
(function (PredefinedFormatOptions) {
PredefinedFormatOptions["ShortDate"] = "shortDate";
PredefinedFormatOptions["MediumDate"] = "mediumDate";
PredefinedFormatOptions["LongDate"] = "longDate";
PredefinedFormatOptions["FullDate"] = "fullDate";
})(PredefinedFormatOptions || (PredefinedFormatOptions = {}));
/**
* **Ignite UI for Angular Date Picker** -
* [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/date_picker.html)
*
* The Ignite UI Date Picker displays a popup calendar that lets users select a single date.
*
* Example:
* ```html
* <igx-date-picker [(ngModel)]="selectedDate"></igx-date-picker>
* ```
*/
let IgxDatePickerComponent = IgxDatePickerComponent_1 = class IgxDatePickerComponent {
constructor(_overlayService, element, _cdr, _moduleRef) {
this._overlayService = _overlayService;
this.element = element;
this._cdr = _cdr;
this._moduleRef = _moduleRef;
/**
* An @Input property that sets the `IgxDatePickerComponent` label.
* The default label is 'Date'.
* ```html
* <igx-date-picker [label]="Calendar"></igx-date-picker>
* ```
*/
this.label = 'Date';
/**
* An @Input property that sets the `IgxDatePickerComponent` label visibility.
* By default the visibility is set to true.
* <igx-date-picker [labelVisibility]="false"></igx-date-picker>
*/
this.labelVisibility = true;
/**
*An @Input property that sets on which day the week starts.
*```html
*<igx-date-picker [weekStart]="WEEKDAYS.FRIDAY" cancelButtonLabel="cancel" todayButtonLabel="today"></igx-date-picker>
*```
*/
this.weekStart = WEEKDAYS.SUNDAY;
/**
* Sets/gets the number of month views displayed.
* Default value is `1`.
* ```html
* <igx-date-picker [monthsViewNumber]="2"></igx-date-picker>
* ```
* ```typescript
* let monthViewsDisplayed = this.datePicker.monthsViewNumber;
* ```
*/
this.monthsViewNumber = 1;
/**
*An @Input property that sets the value of `id` attribute. If not provided it will be automatically generated.
*```html
*<igx-date-picker [id]="'igx-date-picker-3'" cancelButtonLabel="cancel" todayButtonLabel="today"></igx-date-picker>
*```
*/
this.id = `igx-date-picker-${NEXT_ID++}`;
/**
*An @Input property that sets the orientation of the `IgxDatePickerComponent` header.
*```html
*<igx-date-picker [vertical]="'true'" cancelButtonLabel="cancel" todayButtonLabel="today"></igx-date-picker>
*```
*/
this.vertical = false;
/**
*An @Input property that sets whether `IgxDatePickerComponent` is in dialog or drop down mode.
*```html
*<igx-date-picker mode="dropdown"></igx-date-picker>
*```
*/
this.mode = InteractionMode.Dialog;
/**
*An @Input property that sets whether the `IgxDatePickerComponent` date parts would spin continuously or stop when min/max is reached.
*```html
*<igx-date-picker [isSpinLoop]="false"></igx-date-picker>
*```
*/
this.isSpinLoop = true;
/**
*An event that is emitted when the `IgxDatePickerComponent` calendar is opened.
*/
this.onOpened = new EventEmitter();
/**
*An event that is emitted after the `IgxDatePickerComponent` is closed.
*/
this.onClosed = new EventEmitter();
/**
* An event that is emitted when the `IgxDatePickerComponent` is being closed.
*/
this.onClosing = new EventEmitter();
/**
*An @Output property that is fired when selection is made in the calendar.
*```typescript
*public selection(event){
* alert("A date has been selected!");
*}
*```
*```html
*<igx-date-picker (onSelection)="selection($event)" cancelButtonLabel="cancel" todayButtonLabel="today"></igx-date-picker>
*```
*/
this.onSelection = new EventEmitter();
/**
*An @Output property that is fired when date picker value is changed.
*```typescript
*public valueChanged(event){
* alert("Date picker value is changed");
*}
*```
*```html
*<igx-date-picker (valueChange)="valueChanged($event)" mode="dropdown"></igx-date-picker>
*```
*/
this.valueChange = new EventEmitter();
/**
*An @Output property that fires when the user types/spins to a disabled date in the date-picker editor.
*```typescript
*public onDisabledDate(event){
* alert("This date is disabled!");
*}
*```
*```html
*<igx-date-picker (onDisabledDate)="onDisabledDate($event)"></igx-date-picker>
*```
*/
this.onDisabledDate = new EventEmitter();
/**
*An @Output property that fires when the user types/spins invalid date in the date-picker editor.
*```typescript
*public onValidationFailed(event){
* alert("This date is not valid!");
*}
*```
*```html
*<igx-date-picker (onValidationFailed)="onValidationFailed($event)"></igx-date-picker>
*```
*/
this.onValidationFailed = new EventEmitter();
this.hasHeader = true;
this.collapsed = true;
this.displayValuePipe = new DatePickerDisplayValuePipe(this);
this.inputValuePipe = new DatePickerInputValuePipe(this);
this.dateFormatParts = [];
this.isEmpty = true;
this.invalidDate = '';
this.spinDelta = 1;
this.defaultLocale = 'en';
this._formatOptions = {
day: 'numeric',
month: 'short',
weekday: 'short',
year: 'numeric'
};
this._formatViews = {
day: false,
month: true,
year: false
};
this._destroy$ = new Subject();
this._disabledDates = null;
this._specialDates = null;
this._onOpen = new EventEmitter();
this._onClose = new EventEmitter();
this._onTouchedCallback = () => { };
this._onChangeCallback = () => { };
}
/**
*Returns the format options of the `IgxDatePickerComponent`.
*```typescript
*@ViewChild("MyDatePicker")
*public datePicker: IgxDatePickerComponent;
*ngAfterViewInit(){
* let formatOptions = this.datePicker.formatOptions;
*}
*```
*/
get formatOptions() {
return this._formatOptions;
}
/**
*Sets the format options of the `IgxDatePickerComponent`.
*```typescript
*public Options;
*@ViewChild("MyDatePicker")
*public datePicker: IgxDatePickerComponent;
*ngAfterViewInit(){
* this.Options = {
* day: "numeric",
* month: "long",
* weekday: "long",
* year: "numeric"
* }
*this.datePicker.formatOptions = this.Options;
*}
*```
*/
set formatOptions(formatOptions) {
this._formatOptions = Object.assign(this._formatOptions, formatOptions);
}
/**
*Returns the date display format of the `IgxDatePickerComponent` in dropdown mode.
*```typescript
*@ViewChild("MyDatePicker")
*public datePicker: IgxDatePickerComponent;
*ngAfterViewInit(){
* let format = this.datePicker.format;
*}
*```
*/
get format() {
return (this._format === undefined) ? PredefinedFormatOptions.ShortDate : this._format;
}
/**
*Sets the date format of the `IgxDatePickerComponent` when in editable dropdown mode.
*```typescript
*@ViewChild("MyDatePicker")
*public datePicker: IgxDatePickerComponent;
*this.datePicker.format = 'yyyy-M-d';
*}
*```
*/
set format(format) {
this._format = format;
}
/**
*Returns the format views of the `IgxDatePickerComponent`.
*```typescript
*@ViewChild("MyDatePicker")
*public datePicker: IgxDatePickerComponent;
*ngAfterViewInit(){
* let formatViews = this.datePicker.formatViews;
*}
*```
*/
get formatViews() {
return this._formatViews;
}
/**
*Sets the format views of the `IgxDatePickerComponent`.
*```typescript
*public Views;
*@ViewChild("MyDatePicker")
*public datePicker: IgxDatePickerComponent;
*ngAfterViewInit(){
* this.Views = {day:false, month: false, year:false};
* this.datePicker.formatViews = this.Views;
*}
*```
*/
set formatViews(formatViews) {
this._formatViews = Object.assign(this._formatViews, formatViews);
}
/**
* Gets the disabled dates descriptors.
* ```typescript
* let disabledDates = this.datepicker.disabledDates;
* ```
*/
get disabledDates() {
return this._disabledDates;
}
/**
* Sets the disabled dates' descriptors.
* ```typescript
*@ViewChild("MyDatePicker")
*public datePicker: IgxDatePickerComponent;
*ngAfterViewInit(){
* this.datePicker.disabledDates = [
* {type: DateRangeType.Between, dateRange: [new Date("2020-1-1"), new Date("2020-1-15")]},
* {type: DateRangeType.Weekends}];
*}
*```
*/
set disabledDates(value) {
this._disabledDates = value;
}
/**
* Gets the special dates descriptors.
* ```typescript
* let specialDates = this.datepicker.specialDates;
* ```
*/
get specialDates() {
return this._specialDates;
}
/**
* Sets the special dates' descriptors.
* ```typescript
*@ViewChild("MyDatePicker")
*public datePicker: IgxDatePickerComponent;
*ngAfterViewInit(){
* this.datePicker.specialDates = [
* {type: DateRangeType.Between, dateRange: [new Date("2020-1-1"), new Date("2020-1-15")]},
* {type: DateRangeType.Weekends}];
*}
*```
*/
set specialDates(value) {
this._specialDates = value;
}
get modalOverlaySettings() {
return this._modalOverlay;
}
set modalOverlaySettings(value) {
this._modalOverlay = value;
}
get dropDownOverlaySettings() {
return this._dropDownOverlaySettings || this._defaultDropDownOverlaySettings;
}
set dropDownOverlaySettings(value) {
this._dropDownOverlaySettings = value;
}
/**
*Returns the formatted date when `IgxDatePickerComponent` is in dialog mode.
*```typescript
*@ViewChild("MyDatePicker")
*public datePicker: IgxDatePickerComponent;
*public selection(event){
* let selectedDate = this.datePicker.displayData;
* alert(selectedDate);
*}
*```
*```html
*<igx-date-picker #MyDatePicker (onSelection)="selection()" todayButtonLabel="today"></igx-date-picker>
*```
*/
get displayData() {
if (this.value) {
return this._customFormatChecker(this.formatter, this.value);
}
return '';
}
/**
hidden
*/
get transformedDate() {
if (this._value) {
this._transformedDate = (this._isInEditMode) ? this._getEditorDate(this._value) : this._getDisplayDate(this._value);
this.isEmpty = false;
}
else {
this._transformedDate = (this._isInEditMode) ? DatePickerUtil.maskToPromptChars(this.inputMask) : '';
}
return this._transformedDate;
}
set transformedDate(value) {
this._transformedDate = value;
}
/**
* Gets the input group template.
* ```typescript
* let template = this.template();
* ```
* @memberof IgxDatePickerComponent
*/
get template() {
if (this.datePickerTemplateDirective) {
return this.datePickerTemplateDirective.template;
}
return (this.mode === InteractionMode.Dialog) ? this.readOnlyDatePickerTemplate : this.editableDatePickerTemplate;
}
/**
* Gets the context passed to the input group template.
* @memberof IgxDatePickerComponent
*/
get context() {
return {
disabled: this.disabled,
disabledDates: this.disabledDates,
displayData: this.displayData,
format: this.format,
isSpinLoop: this.isSpinLoop,
label: this.label,
labelVisibility: this.labelVisibility,
locale: this.locale,
mask: this.mask,
mode: this.mode,
specialDates: this.specialDates,
value: this.value,
openDialog: (target) => this.openDialog(target)
};
}
/**
*An @Input property that gets/sets the selected date.
*```typescript
*public date: Date = new Date();
*```
*```html
*<igx-date-picker [value]="date"></igx-date-picker>
*```
*/
get value() {
return this._value;
}
set value(date) {
this._value = date;
this._onChangeCallback(date);
}
/**
* @deprecated Use 'onOpened' instead.
*An event that is emitted when the `IgxDatePickerComponent` calendar is opened.
*```typescript
*public open(event){
* alert("The date-picker calendar has been opened!");
*}
*```
*```html
*<igx-date-picker (onOpen)="open($event)" cancelButtonLabel="cancel" todayButtonLabel="today"></igx-date-picker>
*```
*/
get onOpen() {
return this._onOpen;
}
set onOpen(val) {
this._onOpen = val;
}
/**
* @deprecated Use 'onClosed' instead.
*"An event that is emitted when the `IgxDatePickerComponent` is closed.
*```typescript
*public close(event){
* alert("The date-picker has been closed!");
*}
*```
*```html
*<igx-date-picker (onClose)="close($event)" cancelButtonLabel="cancel" todayButtonLabel="today"></igx-date-picker>
*```
*/
get onClose() {
return this._onClose;
}
set onClose(val) {
this._onClose = val;
}
/**
* @hidden
*/
onSpaceClick(event) {
this.openDialog(this.getInputGroupElement());
event.preventDefault();
}
/**
*Method that sets the selected date.
*```typescript
*public date = new Date();
*@ViewChild("MyDatePicker")
*public datePicker: IgxDatePickerComponent;
*ngAfterViewInit(){
* this.datePicker.writeValue(this.date);
*}
*```
*@param value The date you want to select.
*@memberOf {@link IgxDatePickerComponent}
*/
writeValue(value) {
this.value = value;
this._cdr.markForCheck();
}
/**
*@hidden
*/
registerOnChange(fn) { this._onChangeCallback = fn; }
/**
*@hidden
*/
registerOnTouched(fn) { this._onTouchedCallback = fn; }
/**
*@hidden
*/
setDisabledState(isDisabled) { this.disabled = isDisabled; }
/** @hidden */
getEditElement() {
const inputElement = this.editableInput || this.readonlyInput || this.input;
return (inputElement) ? inputElement.nativeElement : null;
}
/** @hidden */
getInputGroupElement() {
return this.inputGroup ? this.inputGroup.element.nativeElement : null;
}
/**
*@hidden
*/
ngOnInit() {
this._positionSettings = {
openAnimation: fadeIn,
closeAnimation: fadeOut
};
this._defaultDropDownOverlaySettings = {
closeOnOutsideClick: true,
modal: false,
scrollStrategy: new AbsoluteScrollStrategy(),
positionStrategy: new AutoPositionStrategy(this._positionSettings),
outlet: this.outlet
};
this._modalOverlaySettings = {
closeOnOutsideClick: true,
modal: true,
outlet: this.outlet
};
this._overlayService.onOpening.pipe(filter((overlay) => overlay.id === this._componentID), takeUntil(this._destroy$)).subscribe((eventArgs) => {
this._onOpening(eventArgs);
});
this._overlayService.onOpened.pipe(filter((overlay) => overlay.id === this._componentID), takeUntil(this._destroy$)).subscribe(() => {
this._onOpened();
});
this._overlayService.onClosed.pipe(filter(overlay => overlay.id === this._componentID), takeUntil(this._destroy$)).subscribe(() => {
this._onClosed();
});
this._overlayService.onClosing.pipe(filter(overlay => overlay.id === this._componentID), takeUntil(this._destroy$)).subscribe((event) => {
this.onClosing.emit(event);
// If canceled in a user onClosing handler
if (event.cancel) {
return;
}
// Do not focus the input if clicking outside in dropdown mode
const input = this.getEditElement();
if (input && !(event.event && this.mode === InteractionMode.DropDown)) {
input.focus();
}
});
if (this.mode === InteractionMode.DropDown) {
this.dateFormatParts = DatePickerUtil.parseDateFormat(this.mask, this.locale);
if (this.mask === undefined) {
this.mask = DatePickerUtil.getMask(this.dateFormatParts);
}
this.inputMask = DatePickerUtil.getInputMask(this.dateFormatParts);
}
}
ngAfterViewInit() {
if (this.mode === InteractionMode.DropDown && this.editableInput) {
fromEvent(this.editableInput.nativeElement, 'keydown').pipe(throttle(() => interval(0, animationFrameScheduler)), takeUntil(this._destroy$)).subscribe((res) => this.onKeyDown(res));
}
}
/**
*@hidden
*/
ngOnDestroy() {
if (this._componentID) {
this._overlayService.hide(this._componentID);
}
this._destroy$.next(true);
this._destroy$.complete();
}
/**
*Selects today's date from calendar and change the input field value, @calendar.viewDate and @calendar.value.
*```typescript
*@ViewChild("MyDatePicker")
*public datePicker: IgxDatePickerComponent;
*ngAfterViewInit(){
*this.datePicker.triggerTodaySelection();
*}
*```
*@memberOf {@link IgxDatePickerComponent}
*/
triggerTodaySelection() {
const today = new Date(Date.now());
this.handleSelection(today);
}
/**
* Change the calendar selection and calling this method will emit the @calendar.onSelection event,
* which will fire @handleSelection method.
*```typescript
*@ViewChild("MyDatePicker")
*public datePicker: IgxDatePickerComponent;
*ngAfterViewInit(){
*this.datePicker.selectDate(this.date);
*}
* ```
* @param date passed date that has to be set to the calendar.
* @memberOf {@link IgxDatePickerComponent}
*/
selectDate(date) {
const oldValue = this.value;
this.value = date;
this.emitValueChangeEvent(oldValue, this.value);
this.onSelection.emit(date);
}
/**
* Deselects the calendar date.
*```typescript
*@ViewChild("MyDatePicker")
*public datePicker: IgxDatePickerComponent;
*ngAfterViewInit(){
*this.datePicker.deselectDate();
*}
* ```
* @memberOf {@link IgxDatePickerComponent}
*/
deselectDate() {
const oldValue = this.value;
this.value = null;
this.emitValueChangeEvent(oldValue, this.value);
if (this.calendar) {
this.calendar.deselectDate();
}
}
/**
* Opens the date picker drop down or dialog.
* @param target HTMLElement - the target element to use for positioning the drop down container according to
* ```html
* <igx-date-picker [value]="date" mode="dropdown" #retemplated>
* <ng-template igxDatePickerTemplate let-openDialog="openDialog"
* let-displayData="displayData">
* <igx-input-group>
* <input #dropDownTarget igxInput [value]="displayData" />
* <igx-suffix (click)="openDialog(dropDownTarget)">
* <igx-icon>alarm</igx-icon>
* </igx-suffix>
* </igx-input-group>
* </ng-template>
* </igx-date-picker>
* ```
*/
openDialog(target) {
if (!this.collapsed) {
return;
}
switch (this.mode) {
case InteractionMode.Dialog: {
this.hasHeader = true;
const modalOverlay = (this.modalOverlaySettings !== undefined) ? this._modalOverlay : this._modalOverlaySettings;
this._componentID = this._overlayService.attach(IgxCalendarContainerComponent, modalOverlay, this._moduleRef);
this._overlayService.show(this._componentID);
break;
}
case InteractionMode.DropDown: {
this.hasHeader = false;
if (target) {
this.dropDownOverlaySettings.positionStrategy.settings.target = target;
}
this._componentID = this._overlayService.attach(IgxCalendarContainerComponent, this.dropDownOverlaySettings, this._moduleRef);
this._overlayService.show(this._componentID);
break;
}
}
}
/**
* Close the calendar.
*
* @hidden
*/
closeCalendar() {
this._overlayService.hide(this._componentID);
}
/**
* Clear the input field, date picker value and calendar selection.
*
* @hidden
*/
clear() {
this.isEmpty = true;
this.invalidDate = '';
this.deselectDate();
this._setCursorPosition(0);
}
/**
* Evaluates when @calendar.onSelection event was fired
* and update the input value.
*
* @param event selected value from calendar.
*
* @hidden
*/
handleSelection(date) {
if (this.value) {
date.setHours(this.value.getHours());
date.setMinutes(this.value.getMinutes());
date.setSeconds(this.value.getSeconds());
date.setMilliseconds(this.value.getMilliseconds());
}
const oldValue = this.value;
this.value = date;
this.emitValueChangeEvent(oldValue, this.value);
this.calendar.viewDate = date;
this.closeCalendar();
this.onSelection.emit(date);
}
/**
* Evaluates when the input blur event was fired
* and re-calculate the date picker value.
*
* @param event
*
* @hidden
*/
onBlur(event) {
this._isInEditMode = false;
this.calculateDate(event.target.value, event.type);
}
/**
* Evaluates when the input focus event was fired
* and re-calculate the editor text.
*
* @param event
* @hidden
*/
onFocus() {
this._isInEditMode = true;
if (this.value && this.invalidDate === '') {
this._transformedDate = this._getEditorDate(this.value);
}
}
/**
* Evaluates when the keydown event was fired for up/down keys
* to provide spinning of date parts.
*
* @param event
*
* @hidden
*/
onKeyDown(event) {
switch (event.key) {
case "ArrowUp" /* UP_ARROW */:
case "Up" /* UP_ARROW_IE */:
event.preventDefault();
event.stopPropagation();
this.spinValue(event.target.value, 1, event.type);
break;
case "ArrowDown" /* DOWN_ARROW */:
case "Down" /* DOWN_ARROW_IE */:
if (event.altKey) {
this.openDialog(this.getInputGroupElement());
}
else {
event.preventDefault();
event.stopPropagation();
this.spinValue(event.target.value, -1, event.type);
}
break;
default:
break;
}
}
/**
* Evaluates when the mouse wheel event was fired
* to provide spinning of date parts.
*
* @param event
*
* @hidden
*/
onWheel(event) {
if (this._isInEditMode) {
event.preventDefault();
event.stopPropagation();
const sign = (event.deltaY > 0) ? -1 : 1;
this.spinValue(event.target.value, sign, event.type);
}
}
/**
* Evaluates when input event was fired in editor.
*
* @param event
*
* @hidden
*/
onInput(event) {
const targetValue = event.target.value;
const cursorPosition = this._getCursorPosition();
const checkInput = DatePickerUtil.checkForCompleteDateInput(this.dateFormatParts, targetValue);
this._isInEditMode = true;
if (targetValue !== DatePickerUtil.maskToPromptChars(this.inputMask)) {
this.isEmpty = false;
}
// If all date parts are completed, change the date-picker value, stay in edit mode
if (checkInput === 'complete' && event.inputType !== 'deleteContentBackward') {
this._transformedDate = targetValue;
this.calculateDate(targetValue, event.type);
this._setCursorPosition(cursorPosition);
}
else if (checkInput === 'partial') {
// While editing, if one date part is deleted, date-picker value is set to null, the remaining input stays intact.
this.deselectDate();
requestAnimationFrame(() => {
this.getEditElement().value = targetValue;
this._setCursorPosition(cursorPosition);
});
}
else if (checkInput === 'empty') {
// Total clean-up as input is deleted.
this.isEmpty = true;
this.deselectDate();
}
}
emitValueChangeEvent(oldValue, newValue) {
if (!isEqual(oldValue, newValue)) {
this.valueChange.emit(newValue);
}
}
calculateDate(dateString, invokedByEvent) {
if (dateString !== '') {
const prevDateValue = this.value;
const inputValue = (invokedByEvent === 'blur') ? this.rawDateString : dateString;
const newDateArray = DatePickerUtil.parseDateArray(this.dateFormatParts, prevDateValue, inputValue);
if (newDateArray.state === "valid" /* Valid */) {
const newValue = newDateArray.date;
// Restore the time part if any
if (prevDateValue) {
newValue.setHours(prevDateValue.getHours());
newValue.setMinutes(prevDateValue.getMinutes());
newValue.setSeconds(prevDateValue.getSeconds());
newValue.setMilliseconds(prevDateValue.getMilliseconds());
}
if (this.disabledDates === null
|| (this.disabledDates !== null && !isDateInRanges(newValue, this.disabledDates))) {
const oldValue = this.value;
this.value = newValue;
this.emitValueChangeEvent(oldValue, this.value);
this.invalidDate = '';
}
else {
const args = {
datePicker: this,
currentValue: newValue,
};
this.onDisabledDate.emit(args);
}
}
else {
const args = {
datePicker: this,
prevValue: prevDateValue
};
this.invalidDate = dateString;
this.onValidationFailed.emit(args);
}
}
}
spinValue(inputValue, sign, eventType) {
this._isInEditMode = true;
this.isEmpty = false;
const cursorPosition = this._getCursorPosition();
const modifiedInputValue = DatePickerUtil.getModifiedDateInput(this.dateFormatParts, inputValue, cursorPosition, this.spinDelta * sign, this.isSpinLoop);
this.getEditElement().value = modifiedInputValue;
this._setCursorPosition(cursorPosition);
const checkInput = DatePickerUtil.checkForCompleteDateInput(this.dateFormatParts, modifiedInputValue);
if (checkInput === 'complete') {
this._isInEditMode = true;
this.calculateDate(modifiedInputValue, eventType);
this._setCursorPosition(cursorPosition);
}
}
_onOpening(event) {
this._initializeCalendarContainer(event.componentRef.instance);
this.collapsed = false;
}
_onOpened() {
this._onTouchedCallback();
this.onOpened.emit(this);
// TODO: remove this line after deprecating 'onOpen'
this._onOpen.emit(this);
if (this.calendar) {
this._focusCalendarDate();
}
}
_onClosed() {
this.collapsed = true;
this._componentID = null;
this.onClosed.emit(this);
// TODO: remove this line after deprecating 'onClose'
this.onClose.emit(this);
}
_initializeCalendarContainer(componentInstance) {
this.calendar = componentInstance.calendar;
const isVertical = (this.vertical && this.mode === InteractionMode.Dialog);
this.calendar.hasHeader = this.hasHeader;
this.calendar.formatOptions = this.formatOptions;
this.calendar.formatViews = this.formatViews;
this.calendar.locale = this.locale;
this.calendar.vertical = isVertical;
this.calendar.weekStart = this.weekStart;
this.calendar.specialDates = this.specialDates;
this.calendar.disabledDates = this.disabledDates;
this.calendar.headerTemplate = this.headerTemplate;
this.calendar.subheaderTemplate = this.subheaderTemplate;
this.calendar.hideOutsideDays = this.hideOutsideDays;
this.calendar.monthsViewNumber = this.monthsViewNumber;
this.calendar.onSelection.pipe(takeUntil(this._destroy$)).subscribe((ev) => this.handleSelection(ev));
if (this.value) {
this.calendar.value = this.value;
this.calendar.viewDate = this.value;
}
componentInstance.mode = this.mode;
componentInstance.vertical = isVertical;
componentInstance.cancelButtonLabel = this.cancelButtonLabel;
componentInstance.todayButtonLabel = this.todayButtonLabel;
componentInstance.datePickerActions = this.datePickerActionsDirective;
componentInstance.onClose.pipe(takeUntil(this._destroy$)).subscribe(() => this.closeCalendar());
componentInstance.onTodaySelection.pipe(takeUntil(this._destroy$)).subscribe(() => this.triggerTodaySelection());
}
// Focus a date, after the calendar appearance into DOM.
_focusCalendarDate() {
requestAnimationFrame(() => {
this.calendar.daysView.focusActiveDate();
});
}
_setLocaleToDate(value) {
if (isIE()) {
// this is a workaround fixing the following IE11 issue:
// IE11 has added character code 8206 (mark for RTL) to the output of toLocaleDateString() that
// precedes each portion that comprises the total date... For more information read this article:
// tslint:disable-next-line: max-line-length
// https://www.csgpro.com/blog/2016/08/a-bad-date-with-internet-explorer-11-trouble-with-new-unicode-characters-in-javascript-date-strings/
const localeDateStrIE = new Date(value.getFullYear(), value.getMonth(), value.getDate(), value.getHours(), value.getMinutes(), value.getSeconds(), value.getMilliseconds());
return localeDateStrIE.toLocaleDateString(this.locale);
}
return value.toLocaleDateString(this.locale);
}
_getCursorPosition() {
return this.getEditElement().selectionStart;
}
_setCursorPosition(start, end = start) {
requestAnimationFrame(() => {
this.getEditElement().setSelectionRange(start, end);
});
}
/**
* Apply custom user formatter upon date.
* @param formatter custom formatter function.
* @param date passed date
*/
_customFormatChecker(formatter, date) {
return this.formatter ? this.formatter(date) : this._setLocaleToDate(date);
}
/*
* Transforms the date according to the specified format when `IgxDatePickerComponent` is in edit mode
* using @angular/common formatDate method: https://angular.io/api/common/formatDate
* @param value: string | number | Date
* @returns formatted string
*/
_getDisplayDate(value) {
if (this.format && !this.formatter) {
const locale = this.locale || this.defaultLocale;
return formatDate(value, this.format, locale);
}
else {
return this._customFormatChecker(this.formatter, value);
}
}
_getEditorDate(value) {
const locale = this.locale || this.defaultLocale;
const changedValue = (value) ? formatDate(value, this.mask, locale) : '';
return DatePickerUtil.addPromptCharsEditMode(this.dateFormatParts, this.value, changedValue);
}
};
IgxDatePickerComponent.ctorParameters = () => [
{ type: IgxOverlayService, decorators: [{ type: Inject, args: [IgxOverlayService,] }] },
{ type: ElementRef },
{ type: ChangeDetectorRef },
{ type: NgModuleRef }
];
__decorate([
Input(),
__metadata("design:type", Object)
], IgxDatePickerComponent.prototype, "label", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], IgxDatePickerComponent.prototype, "labelVisibility", void 0);
__decorate([
Input(),
__metadata("design:type", String)
], IgxDatePickerComponent.prototype, "locale", void 0);
__decorate([
Input(),
__metadata("design:type", Number)
], IgxDatePickerComponent.prototype, "weekStart", void 0);
__decorate([
Input(),
__metadata("design:type", Object),
__metadata("design:paramtypes", [Object])
], IgxDatePickerComponent.prototype, "formatOptions", null);
__decorate([
Input(),
__metadata("design:type", Boolean)
], IgxDatePickerComponent.prototype, "hideOutsideDays", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], IgxDatePickerComponent.prototype, "monthsViewNumber", void 0);
__decorate([
Input(),
__metadata("design:type", String),
__metadata("design:paramtypes", [String])
], IgxDatePickerComponent.prototype, "format", null);
__decorate([
Input(),
__metadata("design:type", String)
], IgxDatePickerComponent.prototype, "mask", void 0);
__decorate([
Input(),
__metadata("design:type", Object),
__metadata("design:paramtypes", [Object])
], IgxDatePickerComponent.prototype, "formatViews", null);
__decorate([
Input(),
__metadata("design:type", Array),
__metadata("design:paramtypes", [Array])
], IgxDatePickerComponent.prototype, "disabledDates", null);
__decorate([
Input(),
__metadata("design:type", Array),
__metadata("design:paramtypes", [Array])
], IgxDatePickerComponent.prototype, "specialDates", null);
__decorate([
Input(),
__metadata("design:type", Object),
__metadata("design:paramtypes", [Object])
], IgxDatePickerComponent.prototype, "modalOverlaySettings", null);
__decorate([
Input(),
__metadata("design:type", Object),
__metadata("design:paramtypes", [Object])
], IgxDatePickerComponent.prototype, "dropDownOverlaySettings", null);
__decorate([
Input(),
__metadata("design:type", Date),
__metadata("design:paramtypes", [Date])
], IgxDatePickerComponent.prototype, "value", null);
__decorate([
HostBinding('attr.id'),
Input(),
__metadata("design:type", Object)
], IgxDatePickerComponent.prototype, "id", void 0);
__decorate([
Input(),
__metadata("design:type", Function)
], IgxDatePickerComponent.prototype, "formatter", void 0);
__decorate([
Input(),
__metadata("design:type", Boolean)
], IgxDatePickerComponent.prototype, "disabled", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], IgxDatePickerComponent.prototype, "vertical", void 0);
__decorate([
Input(),
__metadata("design:type", String)
], IgxDatePickerComponent.prototype, "todayButtonLabel", void 0);
__decorate([
Input(),
__metadata("design:type", String)
], IgxDatePickerComponent.prototype, "cancelButtonLabel", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], IgxDatePickerComponent.prototype, "mode", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], IgxDatePickerComponent.prototype, "isSpinLoop", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], IgxDatePickerComponent.prototype, "outlet", void 0);
__decorate([
DeprecateProperty(`'onOpen' @Output property is deprecated. Use 'onOpened' instead.`),
Output(),
__metadata("design:type", EventEmitter),
__metadata("design:paramtypes", [EventEmitter])
], IgxDatePickerComponent.prototype, "onOpen", null);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxDatePickerComponent.prototype, "onOpened", void 0);
__decorate([
DeprecateProperty(`'onClose' @Output property is deprecated. Use 'onClosed' instead.`),
Output(),
__metadata("design:type", EventEmitter),
__metadata("design:paramtypes", [EventEmitter])
], IgxDatePickerComponent.prototype, "onClose", null);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxDatePickerComponent.prototype, "onClosed", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxDatePickerComponent.prototype, "onClosing", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxDatePickerComponent.prototype, "onSelection", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxDatePickerComponent.prototype, "valueChange", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxDatePickerComponent.prototype, "onDisabledDate", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxDatePickerComponent.prototype, "onValidationFailed", void 0);
__decorate([
ViewChild('readOnlyDatePickerTemplate', { read: TemplateRef, static: true }),
__metadata("design:type", TemplateRef)
], IgxDatePickerComponent.prototype, "readOnlyDatePickerTemplate", void 0);
__decorate([
ViewChild('editableDatePickerTemplate', { read: TemplateRef, static: true }),
__metadata("design:type", TemplateRef)
], IgxDatePickerComponent.prototype, "editableDatePickerTemplate", void 0);
__decorate([
ViewChild(IgxInputGroupComponent),
__metadata("design:type", IgxInputGroupComponent)
], IgxDatePickerComponent.prototype, "inputGroup", void 0);
__decorate([
ViewChild('editableInput', { read: ElementRef }),
__metadata("design:type", ElementRef)
], IgxDatePickerComponent.prototype, "editableInput", void 0);
__decorate([
ViewChild('readonlyInput', { read: ElementRef }),
__metadata("design:type", ElementRef)
], IgxDatePickerComponent.prototype, "readonlyInput", void 0);
__decorate([
ContentChild(IgxInputDirective),
__metadata("design:type", IgxInputDirective)
], IgxDatePickerComponent.prototype, "input", void 0);
__decorate([
ContentChild(IgxDatePickerTemplateDirective, { read: IgxDatePickerTemplateDirective }),
__metadata("design:type", IgxDatePickerTemplateDirective)
], IgxDatePickerComponent.prototype, "datePickerTemplateDirective", void 0);
__decorate([
ContentChild(IgxCalendarHeaderTemplateDirective, { read: IgxCalendarHeaderTemplateDirective }),
__metadata("design:type", IgxCalendarHeaderTemplateDirective)
], IgxDatePickerComponent.prototype, "headerTemplate", void 0);
__decorate([
ContentChild(IgxCalendarSubheaderTemplateDirective, { read: IgxCalendarSubheaderTemplateDirective }),
__metadata("design:type", IgxCalendarSubheaderTemplateDirective)
], IgxDatePickerComponent.prototype, "subheaderTemplate", void 0);
__decorate([
ContentChild(IgxDatePickerActionsDirective, { read: IgxDatePickerActionsDirective }),
__metadata("design:type", IgxDatePickerActionsDirective)
], IgxDatePickerComponent.prototype, "datePickerActionsDirective", void 0);
__decorate([
HostListener('keydown.spacebar', ['$event']),
HostListener('keydown.space', ['$event']),
__metadata("design:type", Function),
__metadata("design:paramtypes", [KeyboardEvent]),
__metadata("design:returntype", void 0)
], IgxDatePickerComponent.prototype, "onSpaceClick", null);
IgxDatePickerComponent = IgxDatePickerComponent_1 = __decorate([
Component({
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: IgxDatePickerComponent_1,
multi: true
}],
// tslint:disable-next-line:component-selector
selector: 'igx-date-picker',
template: "<ng-template #readOnlyDatePickerTemplate>\n <igx-input-group (click)=\"openDialog()\">\n <igx-prefix>\n <igx-icon>today</igx-icon>\n </igx-prefix>\n <label *ngIf=\"labelVisibility\" igxLabel>{{label}}</label>\n <input #readonlyInput class=\"igx-date-picker__input-date\" igxInput [value]=\"displayData || ''\"\n [disabled]=\"disabled\" readonly />\n </igx-input-group>\n</ng-template>\n\n<ng-template #editableDatePickerTemplate>\n <igx-input-group #editableInputGroup [supressInputAutofocus]=\"true\">\n <igx-prefix (click)=\"openDialog(editableInputGroup.element.nativeElement)\">\n <igx-icon>today</igx-icon>\n </igx-prefix>\n <label *ngIf=\"labelVisibility\" igxLabel>{{label}}</label>\n <input #editableInput class=\"igx-date-picker__input-date\" igxInput [igxTextSelection]=\"true\"\n type=\"text\" [value]=\"transformedDate\"\n [igxMask]=\"inputMask\" [placeholder]=\"mask\" [disabled]=\"disabled\" [displayValuePipe]=\"displayValuePipe\"\n [focusedValuePipe]=\"inputValuePipe\" (blur)=\"onBlur($event)\" (wheel)=\"onWheel($event)\"\n (input)=\"onInput($event)\" (focus)=\"onFocus()\" />\n <igx-suffix *ngIf=\"!isEmpty\" (click)=\"clear()\">\n <igx-icon>clear</igx-icon>\n </igx-suffix>\n </igx-input-group>\n</ng-template>\n\n<ng-container *ngTemplateOutlet=\"template; context: context\"></ng-container>\n",
styles: [`
:host {
display: block;
}
`]
}),
__param(0, Inject(IgxOverlayService)),
__metadata("design:paramtypes", [IgxOverlayService, ElementRef,
ChangeDetectorRef, NgModuleRef])
], IgxDatePickerComponent);
export { IgxDatePickerComponent };
/**
* @hidden
*/
let IgxDatePickerModule = class IgxDatePickerModule {
};
IgxDatePickerModule = __decorate([
NgModule({
declarations: [
IgxDatePickerComponent,
IgxCalendarContainerComponent,
IgxDatePickerActionsDirective,
IgxDatePickerTemplateDirective,
DatePickerDisplayValuePipe,
DatePickerInputValuePipe
],
entryComponents: [
IgxCalendarContainerComponent
],
exports: [
IgxDatePickerComponent,
IgxDatePickerTemplateDirective,
IgxDatePickerActionsDirective,
DatePickerDisplayValuePipe,
DatePickerInputValuePipe
],
imports: [
CommonModule,
IgxIconModule,
IgxInputGroupModule,
IgxCalendarModule,
IgxButtonModule,
IgxRippleModule,
IgxMaskModule,
IgxTextSelectionModule
]
})
], IgxDatePickerModule);
export { IgxDatePickerModule };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1waWNrZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vaWduaXRldWktYW5ndWxhci8iLCJzb3VyY2VzIjpbImxpYi9kYXRlLXBpY2tlci9kYXRlLXBpY2tlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNELE9BQU8sRUFDSCxTQUFTLEVBQ1QsWUFBWSxFQUNaLFlBQVksRUFDWixXQUFXLEVBQ1gsS0FBSyxFQUNMLFFBQVEsRUFDUixTQUFTLEVBQ1QsTUFBTSxFQUNOLFNBQVMsRUFDVCxVQUFVLEVBQ1YsV0FBVyxFQUNYLE1BQU0sRUFDTixpQkFBaUIsRUFDakIsWUFBWSxFQUNaLFdBQVcsRUFDWCxNQUFNLEVBQ04sYUFBYSxFQUNoQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekUsT0FBTyxFQUVILGtDQUFrQyxFQUNsQyxpQkFBaUIsRUFDakIscUNBQXFDLEVBQ3JDLFFBQVEsRUFDUixjQUFjLEVBQ2pCLE1BQU0sbUJBQW1CLENBQUM7QUFDM0IsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM5QyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsaUJBQWlCLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN0RyxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSx1QkFBdUIsRUFBRSxRQUFRLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDN0UsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFN0QsT0FBTyxFQUFFLHNCQUFzQixFQUFDLE1BQU0sdURBQXVELENBQUM7QUFDOUYsT0FBTyxFQUNILGVBQWUsRUFDZixpQkFBaUIsRUFDakIsZ0JBQWdCLEVB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