UNPKG

@catull/igniteui-angular

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

1,241 lines 141 kB
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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