trying to fix calendar

This commit is contained in:
Simone Angeloni Bei 2025-05-07 18:09:33 +02:00
parent 3f5782dea0
commit ea3ad437e5
24 changed files with 8849 additions and 65 deletions

View File

@ -1,57 +1,71 @@
import { ModuleWithProviders, NgModule } from '@angular/core';
import { XdceArchModule } from '@isp/xdce-arch-core';
import { NbpModule } from '@isp/xdce-widget';
import { ModuleWithProviders, NgModule } from "@angular/core";
import { NbpBreadCrumbsComponent } from './widgetfideuram/components/nbp-bread-crumbs/nbp-bread-crumbs.component';
export { NbpBreadCrumbsComponent } from './widgetfideuram/components/nbp-bread-crumbs/nbp-bread-crumbs.component';
import { NbpFidBarChartComponent } from './widgetfideuram/components/nbp-fid-bar-chart/nbp-fid-bar-chart.component';
export { NbpFidBarChartComponent } from './widgetfideuram/components/nbp-fid-bar-chart/nbp-fid-bar-chart.component';
import { NbpFidButtonBarComponent } from './widgetfideuram/components/nbp-fid-button-bar/nbp-fid-button-bar.component';
export { NbpFidButtonBarComponent } from './widgetfideuram/components/nbp-fid-button-bar/nbp-fid-button-bar.component';
import { NbpFidDonutChartComponent } from './widgetfideuram/components/nbp-fid-donut-chart/nbp-fid-donut-chart.component';
export { NbpFidDonutChartComponent } from './widgetfideuram/components/nbp-fid-donut-chart/nbp-fid-donut-chart.component';
import { NbpFidPyramidChartComponent } from './widgetfideuram/components/nbp-fid-pyramid-chart/nbp-fid-pyramid-chart.component';
export { NbpFidPyramidChartComponent } from './widgetfideuram/components/nbp-fid-pyramid-chart/nbp-fid-pyramid-chart.component';
import { NbpFidSidePopupComponent } from './widgetfideuram/components/nbp-fid-side-popup/nbp-fid-side-popup.component';
export { NbpFidSidePopupComponent } from './widgetfideuram/components/nbp-fid-side-popup/nbp-fid-side-popup.component';
import { NbpFidTableComponent } from './widgetfideuram/components/nbp-fid-table/nbp-fid-table.component';
export { NbpFidTableComponent } from './widgetfideuram/components/nbp-fid-table/nbp-fid-table.component';
import { NbpFidToggleTabComponentA11Y } from './widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tab.component.a11y';
export { NbpFidToggleTabComponentA11Y } from './widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tab.component.a11y';
import { NbpFidToggleTabComponentNOA11Y } from './widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tab.component.noa11y';
export { NbpFidToggleTabComponentNOA11Y } from './widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tab.component.noa11y';
import { NbpFidToggleTabComponent } from './widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tab.component';
export { NbpFidToggleTabComponent } from './widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tab.component';
import { NbpFidToggleTabsetComponentA11Y } from './widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tabset.component.a11y';
export { NbpFidToggleTabsetComponentA11Y } from './widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tabset.component.a11y';
import { NbpFidToggleTabsetComponentNOA11Y } from './widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tabset.component.noa11y';
export { NbpFidToggleTabsetComponentNOA11Y } from './widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tabset.component.noa11y';
import { NbpFidToggleTabsetComponent } from './widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tabset.component';
export { NbpFidToggleTabsetComponent } from './widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tabset.component';
import { NbpFidComboComponent } from './widgetfideuram/components/nbp-fid-combo/nbp-fid-combo.component';
export { NbpFidComboComponent } from './widgetfideuram/components/nbp-fid-combo/nbp-fid-combo.component';
import { NbpBreadCrumbsComponent } from "./widgetfideuram/components/nbp-bread-crumbs/nbp-bread-crumbs.component";
export { NbpBreadCrumbsComponent } from "./widgetfideuram/components/nbp-bread-crumbs/nbp-bread-crumbs.component";
import { NbpFidBarChartComponent } from "./widgetfideuram/components/nbp-fid-bar-chart/nbp-fid-bar-chart.component";
export { NbpFidBarChartComponent } from "./widgetfideuram/components/nbp-fid-bar-chart/nbp-fid-bar-chart.component";
import { NbpFidButtonBarComponent } from "./widgetfideuram/components/nbp-fid-button-bar/nbp-fid-button-bar.component";
export { NbpFidButtonBarComponent } from "./widgetfideuram/components/nbp-fid-button-bar/nbp-fid-button-bar.component";
import { NbpFidDonutChartComponent } from "./widgetfideuram/components/nbp-fid-donut-chart/nbp-fid-donut-chart.component";
export { NbpFidDonutChartComponent } from "./widgetfideuram/components/nbp-fid-donut-chart/nbp-fid-donut-chart.component";
import { NbpFidPyramidChartComponent } from "./widgetfideuram/components/nbp-fid-pyramid-chart/nbp-fid-pyramid-chart.component";
export { NbpFidPyramidChartComponent } from "./widgetfideuram/components/nbp-fid-pyramid-chart/nbp-fid-pyramid-chart.component";
import { NbpFidSidePopupComponent } from "./widgetfideuram/components/nbp-fid-side-popup/nbp-fid-side-popup.component";
export { NbpFidSidePopupComponent } from "./widgetfideuram/components/nbp-fid-side-popup/nbp-fid-side-popup.component";
import { NbpFidTableComponent } from "./widgetfideuram/components/nbp-fid-table/nbp-fid-table.component";
export { NbpFidTableComponent } from "./widgetfideuram/components/nbp-fid-table/nbp-fid-table.component";
import { NbpFidToggleTabComponentA11Y } from "./widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tab.component.a11y";
export { NbpFidToggleTabComponentA11Y } from "./widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tab.component.a11y";
import { NbpFidToggleTabComponentNOA11Y } from "./widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tab.component.noa11y";
export { NbpFidToggleTabComponentNOA11Y } from "./widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tab.component.noa11y";
import { NbpFidToggleTabComponent } from "./widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tab.component";
export { NbpFidToggleTabComponent } from "./widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tab.component";
import { NbpFidToggleTabsetComponentA11Y } from "./widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tabset.component.a11y";
export { NbpFidToggleTabsetComponentA11Y } from "./widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tabset.component.a11y";
import { NbpFidToggleTabsetComponentNOA11Y } from "./widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tabset.component.noa11y";
export { NbpFidToggleTabsetComponentNOA11Y } from "./widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tabset.component.noa11y";
import { NbpFidToggleTabsetComponent } from "./widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tabset.component";
export { NbpFidToggleTabsetComponent } from "./widgetfideuram/components/nbp-fid-toggle-tabset/nbp-fid-toggle-tabset.component";
import { NbpFidComboComponent } from "./widgetfideuram/components/nbp-fid-combo/nbp-fid-combo.component";
export { NbpFidComboComponent } from "./widgetfideuram/components/nbp-fid-combo/nbp-fid-combo.component";
import { ShowcaseComponent } from './widgetfideuram/components/showcase/showcase.component';
export { ShowcaseComponent } from './widgetfideuram/components/showcase/showcase.component';
import { Showcase1Component } from './widgetfideuram/components/showcase/showcase1.component';
export { Showcase1Component } from './widgetfideuram/components/showcase/showcase1.component';
import { WidgetFideuramShowcaseComponent } from './widgetfideuram/components/widget-fideuram-showcase/widget-fideuram-showcase.component';
export { WidgetFideuramShowcaseComponent } from './widgetfideuram/components/widget-fideuram-showcase/widget-fideuram-showcase.component';
import { ShowcaseComponent } from "./widgetfideuram/components/showcase/showcase.component";
export { ShowcaseComponent } from "./widgetfideuram/components/showcase/showcase.component";
import { Showcase1Component } from "./widgetfideuram/components/showcase/showcase1.component";
export { Showcase1Component } from "./widgetfideuram/components/showcase/showcase1.component";
import { WidgetFideuramShowcaseComponent } from "./widgetfideuram/components/widget-fideuram-showcase/widget-fideuram-showcase.component";
export { WidgetFideuramShowcaseComponent } from "./widgetfideuram/components/widget-fideuram-showcase/widget-fideuram-showcase.component";
import { AgGridModule, AngularFrameworkComponentWrapper, AngularFrameworkOverrides } from 'ag-grid-angular';
import { FormsModule } from '@angular/forms';
export { AgGridModule } from 'ag-grid-angular';
export { DATE_STRING_FORMAT, formatDate, formatNumber, setSpinnerMessage, clearSpinnerMessage } from './widgetfideuram/Utils';
import { NbpFidCalendarGeneric } from "./widgetfideuram/components/nbp-fid-calendar-generic/nbp-fid-calendar-generic.component";
export { NbpFidCalendarGeneric } from "./widgetfideuram/components/nbp-fid-calendar-generic/nbp-fid-calendar-generic.component";
import { FormsModule } from "@angular/forms";
import {
AgGridModule,
AngularFrameworkComponentWrapper,
AngularFrameworkOverrides,
} from "ag-grid-angular";
import { NbpModule } from "@isp/xdce-widget";
import { XdceArchModule } from "@isp/xdce-arch-core";
import { NbpCalendarGenericComponentA11Y } from "./widgetfideuram/components/nbp-fid-calendar-generic/nbp-calendar-generic.component.a11y";
import { NbpCalendarGenericComponentNOA11Y } from "./widgetfideuram/components/nbp-fid-calendar-generic/nbp-calendar-generic.component.noa11y";
export { NbpCalendarGenericComponentA11Y } from "./widgetfideuram/components/nbp-fid-calendar-generic/nbp-calendar-generic.component.a11y";
export { NbpCalendarGenericComponentNOA11Y } from "./widgetfideuram/components/nbp-fid-calendar-generic/nbp-calendar-generic.component.noa11y";
import { NgbInputDatepicker } from "./widgetfideuram/components/nbp-fid-calendar-generic/@ng-bootstrap/datepicker/datepicker-input";
export { NgbInputDatepicker } from "./widgetfideuram/components/nbp-fid-calendar-generic/@ng-bootstrap/datepicker/datepicker-input";
import { RplCalendarNOA11Y } from "./widgetfideuram/components/nbp-fid-calendar-generic/@ng-bootstrap-noa11y/datepicker/datepicker";
export { RplCalendarNOA11Y } from "./widgetfideuram/components/nbp-fid-calendar-generic/@ng-bootstrap-noa11y/datepicker/datepicker";
export { AgGridModule } from "ag-grid-angular";
export {
DATE_STRING_FORMAT,
formatDate,
formatNumber,
setSpinnerMessage,
clearSpinnerMessage,
} from "./widgetfideuram/Utils";
@NgModule({
imports: [
XdceArchModule,
NbpModule,
AgGridModule,
FormsModule,
],
imports: [XdceArchModule, NbpModule, AgGridModule, FormsModule],
declarations: [
NbpBreadCrumbsComponent,
NbpFidBarChartComponent,
@ -70,6 +84,12 @@ export { DATE_STRING_FORMAT, formatDate, formatNumber, setSpinnerMessage, clearS
ShowcaseComponent,
Showcase1Component,
WidgetFideuramShowcaseComponent,
NbpFidCalendarGeneric,
NgbInputDatepicker,
RplCalendarNOA11Y,
NbpCalendarGenericComponentNOA11Y,
NbpCalendarGenericComponentA11Y,
],
exports: [
NbpBreadCrumbsComponent,
@ -89,26 +109,27 @@ export { DATE_STRING_FORMAT, formatDate, formatNumber, setSpinnerMessage, clearS
ShowcaseComponent,
Showcase1Component,
WidgetFideuramShowcaseComponent,
AgGridModule
],
providers: [
AngularFrameworkOverrides,
AngularFrameworkComponentWrapper
AgGridModule,
NbpFidCalendarGeneric,
RplCalendarNOA11Y
],
providers: [AngularFrameworkOverrides, AngularFrameworkComponentWrapper],
entryComponents: [
NbpFidToggleTabComponentA11Y,
NbpFidToggleTabComponentNOA11Y,
NbpFidToggleTabsetComponentA11Y,
NbpFidToggleTabsetComponentNOA11Y,
NbpFidToggleTabComponent,
NbpFidToggleTabsetComponent
]
NbpFidToggleTabsetComponent,
NbpCalendarGenericComponentA11Y,
NbpCalendarGenericComponentNOA11Y,
],
})
export class XdceWidgetFideuramModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: XdceWidgetFideuramModule,
providers: []
providers: [],
};
}
}

View File

@ -0,0 +1,646 @@
import {
ComponentFactoryResolver,
ComponentRef,
Directive,
ElementRef,
EventEmitter,
Input,
NgZone,
OnChanges,
OnDestroy,
Output,
Renderer2,
SimpleChanges,
TemplateRef,
ViewContainerRef,
forwardRef,
} from "@angular/core";
import {
AbstractControl,
ControlValueAccessor,
NG_VALIDATORS,
NG_VALUE_ACCESSOR,
Validator,
} from "@angular/forms";
import {
NgbDatepickerNavigateEventNOA11Y,
RplCalendarNOA11Y,
} from "./datepicker";
import { Positioning } from "@isp/xdce-widget/user-input/isp-typeahead/ng-bootstrap/positioning";
import { EventManager } from "@isp/xdce-arch-core-base";
import {
NgbDatepickerServiceNOA11Y,
NgbDate,
DayTemplateContextNOA11Y,
NgbDateStruct,
NbpCalendarPattern,
NbpDateSeparator,
NbpCalendarPosition,
NgbDateParserFormatterNOA11Y,
NgbCalendarNOA11Y,
} from "@isp/xdce-widget";
const NGB_DATEPICKER_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NgbInputDatepickerNOA11Y),
multi: true,
};
const NGB_DATEPICKER_VALIDATOR = {
provide: NG_VALIDATORS,
useExisting: forwardRef(() => NgbInputDatepickerNOA11Y),
multi: true,
};
/**
* A directive that makes it possible to have datepickers on input fields.
* Manages integration with the input field itself (data entry) and ngModel (validation etc.).
*/
@Directive({
selector: "input[rplCalendarNOA11Y]",
exportAs: "rplCalendarNOA11Y",
host: {
"(input)": "waitForFormat($event.target.value)",
"(change)": "manualDateChange($event.target.value, true)",
"(keyup.esc)": "close()",
"(blur)": "onBlur()",
"(document:click)": "onFocusOut($event)",
},
providers: [
NGB_DATEPICKER_VALUE_ACCESSOR,
NGB_DATEPICKER_VALIDATOR,
NgbDatepickerServiceNOA11Y,
],
})
export class NgbInputDatepickerNOA11Y
implements OnChanges, OnDestroy, ControlValueAccessor, Validator
{
private _cRef: ComponentRef<RplCalendarNOA11Y> = null;
private _model: NgbDate;
private _zoneSubscription: any;
opened: boolean;
dataBeforeChange;
/**
* Reference for the custom template for the day display
*/
@Input() dayTemplate: TemplateRef<DayTemplateContextNOA11Y>;
/**
* Number of months to display
*/
@Input() displayMonths: number;
/**
* First day of the week. With default calendar we use ISO 8601: 1=Mon ... 7=Sun
*/
@Input() firstDayOfWeek: number;
/**
* Callback to mark a given date as disabled.
* 'Current' contains the month that will be displayed in the view
*/
@Input() markDisabled: (
date: NgbDateStruct,
current: { year: number; month: number }
) => boolean;
/**
* Min date for the navigation. If not provided will be 10 years before today or `startDate`
*/
_minDate: NgbDateStruct;
@Input()
get minDate() {
return this._minDate;
}
set minDate(minDate: NgbDateStruct) {
this._minDate = minDate;
}
/**
* Max date for the navigation. If not provided will be 10 years from today or `startDate`
*/
_maxDate: NgbDateStruct;
@Input()
get maxDate() {
return this._maxDate;
}
set maxDate(maxDate: NgbDateStruct) {
this._maxDate = maxDate;
}
/**
* Navigation type: `select` (default with select boxes for month and year), `arrows`
* (without select boxes, only navigation arrows) or `none` (no navigation at all)
*/
@Input() navigation: "select" | "arrows" | "none";
/**
* The way to display days that don't belong to current month: `visible` (default),
* `hidden` (not displayed) or `collapsed` (not displayed with empty space collapsed)
*/
@Input() outsideDays: "visible" | "collapsed" | "hidden";
/**
* Placement of a datepicker popup. Accepts: "top", "bottom", "left", "right", "bottom-left",
* "bottom-right" etc.
*/
@Input() placement = "bottom-left";
/**
* Whether to display days of the week
*/
@Input() showWeekdays: boolean;
/**
* Whether to display week numbers
*/
@Input() showWeekNumbers: boolean;
/**
* Date to open calendar with.
* With default calendar we use ISO 8601: 'month' is 1=Jan ... 12=Dec.
* If nothing or invalid date provided, calendar will open with current month.
* Use 'navigateTo(date)' as an alternative
*/
@Input() startDate: { year: number; month: number };
@Input() disabledWeekend: boolean;
@Input() holidays: Array<NgbDateStruct>;
@Input() taxDeadlines: Array<NgbDateStruct>;
/**
* input for unifiedVg
*/
@Input() isUnifiedVg: boolean;
private _pattern: any = NbpCalendarPattern;
@Input() nbpLabelPattern: NbpCalendarPattern = this._pattern.GGMMAAAA;
private _separator = NbpDateSeparator;
@Input() nbpDateSeparator: NbpDateSeparator = this._separator.DOT;
/**
* An event fired when navigation happens and currently displayed month changes.
* See NgbDatepickerNavigateEvent for the payload info.
*/
@Output() navigate = new EventEmitter<NgbDatepickerNavigateEventNOA11Y>();
private _onChange = (_: any) => {};
private _onTouched = () => {};
private _validatorChange = () => {};
private _placement: any = NbpCalendarPosition;
private positionService: Positioning;
private get isInModal(): boolean {
let el: HTMLElement = <HTMLElement>this._elRef.nativeElement;
if (!el || !el.parentElement || !el.parentElement.tagName) {
return false;
}
let tagName: string = el.parentElement.tagName;
while (!tagName.match(/modal/i) && !tagName.match(/body/i)) {
el = el.parentElement;
tagName =
el.parentElement && el.parentElement.tagName
? el.parentElement.tagName
: "";
}
return tagName && !!tagName.match(/modal/i);
}
private get isCorporate(): boolean {
return this._cRef.location.nativeElement.classList.contains(
"isp-corporate-mode-wrapper"
);
}
get _isNative(): boolean {
return /(ip(a|o)d|iphone|android)/gi.test(window.navigator.userAgent);
}
constructor(
private _parserFormatter: NgbDateParserFormatterNOA11Y,
private _elRef: ElementRef,
private _vcRef: ViewContainerRef,
private _renderer: Renderer2,
private _cfr: ComponentFactoryResolver,
ngZone: NgZone,
private _service: NgbDatepickerServiceNOA11Y,
private _calendar: NgbCalendarNOA11Y,
private eventManager: EventManager
) {
this.positionService = new Positioning();
this._zoneSubscription = ngZone.onStable.subscribe(() =>
this.setDatepickerPosition()
);
}
setDatepickerPosition() {
if (!this._cRef || !this._elRef) {
return;
}
const calendar: HTMLElement = this._cRef.location.nativeElement;
const datepickerInput: HTMLElement = this._elRef.nativeElement;
const calendarClone: HTMLElement = <HTMLElement>calendar.cloneNode(true);
this._renderer.removeClass(
calendarClone.querySelector(".isp-main-datepicker"),
"d-none"
);
this._renderer.addClass(calendarClone, "invisible");
window.document.body.appendChild(calendarClone);
const navigation: number = calendarClone.querySelector(
".isp-datepicker-navigation"
)["offsetHeight"];
const routingView: number = calendarClone.querySelector(
".isp-datepicker-routing-view"
)["offsetHeight"];
const position: ClientRect = this.positionService.positionElements(
datepickerInput,
calendarClone,
this.placement
);
this._renderer.removeChild(calendarClone.parentElement, calendarClone);
switch (this.placement) {
case this._placement.TOP:
case this._placement.TOP_RIGHT:
case this._placement.TOP_LEFT:
position.top = this.isCorporate
? -navigation - routingView
: -navigation - routingView - 3;
break;
case this._placement.RIGHT:
case this._placement.LEFT:
position.top = -navigation - routingView / 2;
break;
}
calendar.style.top = `${position.top}px`;
calendar.style.left = `${position.left}px`;
this._renderer.removeClass(
calendar.querySelector(".isp-main-datepicker"),
"d-none"
);
}
registerOnChange(fn: (value: any) => any): void {
this._onChange = fn;
}
registerOnTouched(fn: () => any): void {
this._onTouched = fn;
}
registerOnValidatorChange(fn: () => void): void {
this._validatorChange = fn;
}
setDisabledState(isDisabled: boolean): void {
this._renderer.setProperty(
this._elRef.nativeElement,
"disabled",
isDisabled
);
if (this.isOpen()) {
this._cRef.instance.setDisabledState(isDisabled);
}
}
validate(c: AbstractControl): { [key: string]: any } {
const value = c.value;
if (value === null || value === undefined) {
return null;
}
if (typeof value === "string") {
let newValue: NgbDate;
newValue = new NgbDate(
parseInt(value.substring(0, 4), 10),
parseInt(value.substring(5, 7), 10),
parseInt(value.substring(8, 10), 10)
);
if (!this._calendar.isValid(newValue)) {
return { ngbDate: { invalid: c.value } };
}
if (
this.minDate &&
NgbDate.from(newValue).before(NgbDate.from(this.minDate))
) {
return { ngbDate: { requiredBefore: this.minDate } };
}
if (
this.maxDate &&
NgbDate.from(newValue).after(NgbDate.from(this.maxDate))
) {
return { ngbDate: { requiredAfter: this.maxDate } };
}
} else {
if (!this._calendar.isValid(value)) {
return { ngbDate: { invalid: c.value } };
}
if (
this.minDate &&
NgbDate.from(value).before(NgbDate.from(this.minDate))
) {
return { ngbDate: { requiredBefore: this.minDate } };
}
if (
this.maxDate &&
NgbDate.from(value).after(NgbDate.from(this.maxDate))
) {
return { ngbDate: { requiredAfter: this.maxDate } };
}
}
}
writeValue(value: any) {
const ngbDate = value
? new NgbDate(value.year, value.month, value.day)
: null;
this._model = this._calendar.isValid(value) ? ngbDate : null;
this._writeModelValue(this._model);
}
waitForFormat(value: string, updateView = false) {
this.dataBeforeChange = value;
let actualValue = value;
setTimeout(() => {
if (actualValue === this.dataBeforeChange) {
this.manualDateChange(actualValue, updateView);
}
}, 2000);
}
manualDateChange(value: string, updateView = false) {
let datesplitted = value.split(/[./-]/g);
if (
this.nbpLabelPattern == this._pattern.MMAAAA &&
datesplitted.length < 3 &&
datesplitted.length > 1
) {
value = "01." + value;
}
let [year, month, day] = value.split("-");
if (this.isUnifiedVg && this._isNative) {
if (year && month && day) {
// value = day + '.' + month + '.' + year;
}
}
this._model = this._service.toValidDate(
this._parserFormatter.parse(value, this.nbpLabelPattern),
null
);
this._onChange(
this._model ? this._model.toStruct() : value === "" ? null : value
);
if (updateView && this._model) {
this._writeModelValue(this._model);
}
}
isOpen() {
return !!this._cRef;
}
/**
* Opens the datepicker with the selected date indicated by the ngModel value.
*/
open(mode: boolean) {
if (!this.isOpen()) {
if (this._model && (this.minDate || this.maxDate)) {
if (
(this.minDate &&
NgbDate.from(this._model).before(NgbDate.from(this.minDate))) ||
(this.maxDate &&
NgbDate.from(this._model).after(NgbDate.from(this.maxDate)))
) {
this._model = null;
}
}
const cf = this._cfr.resolveComponentFactory(RplCalendarNOA11Y);
this._cRef = this._vcRef.createComponent(cf);
this._applyPopupStyling(this._cRef.location.nativeElement);
this._cRef.instance.writeValue(this._model);
this._applyDatepickerInputs(this._cRef.instance);
this._subscribeForDatepickerOutputs(this._cRef.instance);
this._cRef.instance.disabledWeekend = this.disabledWeekend;
this._cRef.instance.holidays = this.holidays;
this._cRef.instance.taxDeadlines = this.taxDeadlines;
if (mode) {
this._renderer.addClass(
this._cRef.location.nativeElement,
"isp-corporate-mode-wrapper"
);
}
this._cRef.instance.ngOnInit();
// date selection event handling
this._cRef.instance.registerOnChange((selectedDate) => {
this.writeValue(selectedDate);
this._onChange(selectedDate);
if (!this.opened) {
this.close();
}
});
// focus handling
this._cRef.instance.focus();
}
}
/**
* Closes the datepicker popup.
*/
close() {
if (this.isOpen()) {
this._vcRef.remove(this._vcRef.indexOf(this._cRef.hostView));
this._cRef = null;
this.eventManager.emit("DATEPICKER_CLOSE", true);
}
}
/**
* Toggles the datepicker popup (opens when closed and closes when opened).
*/
toggle(mode: boolean) {
if (this.isOpen()) {
this.close();
} else {
this.open(mode);
}
}
addMargin(value: string) {
if (this._cRef) {
this._renderer.setStyle(
this._cRef.location.nativeElement,
"margin-top",
value
);
}
}
onFocusOut($event) {
const parent: HTMLElement = this._elRef.nativeElement.parentElement;
const icon: HTMLElement = parent.querySelector("i");
if (
this.isOpen() &&
!(
event.target === icon ||
this._elRef.nativeElement.contains($event.target) ||
this._cRef.location.nativeElement.contains($event.target)
)
) {
this._cRef.instance.focusOutComponent($event);
console.info("onfocusout close");
this.close();
if (this.eventManager) {
this.eventManager.emit("HANDLER_CALENDAR", {});
}
}
}
/**
* Navigates current view to provided date.
* With default calendar we use ISO 8601: 'month' is 1=Jan ... 12=Dec.
* If nothing or invalid date provided calendar will open current month.
* Use 'startDate' input as an alternative
*/
navigateTo(date?: { year: number; month: number }) {
if (this.isOpen()) {
this._cRef.instance.navigateTo(date);
}
}
onBlur() {
this._onTouched();
}
ngOnChanges(changes: SimpleChanges) {
if (changes["minDate"] || changes["maxDate"]) {
this._validatorChange();
}
}
ngOnDestroy() {
this.close();
this._zoneSubscription.unsubscribe();
}
getCalendarHeight() {
if (this._cRef && this._cRef.instance.datepickerRoutingView) {
return this._cRef.instance.datepickerRoutingView.getRoutingViewHeight();
}
return 0;
}
getCalendarWidth() {
if (this._cRef && this._cRef.instance.datepickerRoutingView) {
return this._cRef.instance.datepickerRoutingView.getRoutingViewWidth();
}
return 0;
}
getInputHeight() {
if (this._elRef) {
return this._elRef.nativeElement.offsetHeight;
}
return 0;
}
private _applyDatepickerInputs(datepickerInstance: RplCalendarNOA11Y): void {
[
"dayTemplate",
"displayMonths",
"firstDayOfWeek",
"markDisabled",
"minDate",
"maxDate",
"navigation",
"outsideDays",
"showNavigation",
"showWeekdays",
"showWeekNumbers",
].forEach((optionName: string) => {
if ((this as any)[optionName] !== undefined) {
(datepickerInstance as any)[optionName] = (this as any)[optionName];
}
});
datepickerInstance.startDate = this.startDate || this._model;
}
private _applyPopupStyling(nativeElement: any) {
this._renderer.addClass(nativeElement, "dropdown-menu");
this._renderer.setStyle(nativeElement, "padding", "0");
}
private _subscribeForDatepickerOutputs(
datepickerInstance: RplCalendarNOA11Y
) {
datepickerInstance.navigate.subscribe((date: any) =>
this.navigate.emit(date)
);
}
private _writeModelValue(model: NgbDate) {
if (model) {
const { day, month, year } = model;
if (this.nbpLabelPattern == this._pattern.MMAAAA) {
this._renderer.setProperty(
this._elRef.nativeElement,
"value",
this._parserFormatter.format(
{ year, month, day: 0 },
this.nbpLabelPattern,
this.nbpDateSeparator
)
);
} else {
this._renderer.setProperty(
this._elRef.nativeElement,
"value",
this._parserFormatter.format(
{ year, month, day },
this.nbpLabelPattern,
this.nbpDateSeparator
)
);
}
} else {
this._renderer.setProperty(
this._elRef.nativeElement,
"value",
this._parserFormatter.format(
model,
this.nbpLabelPattern,
this.nbpDateSeparator
)
);
}
if (this.isOpen()) {
this._cRef.instance.writeValue(model);
this._onTouched();
}
}
}

View File

@ -0,0 +1,102 @@
<div class="isp-datepicker-routing-view" #ispDatepickerRoutingView>
<div [ngSwitch]="currentTemplate">
<!-- giorni -->
<div *ngSwitchCase=0>
<!-- mesi nell'header. -->
<div *ngIf="showWeekdays" class="ngb-dp-week d-flex">
<div *ngIf="showWeekNumbers" class="ngb-dp-weekday"></div>
<div *ngFor="let w of month.weekdays" class="ngb-dp-weekday small text-center text-info font-italic" [attr.role]="'button'" [attr.aria-label]="' '">
<span [attr.role]="'button'" [attr.aria-label]="' '" [attr.aria-labelledby]="' '">
{{ i18n.getWeekdayShortName(w) | translate | slice: 0:3 }}
</span>
</div>
</div>
<ng-template ngFor let-week [ngForOf]="month.weeks">
<div *ngIf="!isCollapsed(week) && !isHiddenWeek(week)" class="ngb-dp-week d-flex">
<div *ngIf="showWeekNumbers" class="ngb-dp-week-number small text-center font-italic text-muted">
<span [attr.role]="'none'" [attr.aria-label]="' '">{{ week.number }}</span>
</div>
<div *ngFor="let day of week.days" (click)="doSelect(day, $event)" class="ngb-dp-day"
[class.disabled]="day.context.disabled" [class.hidden]="isHidden(day)"
[attr.role]="'none'"
[attr.aria-label]="' '">
<ng-template [ngIf]="!isHidden(day)">
<div ngbDatepickerDayView
[ngClass] = "{'cursor-pointer' : !disabledWeekend && !day.context.disabled}"
[date]="day.context.date"
[currentMonth]="day.context.currentMonth"
[selected]="day.context.selected"
[disabled]="day.context.disabled"
[focused]="day.context.focused"
[startDateEnabled]="startDateEnabled"
[endDateEnabled]="endDateEnabled"
[isToday]="day.context.isToday"
[isWeekend]="day.context.isWeekend"
[isHoliday]="day.context.isHoliday"
[taxDeadlines]="taxDeadlines"
[isFiscalDay]="day.context.isFiscalDay"
[attr.role]="'none'"
[attr.aria-label]="' '"
[attr.aria-labelledby]="' '"
[attr.aria-describedby]="' '">
</div>
</ng-template>
</div>
</div>
</ng-template>
</div>
<!-- mesi -->
<div *ngSwitchCase=1>
<div *ngFor="let row of mesi" class="d-flex ngb-dp-mese">
<ng-container *ngFor="let mese of row">
<div ngbDatepickerReplyMonthView [mese]="mese" [year]="dataTemplate.year" [selected]="mese.selected"
[disabled]="mese.disabled"
[focused]="mese.focused"
[startDateEnabled]="startDateEnabled"
[endDateEnabled]="endDateEnabled"
[attr.role]="'none'"
[attr.aria-label]="' '"
[attr.aria-labelledby]="' '"
[attr.aria-describedby]="' '"
(click)="doSelectMonth(mese, $event)">
</div>
</ng-container>
</div>
</div>
<!-- anni -->
<div *ngSwitchCase=2>
<div *ngFor="let row of years" class="d-flex ngb-dp-mese">
<ng-container *ngFor="let year of row">
<div ngbDatepickerReplyYearsView [year]="year" [selected]="year.selected" [disabled]="year.disabled"
[focused]="year.focused"
[startDateEnabled]="startDateEnabled"
[endDateEnabled]="endDateEnabled"
[attr.role]="'none'"
[attr.aria-label]="' '"
[attr.aria-labelledby]="' '"
[attr.aria-describedby]="' '"
(click)="doSelectYear(year, $event)">
</div>
</ng-container>
</div>
</div>
<!-- default -->
<div *ngSwitchDefault>errore template</div>
</div>
<div><button name="today">Oggi</button><button name="clear">Cancella</button><button name="close">Chiudi</button></div>
</div>

View File

@ -0,0 +1,112 @@
.isp-datepicker-routing-view {
pointer-events: auto;
.d-flex {
display: -webkit-box !important;
display: -ms-flexbox !important;
display: flex !important;
border-bottom-width: 0.0625rem;
border-bottom-style: solid;
border-right-width: 0.0625rem;
border-right-style: solid;
border-left-width: 0.0625rem;
border-left-style: solid;
padding: 0 0.0625rem;
&:first-child:not(.ngb-dp-mese) {
border-top-width: 0.0625rem;
border-top-style: solid;
}
&.ngb-dp-week, &.ngb-dp-mese {
.ngb-dp-day {
width: 2.6875rem !important;
height: 2.5625rem !important;
cursor: pointer;
position: relative;
box-sizing: border-box;
&.disabled, &.hidden {
cursor: default;
}
&:not(:first-child) {
border-left-width: 0.0625rem;
border-left-style: solid;
}
.cursor-pointer {
cursor : pointer !important
}
}
.bg-primary {
&::before {
position: absolute;
top: 0;
right: -0.5rem;
content: '';
display: inline-block;
width: 0;
height: 0;
margin: 0;
padding: 0;
}
}
.btn-secondary {
height: inherit;
font-size: .625rem !important;
}
.btn-secondary, .btn-secondary-month, .btn-secondary-years {
font-weight: bold;
font-size: 0.75rem;
}
div[ngbdatepickerreplymonthview], div[ngbdatepickerreplyyearsview]{
&.btn-secondary-month, &.btn-secondary-years {
border-radius: 0 !important;
box-sizing: border-box;
text-align: center;
min-width: 4.95rem !important;
height: 2.8125rem !important;
line-height: 2.8125rem !important;
vertical-align: middle !important;
border-right-width: 0.0625rem;
border-right-style: solid;
border-top-width: 0.0625rem;
border-top-style: solid;
border-collapse: collapse;
border-spacing: 0;
&:last-child {
border-right-style: none;
border-right-width: 0;
}
.ngbdatepickerreplymonthviewdisabled, .ngbDatepickerReplyYearsViewdisabled {
cursor: default;
opacity: 0.5;
}
.d-flex:first-child & {
border-top-width: 0;
border-top-style: none;
}
}
}
.is-weekend, .is-daypast {
cursor: default;
}
.ngb-dp-weekday, .ngb-dp-week-number {
width: 14.28% !important;
height: 2.375rem !important;
line-height: 2.4375rem;
&.small, & small {
font-size: 80%;
font-weight: 400;
}
&.text-center {
text-align: center !important;
}
&.font-italic {
font-family: 'Arial Bold', 'Arial';
font-weight: 700;
font-style: normal !important;
font-size: .875rem;
text-align: center;
text-transform: uppercase;
}
}
}
}
}

View File

@ -0,0 +1,292 @@
import {
Component,
EventEmitter,
Input,
OnInit,
Output,
TemplateRef,
ChangeDetectionStrategy,
ChangeDetectorRef,
SimpleChanges,
OnChanges,
OnDestroy,
ViewChild,
ElementRef,
} from "@angular/core";
import { CalendarItemNOA11Y } from "./datepicker";
import { Subscription } from "rxjs";
import {
DayTemplateContextNOA11Y,
NgbDataTemplateStruct,
MonthViewModel,
NgbDate,
NgbDatepickerI18nNOA11Y,
NgbDatepickerServiceNOA11Y,
DayViewModel,
WeekViewModel,
} from "@isp/xdce-widget";
@Component({
selector: "ngb-datepicker-routing-view",
host: { class: "d-block" },
templateUrl: "./datepicker-routing-view.html",
styleUrls: ["./datepicker-routing-view.scss"],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class NgbDatepickerRoutingViewNOA11Y
implements OnInit, OnChanges, OnDestroy
{
@Input() dayTemplate: TemplateRef<DayTemplateContextNOA11Y>;
@Input() monthTemplate: TemplateRef<DayTemplateContextNOA11Y>;
@Input() yearsTemplate: TemplateRef<DayTemplateContextNOA11Y>;
@Input() currentTemplate: number;
@Input() mesi: any;
@Input() years: any;
@Input() disabledWeekend: boolean;
@Input() date: any;
@Input() dataTemplate: NgbDataTemplateStruct;
@Input() month: MonthViewModel;
@Input() outsideDays: "visible" | "hidden" | "collapsed";
@Input() showWeekdays;
@Input() showWeekNumbers;
@Input() startDateEnabled: any;
@Input() endDateEnabled: any;
@Input() isToday: boolean;
@Input() isWeekend: boolean;
@Input() taxDeadlines: any;
@Output() select = new EventEmitter<NgbDate>();
@Output() changeTemplate = new EventEmitter<NgbDataTemplateStruct>();
@ViewChild("ispDatepickerRoutingView") routingView: ElementRef;
currentYear: number;
currentMonth: number;
currentDay: number;
sub: Subscription;
constructor(
public i18n: NgbDatepickerI18nNOA11Y,
private cdr: ChangeDetectorRef,
private service: NgbDatepickerServiceNOA11Y
) {}
ngOnInit() {
// alert("in select in routing : " + this.startDateEnabled)
// alert("in select in routing : " + this.endDateEnabled)
// this.currentYear = this.date && this.date.year;
// this.currentMonth = this.date && this.date.month;
// console.info('routing init', this.currentYear, this.currentMonth);
this.dataTemplate.day = this.date && this.date.day;
this.dataTemplate.month = this.date && this.date.month;
this.dataTemplate.year = this.date && this.date.year;
const model = this.service._model$.getValue();
if (model && model.selectedDate) {
this.currentDay = model.selectedDate.day;
this.currentMonth = model.selectedDate.month;
this.currentYear = model.selectedDate.year;
}
// this.sub = this.service.model$.subscribe((model) => {
// if(model.selectedDate) {
// this.currentDay = model.selectedDate.day;
// this.currentMonth = model.selectedDate.month;
// this.currentYear = model.selectedDate.year;
// }
// })
// console.info('routing init', this.date, this.dataTemplate);
}
ngOnDestroy(): void {
// if (this.sub) {
// this.sub.unsubscribe();
// }
}
ngOnChanges(changes: SimpleChanges) {
if (changes.years) {
this.years = [...changes.years.currentValue];
}
if (changes.currentTemplate || changes.dataTemplate) {
this.resetMesi();
this.resetAnni();
const model = this.service._model$.getValue();
if (model && model.selectedDate) {
this.currentDay = model.selectedDate.day;
this.currentMonth = model.selectedDate.month;
this.currentYear = model.selectedDate.year;
}
}
this.cdr.detectChanges();
}
doSelect(day: DayViewModel, $event: any) {
if (!this.abilitaGiorni(day.date)) {
return;
}
if (this.dataTemplate.valid) {
// il day si prende quello selezionato e non quello del dataTemplate
// day.date.day = this.dataTemplate.day;
day.date.month = this.dataTemplate.month;
day.date.year = this.dataTemplate.year;
this.currentYear = day.date.year;
this.currentMonth = day.date.month;
this.currentDay = day.date.day;
this.select.emit(NgbDate.from(day.date));
} else {
if (!day.context.disabled && !this.isHidden(day)) {
this.currentYear = day.date.year;
this.currentMonth = day.date.month;
this.currentDay = day.date.day;
this.select.emit(NgbDate.from(day.date));
}
}
$event.stopPropagation();
}
abilitaGiorni(data) {
let buffer = new Date(data.year, data.month - 1, data.day);
let startDate = new Date(
this.startDateEnabled.year,
this.startDateEnabled.month - 1,
this.startDateEnabled.day
);
let endDate = new Date(
this.endDateEnabled.year,
this.endDateEnabled.month - 1,
this.endDateEnabled.day
);
return startDate <= buffer && buffer <= endDate;
}
abilitaMesi(data) {
return (
((this.startDateEnabled.year == this.dataTemplate.year &&
this.startDateEnabled.month <= data.number) ||
(data.number < this.startDateEnabled.month &&
this.startDateEnabled.year < this.dataTemplate.year) ||
(this.startDateEnabled.month <= data.number &&
this.startDateEnabled.year <= this.dataTemplate.year)) &&
((data.number <= this.endDateEnabled.month &&
this.dataTemplate.year <= this.endDateEnabled.year) ||
(data.number > this.endDateEnabled.month &&
this.dataTemplate.year < this.endDateEnabled.year))
);
}
abilitaAnni(data) {
return (
this.startDateEnabled.year <= data.number &&
data.number <= this.endDateEnabled.year
);
}
doSelectMonth(mese: any, $event: any) {
if (!this.abilitaMesi(mese)) {
return;
}
this.currentTemplate = 0;
this.dataTemplate.template = this.currentTemplate;
// reset giorni
this.month.weeks.forEach((week) => {
week.days.forEach((day) => {
day.context.selected =
day.date.day === this.currentDay &&
day.date.month === this.currentMonth &&
day.date.year === this.currentYear;
});
});
this.resetMesi();
this.dataTemplate.month = mese.number;
this.dataTemplate.valid = true;
this.changeTemplate.emit(this.dataTemplate);
$event.stopPropagation();
}
doSelectYear(year: any, $event: any) {
if (!this.abilitaAnni(year)) {
return;
}
this.currentTemplate = 1;
this.dataTemplate.template = this.currentTemplate;
// resetta mesi e anno
this.resetMesi();
this.dataTemplate.year = year.number;
this.dataTemplate.valid = true;
this.changeTemplate.emit(this.dataTemplate);
$event.stopPropagation();
}
isCollapsed(week: WeekViewModel) {
return (
this.outsideDays === "collapsed" &&
week.days[0].date.month !== this.month.number &&
week.days[week.days.length - 1].date.month !== this.month.number
);
}
isHiddenWeek(week: WeekViewModel) {
let counter = 0;
for (let i = 0; i < week.days.length; i++) {
if (this.isHidden(week.days[i])) {
counter++;
}
}
return counter === 7;
}
isHidden(day: DayViewModel) {
return (
(this.outsideDays === "hidden" || this.outsideDays === "collapsed") &&
this.month.number !== day.date.month
);
}
getRoutingViewHeight() {
return this.routingView.nativeElement.offsetHeight;
}
getRoutingViewWidth() {
return this.routingView.nativeElement.offsetWidth;
}
private resetMesi() {
let months: CalendarItemNOA11Y[][] = [];
months = this.mesi.map((row) => {
return row.map((m) => {
const res = { ...m };
res.selected =
res.number === this.currentMonth &&
this.dataTemplate.year === this.currentYear;
return res;
});
});
this.mesi = months;
}
private resetAnni() {
let yrs: CalendarItemNOA11Y[][] = [];
yrs = this.years.map((row) => {
return row.map((y) => {
const res = { ...y };
res.selected = res.number === this.currentYear;
return res;
});
});
this.years = yrs;
}
}

View File

@ -0,0 +1,78 @@
<!-- intestazione -->
<div class="isp-main-datepicker d-none">
<div class="ngb-dp-header bg-faded pt-1 rounded-top" [style.height.rem]="getHeaderHeight()"
[style.marginBottom.rem]="-getHeaderMargin()">
<!-- componente per la navigazione! Seleziona il template -->
<ngb-datepicker-navigation *ngIf="navigation !== 'none'"
[date]="model.firstDate"
[minDate]="model.minDate"
[maxDate]="model.maxDate"
[months]="model.months.length"
[years]="years"
[template]="template"
[disabled]="model.disabled"
[showWeekNumbers]="showWeekNumbers"
[showSelect]="navigation === 'select'"
[disabledWeekend]="model.disabledWeekend"
[holidays]="model.holidays"
[taxDeadlines]="model.taxDeadlines"
(navigate)="onNavigateEvent($event)"
(select)="onNavigateDateSelect($event)"
(newTemplate)="setNewTemplate($event)"
[attr.role]="'none'"
[attr.label]="' '"
[attr.labelledby]="' '"
[attr.describedby]="' '">
</ngb-datepicker-navigation>
</div>
<!-- corpo componente -->
<div class="ngb-dp-months d-flex px-1 pb-1">
<ng-template ngFor let-month [ngForOf]="model.months" let-i="index">
<div class="ngb-dp-month d-block ml-3">
<div *ngIf="navigation !== 'select' || displayMonths > 1" style="min-width:150px"
class="ngb-dp-month-name text-center" (click)="setNewTemplate((template+1)%3);$event.stopPropagation();">
<div [ngSwitch]="template" style="margin-top:1px">
<div *ngSwitchCase=0 >
{{ i18n.getMonthFullName(dataTemplate.month) | translate }} {{ dataTemplate.year }}
</div>
<div *ngSwitchCase=1>
{{ dataTemplate.year }}
</div>
<div *ngSwitchCase=2>
{{ dataTemplate.year }} - {{ dataTemplate.year + 11 }}
</div>
</div>
</div>
<!-- componente routing che usa il template selezionato-->
<ngb-datepicker-routing-view
[mesi]="mesi"
[years]="years"
[disabledWeekend]="disabledWeekend"
[dataTemplate]="dataTemplate"
[date]="model.firstDate"
[currentTemplate]="template"
[month]="month"
[showWeekdays]="showWeekdays"
[showWeekNumbers]="showWeekNumbers"
[startDateEnabled]="startDateEnabled"
[endDateEnabled]="endDateEnabled"
[outsideDays]="(displayMonths === 1 ? outsideDays : 'hidden')"
[taxDeadlines]="taxDeadlines"
(select)="onDateSelect($event)"
(changeTemplate)="onChangeTemplate($event)"
[attr.role]="'none'"
[attr.label]="' '"
[attr.labelledby]="' '"
[attr.describedby]="' '">
</ngb-datepicker-routing-view>
</div>
</ng-template>
</div>
</div>

View File

@ -0,0 +1,201 @@
:host(.isp-corporate-mode-wrapper) {
&.dropdown-menu {
margin-top: 0;
}
.isp-main-datepicker{
.ngb-dp-header {
height: 2.1875rem!important;
margin-bottom: 0 !important;
& ::ng-deep .isp-datepicker-navigation {
height: 2.1875rem !important;
border-top-left-radius: 0.125rem;
border-top-right-radius: 0.125rem;
span {
button.btn-link {
width: 2.1875rem;
height: 2.1875rem;
font-size: 0.9375rem;
&:disabled {
opacity: 0.5;
cursor: default;
}
}
}
}
}
.ngb-dp-months {
.ngb-dp-month {
.ngb-dp-month-name {
height: 2.1875rem !important;
margin-top: -2.1875rem !important;
top: auto;
line-height: 0.875rem !important;
font-size: 0.75rem !important;
}
& ::ng-deep .isp-datepicker-routing-view {
.d-flex {
border-bottom-style: none;
border-bottom-width: initial;
&:last-child{
border-bottom-width: 0.0625rem;
border-bottom-style: solid;
border-bottom-left-radius: 0.125rem;
border-bottom-right-radius: 0.125rem;
}
&.ngb-dp-mese:first-child {
border-top-width: 0.0625rem;
border-top-style: solid;
}
&.ngb-dp-week, &.ngb-dp-mese {
.ngb-dp-week-number {
height: inherit !important;
line-height: inherit;
width: 2.125rem !important;
font-size: 0.75rem;
}
.ngb-dp-weekday {
height: inherit !important;
line-height: 1.3125rem;
width: 2.125rem !important;
font-size: 0.625rem;
}
.ngb-dp-day {
width: 2.125rem !important;
height: 2.125rem !important;
font-size: 0.75rem;
&:not(:first-child) {
border-left: none;
}
.bg-primary, .btn-secondary {
font-size: 0.75rem;
.ngbdatepickerdayview, .ngbdatepickerdayviewdisabled {
line-height: 2.125rem !important;
}
.ngbdatepickerreplymonthview {
cursor: pointer;
}
.ngbdatepickerdayviewdisabled, .ngbdatepickerreplymonthviewdisabled {
cursor: default;
}
.ngbDatepickerReplyYearsView {
cursor: pointer;
}
.ngbDatepickerReplyYearsView[disabled] {
cursor: default;
}
.ngbDatepickerReplyYearsViewdisabled {
cursor: default;
}
}
.is-weekend, .is-daypast, .text-muted {
.ngbdatepickerdayview{
opacity: .5;
}
}
}
div[ngbdatepickerreplymonthview], div[ngbdatepickerreplyyearsview]{
&.btn-secondary-month, &.btn-secondary-years {
min-width: 0rem !important;
width: 3.75rem !important;
height: 2.125rem !important;
line-height: 2.125rem !important;
border-right: none;
border-top: none;
font-size: 0.75rem;
.ngbdatepickerdayview, .ngbdatepickerreplymonthview {
cursor: pointer;
}
.ngbdatepickerdayviewdisabled, .ngbdatepickerreplymonthviewdisabled {
cursor: default;
}
.ngbDatepickerReplyYearsView {
cursor: pointer;
}
.ngbDatepickerReplyYearsView[disabled] {
cursor: default;
}
.ngbDatepickerReplyYearsViewdisabled {
cursor: default;
}
}
}
}
}
}
}
}
}
}
.isp-main-datepicker {
.justify-content-between {
-webkit-box-pack: justify !important;
-ms-flex-pack: justify !important;
justify-content: space-between !important;
}
.d-flex {
display: -webkit-box !important;
display: -ms-flexbox !important;
display: flex !important;
height: 3.125rem !important;
line-height: 1.875rem !important;
}
.collapsed {
margin-bottom: -2rem;
}
.ngb-dp-header {
height: 4.625rem !important;
margin-bottom: -1.5rem !important;
border-bottom: none !important;
&.pt-1 {
padding-top: 0 !important;
height: 4.25rem;
margin-bottom: -2rem;
}
&.rounded-top {
border-radius: 0 !important;
}
}
.ngb-dp-months {
&.pb-1 {
padding: 0 !important;
}
&.px-1 {
padding-left: 0 !important;
padding-right: 0 !important;
}
.ngb-dp-month {
pointer-events: none;
&:first-child {
margin-left: 0 !important;
}
&.ml-3 {
margin-left: 1rem;
}
&.d-block {
display: block !important;
}
.ngb-dp-month-name {
font-family: 'Arial', sans-serif;
font-size: 1rem !important;
font-weight: 700;
text-transform: uppercase;
position: absolute;
text-align: center !important;
top: 0;
height: 3.125rem !important;
line-height: 1.42857143rem !important;
word-wrap: break-word;
word-break: break-word;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
display:flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
}
}
}

View File

@ -0,0 +1,800 @@
import { Subscription } from "rxjs";
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
Input,
OnChanges,
TemplateRef,
forwardRef,
OnInit,
SimpleChanges,
EventEmitter,
Output,
OnDestroy,
ElementRef,
ViewChild,
ViewChildren,
} from "@angular/core";
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from "@angular/forms";
import { NgbDatepickerRoutingViewNOA11Y } from "./datepicker-routing-view";
import {
DatepickerViewModel,
DayTemplateContextNOA11Y,
EnabledRangeService,
isChangedDate,
NavigationEvent,
NgbCalendarNOA11Y,
NgbDataTemplateStruct,
NgbDate,
NgbDatepickerConfigNOA11Y,
NgbDatepickerI18nNOA11Y,
NgbDatepickerKeyMapServiceNOA11Y,
NgbDatepickerServiceNOA11Y,
NgbDateStruct,
} from "@isp/xdce-widget";
import { toInteger } from "@isp/xdce-widget/user-input/isp-typeahead/ng-bootstrap/util";
const NGB_CALENDAR_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => RplCalendarNOA11Y),
multi: true,
};
/**
* The payload of the datepicker navigation event
*/
export interface RplCalendarNavigateEventNOA11Y {
/**
* Currently displayed month
*/
current: { year: number; month: number };
/**
* Month we're navigating to
*/
next: { year: number; month: number };
}
export class CalendarItemNOA11Y {
name: string;
number: number;
focused: boolean;
disabled: boolean;
selected: boolean;
}
/**
* A lightweight and highly configurable datepicker directive
*/
@Component({
exportAs: "fidRplCalendarNOA11Y",
selector: "fid-rpl-calendar-noa11y",
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
class: "d-inline-block rounded",
tabindex: "0",
"[attr.tabindex]": 'model.disabled ? undefined : "0"',
"(blur)": "showFocus(false)",
"(focus)": "showFocus(true)",
"(keydown)": "onKeyDown($event)",
},
templateUrl: './datepicker.html',
styleUrls: ["./datepicker.scss"],
providers: [
NGB_CALENDAR_VALUE_ACCESSOR,
NgbDatepickerServiceNOA11Y,
NgbDatepickerKeyMapServiceNOA11Y,
],
})
export class RplCalendarNOA11Y
implements OnDestroy, OnChanges, OnInit, ControlValueAccessor
{
model: DatepickerViewModel;
@ViewChild(forwardRef(() => NgbDatepickerRoutingViewNOA11Y))
datepickerRoutingView: NgbDatepickerRoutingViewNOA11Y;
@ViewChild(forwardRef(() => NgbDatepickerRoutingViewNOA11Y))
datepickerHeader: NgbDatepickerRoutingViewNOA11Y;
private _subscription: Subscription;
/**
* Reference for the custom template for the day display
*/
@Input() dayTemplate: TemplateRef<DayTemplateContextNOA11Y>;
/**
* Number of months to display
*/
@Input() displayMonths: number;
/**
* First day of the week. With default calendar we use ISO 8601: 'weekday' is 1=Mon ... 7=Sun
*/
@Input() firstDayOfWeek: number;
/**
* Callback to mark a given date as disabled.
* 'Current' contains the month that will be displayed in the view
*/
@Input() markDisabled: (
date: NgbDateStruct,
current: { year: number; month: number }
) => boolean;
/**
* Min date for the navigation. If not provided will be 10 years before today or `startDate`
*/
_minDate: NgbDateStruct;
@Input()
get minDate() {
return this._minDate;
}
set minDate(minDate: NgbDateStruct) {
this._minDate = minDate;
this.startDateEnabled = minDate;
}
/**
* Max date for the navigation. If not provided will be 10 years from today or `startDate`
*/
_maxDate: NgbDateStruct;
@Input()
get maxDate() {
return this._maxDate;
}
set maxDate(maxDate: NgbDateStruct) {
this._maxDate = maxDate;
this.endDateEnabled = maxDate;
}
/**
* Navigation type: `select` (default with select boxes for month and year), `arrows`
* (without select boxes, only navigation arrows) or `none` (no navigation at all)
*/
@Input() navigation: "select" | "arrows" | "none";
/**
* The way to display days that don't belong to current month: `visible` (default),
* `hidden` (not displayed) or `collapsed` (not displayed with empty space collapsed)
*/
@Input() outsideDays: "visible" | "collapsed" | "hidden";
/**
* Whether to display days of the week
*/
@Input() showWeekdays: boolean;
/**
* Whether to display week numbers
*/
@Input() showWeekNumbers: boolean;
/**
* Date to open calendar with.
* With default calendar we use ISO 8601: 'month' is 1=Jan ... 12=Dec.
* If nothing or invalid date provided, calendar will open with current month.
* Use 'navigateTo(date)' as an alternative
*/
@Input() startDate: { year: number; month: number; day?: number };
@Input() startDateEnabled: any;
@Input() endDateEnabled: any;
@Input() disabledWeekend: boolean;
@Input() holidays: Array<NgbDateStruct>;
@Input() taxDeadlines: Array<NgbDateStruct>;
// /**
// * Start date Enabled
// */
// @Input() startDateEnabled: { year: number, month: number, day: number };
// /**
// * End date Enabled
// */
// @Input() endDateEnabled: { year: number, month: number, day: number };
/**
* In questa variabile sono memorizzati i dati iniziali che scenderanno l'albero dei template
*/
dataTemplate: NgbDataTemplateStruct = {
template: 0,
day: 0,
month: 0,
year: 0,
valid: false,
};
/**
* An event fired when navigation happens and currently displayed month changes.
* See NgbDatepickerNavigateEvent for the payload info.
*/
@Output() navigate = new EventEmitter<NgbDatepickerNavigateEventNOA11Y>();
/**
* Template da Adoperare
*/
template: number = 0;
mesi: CalendarItemNOA11Y[][] = [
[
{
name: "JAN",
number: 1,
disabled: false,
selected: false,
focused: false,
},
{
name: "FEB",
number: 2,
disabled: false,
selected: false,
focused: false,
},
{
name: "MAR",
number: 3,
disabled: false,
selected: false,
focused: false,
},
{
name: "APR",
number: 4,
disabled: false,
selected: false,
focused: false,
},
],
[
{
name: "MAY",
number: 5,
disabled: false,
selected: false,
focused: false,
},
{
name: "JUN",
number: 6,
disabled: false,
selected: false,
focused: false,
},
{
name: "JUL",
number: 7,
disabled: false,
selected: false,
focused: false,
},
{
name: "AUG",
number: 8,
disabled: false,
selected: false,
focused: false,
},
],
[
{
name: "SEP",
number: 9,
disabled: false,
selected: false,
focused: false,
},
{
name: "OCT",
number: 10,
disabled: false,
selected: false,
focused: false,
},
{
name: "NOV",
number: 11,
disabled: false,
selected: false,
focused: false,
},
{
name: "DEC",
number: 12,
disabled: false,
selected: false,
focused: false,
},
],
];
years: CalendarItemNOA11Y[][] = [
[
{
name: "2018",
number: 2018,
disabled: false,
selected: false,
focused: false,
},
{
name: "2019",
number: 2019,
disabled: false,
selected: false,
focused: false,
},
{
name: "2020",
number: 2020,
disabled: false,
selected: false,
focused: false,
},
{
name: "2021",
number: 2021,
disabled: false,
selected: false,
focused: false,
},
],
[
{
name: "2022",
number: 2022,
disabled: false,
selected: false,
focused: false,
},
{
name: "2023",
number: 2023,
disabled: false,
selected: false,
focused: false,
},
{
name: "2024",
number: 2024,
disabled: false,
selected: false,
focused: false,
},
{
name: "2025",
number: 2025,
disabled: false,
selected: false,
focused: false,
},
],
[
{
name: "2026",
number: 2026,
disabled: false,
selected: false,
focused: false,
},
{
name: "2027",
number: 2027,
disabled: false,
selected: false,
focused: false,
},
{
name: "2028",
number: 2028,
disabled: false,
selected: false,
focused: false,
},
{
name: "2029",
number: 2029,
disabled: false,
selected: false,
focused: false,
},
],
];
onChange = (_: any) => {};
onTouched = () => {};
// startDateEnabled: string;
// endDateEnabled: string;
constructor(
private enabledRange: EnabledRangeService,
private _keyMapService: NgbDatepickerKeyMapServiceNOA11Y,
public _service: NgbDatepickerServiceNOA11Y,
private _calendar: NgbCalendarNOA11Y,
public i18n: NgbDatepickerI18nNOA11Y,
config: NgbDatepickerConfigNOA11Y,
private _cd: ChangeDetectorRef,
private _elementRef: ElementRef
) {
this.dayTemplate = config.dayTemplate;
this.displayMonths = config.displayMonths;
this.firstDayOfWeek = config.firstDayOfWeek;
this.markDisabled = config.markDisabled;
this.minDate = config.minDate;
this.maxDate = config.maxDate;
this.navigation = config.navigation;
this.showWeekdays = config.showWeekdays;
this.showWeekNumbers = config.showWeekNumbers;
this.startDate = config.startDate;
this.disabledWeekend = config.disabledWeekend;
this.holidays = config.holidays;
this.taxDeadlines = config.taxDeadlines;
this.startDateEnabled = enabledRange.startDate;
this.endDateEnabled = enabledRange.endDate;
// alert("finale Start : " + this.startDateEnabled)
// alert("finale End : " + this.endDateEnabled)
this._subscription = _service.model$.subscribe((model) => {
const newDate = model.firstDate;
const oldDate = this.model ? this.model.firstDate : null;
const newSelectedDate = model.selectedDate;
const oldSelectedDate = this.model ? this.model.selectedDate : null;
this.model = model;
// handling selection change
if (isChangedDate(newSelectedDate, oldSelectedDate)) {
this.onTouched();
this.onChange(
newSelectedDate
? {
year: newSelectedDate.year,
month: newSelectedDate.month,
day: newSelectedDate.day,
}
: null
);
}
// emitting navigation event if the first month changes
if (!newDate.equals(oldDate)) {
this.navigate.emit({
current: oldDate
? { year: oldDate.year, month: oldDate.month }
: null,
next: { year: newDate.year, month: newDate.month },
});
}
_cd.markForCheck();
});
}
abilitaMesi(data) {
if (
this.startDateEnabled.month <= data &&
data <= this.endDateEnabled.month &&
this.startDateEnabled.year <= this.dataTemplate.year &&
this.dataTemplate.year <= this.endDateEnabled.year
) {
return true;
}
return false;
}
abilitaAnni(data) {
if (
this.startDateEnabled.year <= data &&
data <= this.endDateEnabled.year
) {
return true;
}
return false;
}
setNewTemplate(selectedTemplate: number) {
this.setMesi(this.dataTemplate.month, true);
this.updateYears(this.dataTemplate.year);
this.setYear(this.dataTemplate.year, true);
const prevTemplate = this.template;
this.template = selectedTemplate;
if (prevTemplate === 2 && this.template === 0) {
const model = this._service._model$.getValue();
if (model && model.selectedDate) {
this.navigateTo({
month: model.selectedDate.month,
year: model.selectedDate.year,
});
}
}
}
setMesi(position: number, selected: boolean) {
if (!this.abilitaMesi(position)) return;
let nRow = 0,
nCol = 0;
if (position == 4) nRow = 0;
else if (position == 8) nRow = 1;
else if (position == 12) nRow = 2;
else nRow = Math.trunc(position / 4);
nCol = position - nRow * 4 - 1;
console.info(
"dataTemplate",
this.dataTemplate,
"mese",
this.mesi[nRow][nCol],
"nRow",
nRow,
"nCol",
nCol
);
this.mesi[nRow][nCol].selected = selected;
}
updateYears(startYearValue: number) {
let yrs: CalendarItemNOA11Y[][] = [];
for (let j = 0; j < 3; j++) {
yrs[j] = [];
for (let i = 0; i < 4; i++) {
const yr = new CalendarItemNOA11Y();
yr.number = startYearValue + i + j * 4;
yr.name = yr.number + "";
yr.disabled = false;
yr.focused = false;
yr.selected = false;
yrs[j][i] = yr;
// this.years[j][i].number = startYearValue + i + j * 4
// this.years[j][i].name = this.years[j][i].number + "";
}
}
yrs.forEach((row) => {
row.forEach((y) => {
y.selected = this.dataTemplate.year === y.number;
});
});
this.years = yrs;
}
setYear(yearValue: number, selected: boolean) {
if (!this.abilitaAnni(yearValue)) return;
this.years.forEach((row) => {
row.forEach((year) => {
if (year.number == yearValue) year.selected = selected;
});
});
}
/**
* Manually focus the calendar
*/
focus() {
this._elementRef.nativeElement.focus();
}
getHeaderHeight() {
const h = this.showWeekdays ? 6.25 : 4.25;
return this.displayMonths === 1 || this.navigation !== "select" ? h - 2 : h;
}
getHeaderMargin() {
const m = this.showWeekdays ? 2 : 0;
return this.displayMonths !== 1 || this.navigation !== "select" ? m + 2 : m;
}
/**
* Navigates current view to provided date.
* With default calendar we use ISO 8601: 'month' is 1=Jan ... 12=Dec.
* If nothing or invalid date provided calendar will open current month.
* Use 'startDate' input as an alternative
*/
navigateTo(date?: { year: number; month: number }) {
this._service.open(
date ? new NgbDate(date.year, date.month, 1) : this._calendar.getToday()
);
}
ngOnDestroy() {
this._subscription.unsubscribe();
}
ngOnInit() {
if (this.model === undefined) {
this._service.displayMonths = toInteger(this.displayMonths);
this._service.markDisabled = this.markDisabled;
this._service.firstDayOfWeek = this.firstDayOfWeek;
this._service.disabledWeekend = this.disabledWeekend;
this._service.holidays = this.holidays;
this._service.taxDeadlines = this.taxDeadlines;
this._setDates();
// inixializzazione dataTemplate alla data selezionata
if (!this.startDate || !this.startDate.month || !this.startDate.year) {
this.startDate = { year: null, month: null, day: null };
let today = new Date();
let dd = today.getDate();
let mm = today.getMonth() + 1; //January is 0!
let yyyy = today.getFullYear();
this.startDate.day = dd;
this.startDate.month = mm;
this.startDate.year = yyyy;
}
this.dataTemplate.day = this.startDate.day;
this.dataTemplate.month = this.startDate.month;
this.dataTemplate.year = this.startDate.year;
this.dataTemplate.valid = false;
let elem: HTMLElement = this._elementRef.nativeElement;
elem.classList.contains("isp-corporate-mode-wrapper")
? (this.outsideDays = "hidden")
: (this.outsideDays = "visible");
}
}
ngOnChanges(changes: SimpleChanges) {
if (changes["displayMonths"]) {
this._service.displayMonths = toInteger(this.displayMonths);
}
if (changes["markDisabled"]) {
this._service.markDisabled = this.markDisabled;
}
if (changes["firstDayOfWeek"]) {
this._service.firstDayOfWeek = this.firstDayOfWeek;
}
if (changes["taxDeadlines"]) {
this._service.taxDeadlines = this.taxDeadlines;
}
}
onDateSelect(date: NgbDate) {
this._service.focus(date);
this.writeValue(date);
}
onKeyDown(event: KeyboardEvent) {
this._keyMapService.processKey(event);
}
onNavigateDateSelect(date: NgbDate) {
this._service.open(date);
}
onNavigateEvent(event: NavigationEvent) {
let bufferData: NgbDate;
this.model.firstDate.month = this.dataTemplate.month;
this.model.firstDate.year = this.dataTemplate.year;
if (event == NavigationEvent.PREV && this.template == 0) {
bufferData = this._calendar.getPrev(this.model.firstDate, "m", 1);
this._service.open(bufferData);
this.updateDataTemplate(bufferData);
} else if (NavigationEvent.NEXT && this.template == 0) {
bufferData = this._calendar.getNext(this.model.firstDate, "m", 1);
this._service.open(bufferData);
this.updateDataTemplate(bufferData);
} else if (event == NavigationEvent.PREV && this.template == 1) {
bufferData = this._calendar.getPrev(this.model.firstDate, "m", 12);
this._service.open(bufferData);
this.updateDataTemplate(bufferData);
} else if (event == NavigationEvent.NEXT && this.template == 1) {
bufferData = this._calendar.getNext(this.model.firstDate, "m", 12);
this._service.open(bufferData);
this.updateDataTemplate(bufferData);
} else if (event == NavigationEvent.PREV && this.template == 2) {
bufferData = this._calendar.getPrev(this.model.firstDate, "m", 144);
this._service.open(bufferData);
this.updateDataTemplate(bufferData);
this.updateYears(this.dataTemplate.year);
} else if (event == NavigationEvent.NEXT && this.template == 2) {
bufferData = this._calendar.getNext(this.model.firstDate, "m", 144);
this._service.open(bufferData);
this.updateDataTemplate(bufferData);
this.updateYears(this.dataTemplate.year);
}
}
onChangeTemplate(dataTemplate: NgbDataTemplateStruct) {
this.dataTemplate = dataTemplate;
this.template = dataTemplate.template;
this.navigateTo({ month: dataTemplate.month, year: dataTemplate.year });
}
updateDataTemplate(date: NgbDate) {
const newTemplate = { ...this.dataTemplate };
newTemplate.day = date.day;
newTemplate.month = date.month;
newTemplate.year = date.year;
this.dataTemplate = newTemplate;
this.navigateTo({
month: this.dataTemplate.month,
year: this.dataTemplate.year,
});
}
registerOnChange(fn: (value: any) => any): void {
this.onChange = fn;
}
registerOnTouched(fn: () => any): void {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean) {
this._service.disabled = isDisabled;
}
showFocus(focusVisible: boolean) {
this._service.focusVisible = focusVisible;
}
writeValue(value: any) {
this._service.select(value);
}
private _setDates() {
const startDate = this._service.toValidDate(
this.startDate,
this._calendar.getToday()
);
const minDate = this._service.toValidDate(
this.minDate,
this._calendar.getPrev(startDate, "y", 10)
);
const maxDate = this._service.toValidDate(
this.maxDate,
this._calendar.getPrev(this._calendar.getNext(startDate, "y", 11))
);
this.minDate = {
year: minDate.year,
month: minDate.month,
day: minDate.day,
};
this.maxDate = {
year: maxDate.year,
month: maxDate.month,
day: maxDate.day,
};
this._service.minDate = minDate;
this._service.maxDate = maxDate;
this.navigateTo(startDate);
}
public focusOutComponent(event: any) {
if (!this._elementRef.nativeElement.contains(event.target)) {
let elem: HTMLElement = this._elementRef.nativeElement;
if (elem.parentElement) {
elem.parentElement.removeChild(elem);
}
this._subscription.unsubscribe();
}
}
}
/**
* The payload of the calendar navigation event
*/
export interface NgbDatepickerNavigateEventNOA11Y {
/**
* Currently displayed month
*/
current: { year: number; month: number };
/**
* Month we're navigating to
*/
next: { year: number; month: number };
}

View File

@ -0,0 +1,669 @@
import {
ComponentFactoryResolver,
ComponentRef,
Directive,
ElementRef,
EventEmitter,
Input,
NgZone,
OnChanges,
OnDestroy,
Output,
Renderer2,
SimpleChanges,
TemplateRef,
ViewContainerRef,
forwardRef,
} from "@angular/core";
import {
AbstractControl,
ControlValueAccessor,
NG_VALIDATORS,
NG_VALUE_ACCESSOR,
Validator,
} from "@angular/forms";
import {
DayTemplateContext,
NbpCalendarPattern,
NbpCalendarPosition,
NbpDateSeparator,
NgbCalendar,
NgbDate,
NgbDateParserFormatter,
NgbDateStruct,
NgbDatepickerNavigateEvent,
NgbDatepickerService,
} from "@isp/xdce-widget";
import { RplCalendar } from "./datepicker";
import { EventManager } from "@isp/xdce-arch-core-base";
import { Positioning } from "@isp/xdce-widget/user-input/isp-typeahead/ng-bootstrap/positioning";
const NGB_DATEPICKER_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NgbInputDatepicker),
multi: true,
};
const NGB_DATEPICKER_VALIDATOR = {
provide: NG_VALIDATORS,
useExisting: forwardRef(() => NgbInputDatepicker),
multi: true,
};
/**
* A directive that makes it possible to have datepickers on input fields.
* Manages integration with the input field itself (data entry) and ngModel (validation etc.).
*/
@Directive({
selector: "input[fidRplCalendar]",
exportAs: "fidRplCalendar",
host: {
"(input)": "waitForFormat($event.target.value)",
"(change)": "manualDateChange($event.target.value, true)",
"(keyup.esc)": "close()",
"(blur)": "onBlur()",
"(document:click)": "onFocusOut($event)",
},
providers: [
NGB_DATEPICKER_VALUE_ACCESSOR,
NGB_DATEPICKER_VALIDATOR,
NgbDatepickerService,
],
})
export class NgbInputDatepicker
implements OnChanges, OnDestroy, ControlValueAccessor, Validator
{
private _cRef: ComponentRef<RplCalendar> = null;
private _model: NgbDate;
private _zoneSubscription: any;
opened: boolean;
dataBeforeChange;
@Input() onDateSelectedCallback: (value: any) => void | null;
/**
* Reference for the custom template for the day display
*/
@Input() dayTemplate: TemplateRef<DayTemplateContext>;
/**
* Number of months to display
*/
@Input() displayMonths: number;
/**
* First day of the week. With default calendar we use ISO 8601: 1=Mon ... 7=Sun
*/
@Input() firstDayOfWeek: number;
/**
* Callback to mark a given date as disabled.
* 'Current' contains the month that will be displayed in the view
*/
@Input() markDisabled: (
date: NgbDateStruct,
current: { year: number; month: number }
) => boolean;
/**
* Min date for the navigation. If not provided will be 10 years before today or `startDate`
*/
_minDate: NgbDateStruct;
@Input()
get minDate() {
return this._minDate;
}
set minDate(minDate: NgbDateStruct) {
this._minDate = minDate;
}
/**
* Max date for the navigation. If not provided will be 10 years from today or `startDate`
*/
_maxDate: NgbDateStruct;
@Input()
get maxDate() {
return this._maxDate;
}
set maxDate(maxDate: NgbDateStruct) {
this._maxDate = maxDate;
}
/**
* Navigation type: `select` (default with select boxes for month and year), `arrows`
* (without select boxes, only navigation arrows) or `none` (no navigation at all)
*/
@Input() navigation: "select" | "arrows" | "none";
/**
* The way to display days that don't belong to current month: `visible` (default),
* `hidden` (not displayed) or `collapsed` (not displayed with empty space collapsed)
*/
@Input() outsideDays: "visible" | "collapsed" | "hidden";
/**
* Placement of a datepicker popup. Accepts: "top", "bottom", "left", "right", "bottom-left",
* "bottom-right" etc.
*/
@Input() placement = "bottom-left";
/**
* Whether to display days of the week
*/
@Input() showWeekdays: boolean;
/**
* Whether to display week numbers
*/
@Input() showWeekNumbers: boolean;
/**
* Date to open calendar with.
* With default calendar we use ISO 8601: 'month' is 1=Jan ... 12=Dec.
* If nothing or invalid date provided, calendar will open with current month.
* Use 'navigateTo(date)' as an alternative
*/
@Input() startDate: { year: number; month: number };
@Input() disabledWeekend: boolean;
@Input() holidays: Array<NgbDateStruct>;
@Input() taxDeadlines: Array<NgbDateStruct>;
/**
* input for unifiedVg
*/
@Input() isUnifiedVg: boolean;
private _pattern: any = NbpCalendarPattern;
@Input() nbpLabelPattern: NbpCalendarPattern = this._pattern.GGMMAAAA;
private _separator = NbpDateSeparator;
@Input() nbpDateSeparator: NbpDateSeparator = this._separator.DOT;
/**
* An event fired when navigation happens and currently displayed month changes.
* See NgbDatepickerNavigateEvent for the payload info.
*/
@Output() navigate = new EventEmitter<NgbDatepickerNavigateEvent>();
private _onChange = (_: any) => {};
private _onTouched = () => {};
private _validatorChange = () => {};
private _placement: any = NbpCalendarPosition;
private positionService: Positioning;
private get isInModal(): boolean {
let el: HTMLElement = <HTMLElement>this._elRef.nativeElement;
if (!el || !el.parentElement || !el.parentElement.tagName) {
return false;
}
let tagName: string = el.parentElement.tagName;
while (!tagName.match(/modal/i) && !tagName.match(/body/i)) {
el = el.parentElement;
tagName =
el.parentElement && el.parentElement.tagName
? el.parentElement.tagName
: "";
}
return tagName && !!tagName.match(/modal/i);
}
private get isCorporate(): boolean {
return this._cRef.location.nativeElement.classList.contains(
"isp-corporate-mode-wrapper"
);
}
get _isNative(): boolean {
return /(ip(a|o)d|iphone|android)/gi.test(window.navigator.userAgent);
}
constructor(
private _parserFormatter: NgbDateParserFormatter,
private _elRef: ElementRef,
private _vcRef: ViewContainerRef,
private _renderer: Renderer2,
private _cfr: ComponentFactoryResolver,
ngZone: NgZone,
private _service: NgbDatepickerService,
private _calendar: NgbCalendar,
private eventManager: EventManager
) {
this.positionService = new Positioning();
this._zoneSubscription = ngZone.onStable.subscribe(() =>
this.setDatepickerPosition()
);
}
get screenWidth(): number {
return window.innerWidth;
}
setDatepickerPosition() {
if (!this._cRef || !this._elRef) {
return;
}
if (this.screenWidth < this.getCalendarWidth() + 200) {
this.placement = this._placement.BOTTOM_LEFT;
}
const calendar: HTMLElement = this._cRef.location.nativeElement;
const datepickerInput: HTMLElement = this._elRef.nativeElement;
const calendarClone: HTMLElement = <HTMLElement>calendar.cloneNode(true);
this._renderer.removeClass(
calendarClone.querySelector(".isp-main-datepicker"),
"d-none"
);
this._renderer.addClass(calendarClone, "invisible");
window.document.body.appendChild(calendarClone);
const navigation: number = calendarClone.querySelector(
".isp-datepicker-navigation"
)["offsetHeight"];
const routingView: number = calendarClone.querySelector(
".isp-datepicker-routing-view"
)["offsetHeight"];
const position: ClientRect = this.positionService.positionElements(
datepickerInput,
calendarClone,
this.placement
);
this._renderer.removeChild(calendarClone.parentElement, calendarClone);
switch (this.placement) {
case this._placement.TOP:
case this._placement.TOP_RIGHT:
case this._placement.TOP_LEFT:
position.top = this.isCorporate
? -navigation - routingView
: -navigation - routingView - 3;
break;
case this._placement.RIGHT:
case this._placement.LEFT:
position.top = -navigation - routingView / 2;
break;
}
calendar.style.top = `${position.top}px`;
calendar.style.left = `${position.left}px`;
this._renderer.removeClass(
calendar.querySelector(".isp-main-datepicker"),
"d-none"
);
}
registerOnChange(fn: (value: any) => any): void {
this._onChange = fn;
}
registerOnTouched(fn: () => any): void {
this._onTouched = fn;
}
registerOnValidatorChange(fn: () => void): void {
this._validatorChange = fn;
}
setDisabledState(isDisabled: boolean): void {
this._renderer.setProperty(
this._elRef.nativeElement,
"disabled",
isDisabled
);
if (this.isOpen()) {
this._cRef.instance.setDisabledState(isDisabled);
}
}
validate(c: AbstractControl): { [key: string]: any } {
const value = c.value;
if (value === null || value === undefined) {
return null;
}
if (typeof value === "string") {
let newValue: NgbDate;
newValue = new NgbDate(
parseInt(value.substring(0, 4), 10),
parseInt(value.substring(5, 7), 10),
parseInt(value.substring(8, 10), 10)
);
if (!this._calendar.isValid(newValue)) {
return { ngbDate: { invalid: c.value } };
}
if (
this.minDate &&
NgbDate.from(newValue).before(NgbDate.from(this.minDate))
) {
return { ngbDate: { requiredBefore: this.minDate } };
}
if (
this.maxDate &&
NgbDate.from(newValue).after(NgbDate.from(this.maxDate))
) {
return { ngbDate: { requiredAfter: this.maxDate } };
}
} else {
if (!this._calendar.isValid(value)) {
return { ngbDate: { invalid: c.value } };
}
if (
this.minDate &&
NgbDate.from(value).before(NgbDate.from(this.minDate))
) {
return { ngbDate: { requiredBefore: this.minDate } };
}
if (
this.maxDate &&
NgbDate.from(value).after(NgbDate.from(this.maxDate))
) {
return { ngbDate: { requiredAfter: this.maxDate } };
}
}
}
writeValue(value: any) {
const ngbDate = value
? new NgbDate(value.year, value.month, value.day)
: null;
this._model = this._calendar.isValid(value) ? ngbDate : null;
this._writeModelValue(this._model);
}
waitForFormat(value: string, updateView = false) {
this.dataBeforeChange = value;
let actualValue = value;
setTimeout(() => {
if (actualValue === this.dataBeforeChange) {
this.manualDateChange(actualValue, updateView);
}
}, 2000);
}
manualDateChange(value: string, updateView = false) {
let datesplitted = value.split(/[./-]/g);
if (
this.nbpLabelPattern == this._pattern.MMAAAA &&
datesplitted.length < 3 &&
datesplitted.length > 1
) {
value = "01." + value;
}
let [year, month, day] = value.split("-");
if (this.isUnifiedVg && this._isNative) {
if (year && month && day) {
// value = day + '.' + month + '.' + year;
}
}
this._model = this._service.toValidDate(
this._parserFormatter.parse(value, this.nbpLabelPattern),
null
);
this._onChange(
this._model ? this._model.toStruct() : value === "" ? null : value
);
if (updateView && this._model) {
this._writeModelValue(this._model);
}
}
isOpen() {
return !!this._cRef;
}
/**
* Opens the datepicker with the selected date indicated by the ngModel value.
*/
open(mode: boolean, fromkeyboard: boolean) {
if (!this.isOpen()) {
if (this._model && (this.minDate || this.maxDate)) {
if (
(this.minDate &&
NgbDate.from(this._model).before(NgbDate.from(this.minDate))) ||
(this.maxDate &&
NgbDate.from(this._model).after(NgbDate.from(this.maxDate)))
) {
this._model = null;
}
}
const cf = this._cfr.resolveComponentFactory(RplCalendar);
this._cRef = this._vcRef.createComponent(cf);
this._applyPopupStyling(this._cRef.location.nativeElement);
this._cRef.instance.writeValue(this._model);
this._applyDatepickerInputs(this._cRef.instance);
this._subscribeForDatepickerOutputs(this._cRef.instance);
this._cRef.instance.disabledWeekend = this.disabledWeekend;
this._cRef.instance.holidays = this.holidays;
this._cRef.instance.taxDeadlines = this.taxDeadlines;
this._cRef.instance.fromkeyboard = fromkeyboard;
if (mode) {
this._renderer.addClass(
this._cRef.location.nativeElement,
"isp-corporate-mode-wrapper"
);
}
this._cRef.instance.ngOnInit();
// date selection event handling
this._cRef.instance.forceClose.subscribe(() => {
if (this.opened) return;
this.close();
if (this.onDateSelectedCallback)
this.onDateSelectedCallback(this.dataBeforeChange);
});
this._cRef.instance.registerOnChange((selectedDate) => {
this.writeValue(selectedDate);
this._onChange(selectedDate);
if (!this.opened) {
this.close();
}
if (this.onDateSelectedCallback)
this.onDateSelectedCallback(selectedDate);
});
// focus handling
this._cRef.instance.focus();
// Escape Key handling - d100f
// const handleKeyUp = (event) => {
// if (event.key === "Escape") {
// this.close();
// document.removeEventListener("keyup", handleKeyUp);
// }
// };
// document.addEventListener("keyup", handleKeyUp);
}
}
/**
* Closes the datepicker popup.
*/
close() {
if (this.isOpen()) {
this._vcRef.remove(this._vcRef.indexOf(this._cRef.hostView));
this._cRef = null;
this.eventManager.emit("DATEPICKER_CLOSE", true);
}
}
/**
* Toggles the datepicker popup (opens when closed and closes when opened).
*/
toggle(mode: boolean, fromkeyboard?: boolean) {
if (this.isOpen()) {
this.close();
} else {
this.open(mode, fromkeyboard);
}
}
addMargin(value: string) {
if (this._cRef) {
this._renderer.setStyle(
this._cRef.location.nativeElement,
"margin-top",
value
);
}
}
onFocusOut($event) {
const parent: HTMLElement = this._elRef.nativeElement.parentElement;
const icon: HTMLElement = parent.querySelector("i");
if (
this.isOpen() &&
!(
event.target === icon ||
this._elRef.nativeElement.contains($event.target) ||
this._cRef.location.nativeElement.contains($event.target)
)
) {
this._cRef.instance.focusOutComponent($event);
console.info("onfocusout close");
this.close();
if (this.eventManager) {
this.eventManager.emit("HANDLER_CALENDAR", {});
}
}
}
/**
* Navigates current view to provided date.
* With default calendar we use ISO 8601: 'month' is 1=Jan ... 12=Dec.
* If nothing or invalid date provided calendar will open current month.
* Use 'startDate' input as an alternative
*/
navigateTo(date?: { year: number; month: number }) {
if (this.isOpen()) {
this._cRef.instance.navigateTo(date);
}
}
onBlur() {
this._onTouched();
}
ngOnChanges(changes: SimpleChanges) {
if (changes["minDate"] || changes["maxDate"]) {
this._validatorChange();
}
}
ngOnDestroy() {
this.close();
this._zoneSubscription.unsubscribe();
}
getCalendarHeight() {
if (this._cRef && this._cRef.instance.datepickerRoutingView) {
return this._cRef.instance.datepickerRoutingView.getRoutingViewHeight();
}
return 0;
}
getCalendarWidth() {
if (this._cRef && this._cRef.instance.datepickerRoutingView) {
return this._cRef.instance.datepickerRoutingView.getRoutingViewWidth();
}
return 0;
}
getInputHeight() {
if (this._elRef) {
return this._elRef.nativeElement.offsetHeight;
}
return 0;
}
private _applyDatepickerInputs(datepickerInstance: RplCalendar): void {
[
"dayTemplate",
"displayMonths",
"firstDayOfWeek",
"markDisabled",
"minDate",
"maxDate",
"navigation",
"outsideDays",
"showNavigation",
"showWeekdays",
"showWeekNumbers",
].forEach((optionName: string) => {
if ((this as any)[optionName] !== undefined) {
(datepickerInstance as any)[optionName] = (this as any)[optionName];
}
});
datepickerInstance.startDate = this.startDate || this._model;
}
private _applyPopupStyling(nativeElement: any) {
this._renderer.addClass(nativeElement, "dropdown-menu");
this._renderer.setStyle(nativeElement, "padding", "0");
}
private _subscribeForDatepickerOutputs(datepickerInstance: RplCalendar) {
datepickerInstance.navigate.subscribe((date: any) =>
this.navigate.emit(date)
);
}
private _writeModelValue(model: NgbDate) {
if (model) {
const { day, month, year } = model;
if (this.nbpLabelPattern == this._pattern.MMAAAA) {
this._renderer.setProperty(
this._elRef.nativeElement,
"value",
this._parserFormatter.format(
{ year, month, day: 0 },
this.nbpLabelPattern,
this.nbpDateSeparator
)
);
} else {
this._renderer.setProperty(
this._elRef.nativeElement,
"value",
this._parserFormatter.format(
{ year, month, day },
this.nbpLabelPattern,
this.nbpDateSeparator
)
);
}
} else {
this._renderer.setProperty(
this._elRef.nativeElement,
"value",
this._parserFormatter.format(
model,
this.nbpLabelPattern,
this.nbpDateSeparator
)
);
}
if (this.isOpen()) {
this._cRef.instance.writeValue(model);
this._onTouched();
}
}
}

View File

@ -0,0 +1,118 @@
<div class="isp-datepicker-routing-view" #ispDatepickerRoutingView (keydown.tab)="onKeyDownTab()">
<div [ngSwitch]="currentTemplate">
<!-- giorni -->
<div *ngSwitchCase=0>
<!-- mesi nell'header. -->
<div *ngIf="showWeekdays" class="ngb-dp-week d-flex" role="row" [attr.aria-hidden]="true">
<div *ngIf="showWeekNumbers" class="ngb-dp-weekday"></div>
<div *ngFor="let w of month.weekdays" class="ngb-dp-weekday small text-center text-info font-italic" [attr.aria-hidden]="true">
<span [attr.role]="'columnheader'" [attr.aria-labelledby]="''">
{{ i18n.getWeekdayShortName(w) | translate | uppercase | slice: 0:3 }}
</span>
</div>
</div>
<ng-template ngFor let-week [ngForOf]="month.weeks">
<div *ngIf="!isCollapsed(week) && !isHiddenWeek(week)" class="ngb-dp-week d-flex" role="row">
<div *ngIf="showWeekNumbers" class="ngb-dp-week-number small text-center font-italic text-muted">
<span [attr.role]="'columnheader'" [attr.aria-label]="''">{{ week.number }}</span>
</div>
<div *ngFor="let day of week.days" (click)="doSelect(day, $event)" class="ngb-dp-day"
[class.disabled]="day.context.disabled"
[class.hidden]="isHidden(day)"
[class.tab-focused]="day.context.focused && tabFocusVisible"
[attr.aria-label]="''">
<ng-template [ngIf]="!isHidden(day)">
<div ngbDatepickerDayView
[ngClass] = "{'cursor-pointer' : !disabledWeekend && !day.context.disabled}"
[date]="day.context.date"
[currentMonth]="day.context.currentMonth"
[selected]="day.context.selected"
[disabled]="day.context.disabled"
[focused]="day.context.focused"
[startDateEnabled]="startDateEnabled"
[endDateEnabled]="endDateEnabled"
[isToday]="day.context.isToday"
[isWeekend]="day.context.isWeekend"
[isHoliday]="day.context.isHoliday"
[taxDeadlines]="taxDeadlines"
[isFiscalDay]="day.context.isFiscalDay"
[attr.role]="'cell'"
[attr.aria-selected]="day.context.selected"
[attr.tabindex]="isActiveCell(day)"
[labelText]="i18n.getAriaLabelDaysTabularForm(day)"
[attr.aria-label]="i18n.getAriaLabelDays(day)"
[attr.aria-labelledby]="''"
[attr.aria-describedby]="''">
</div>
</ng-template>
</div>
</div>
</ng-template>
</div>
<!-- mesi -->
<div *ngSwitchCase=1>
<div *ngFor="let line of mesi" class="d-flex ngb-dp-mese" role="row">
<ng-container *ngFor="let mese of line">
<div ngbDatepickerReplyMonthView
[mese]="mese"
[year]="dataTemplate.year"
[selected]="mese.selected"
[disabled]="mese.disabled"
[focused]="mese.focused"
[mounthFocusVisible]="tabFocusVisible"
[startDateEnabled]="startDateEnabled"
[endDateEnabled]="endDateEnabled"
[attr.role]="'cell'"
type='button'
[labelText]="i18n.getAriaLabelMonthTabularForm(mese.name, dataTemplate.year)"
[attr.aria-label]="i18n.getAriaLabelMonth(mese.name, dataTemplate.year)"
[attr.aria-selected]="mese.selected"
[attr.aria-labelledby]="''"
[attr.aria-describedby]="''"
(click)="doSelectMonth(mese, $event)">
</div>
</ng-container>
</div>
</div>
<!-- anni -->
<div *ngSwitchCase=2>
<div *ngFor="let line of years" class="d-flex ngb-dp-mese" role="row">
<ng-container *ngFor="let year of line">
<div ngbDatepickerReplyYearsView [year]="year" [selected]="year.selected" [disabled]="year.disabled"
[focused]="year.focused"
[startDateEnabled]="startDateEnabled"
[endDateEnabled]="endDateEnabled"
[attr.aria-selected]="year.selected"
[attr.role]="'cell'"
type='button'
[attr.aria-label]="i18n.getAriaLabelYear(year.name)"
[attr.aria-labelledby]="''"
[attr.aria-describedby]="''"
[labelText]="i18n.getAriaLabelYearTabularForm(year.name)"
[yearFocusVisible]="tabFocusVisible"
(click)="doSelectYear(year, $event)">
</div>
</ng-container>
</div>
</div>
<!-- default -->
<div *ngSwitchDefault>errore template</div>
</div>
<div>
<button>Oggi</button><button>Cancella</button><button>Chiudi</button>
</div>
</div>

View File

@ -0,0 +1,158 @@
.isp-datepicker-routing-view {
pointer-events: none;
pointer-events: auto;
.d-flex {
display: -webkit-box !important;
display: -ms-flexbox !important;
display: flex !important;
border-bottom-width: 1px;
border-bottom-style: solid;
border-right-width: 1px;
border-right-style: solid;
border-left-width: 1px;
border-left-style: solid;
&:first-child:not(.ngb-dp-mese) {
border-top-width: 1px;
border-top-style: solid;
}
&.ngb-dp-week, &.ngb-dp-mese {
.ngb-dp-day {
width: 2.6875rem;
height: 2.5625rem !important;
cursor: pointer;
position: relative;
box-sizing: border-box;
&.disabled, &.hidden {
cursor: default;
}
&:not(:first-child) {
border-left-width: 1px;
border-left-style: solid;
}
.cursor-pointer {
cursor : pointer !important
}
&[tabindex='0'] {
//pointer-events: none;
&:focus-visible {
box-shadow: 0 0 0 2px #FFFFFF, 0 0 0 4px #FFF599, 0 0 0 6px #000000!important;
border-radius: 4px!important;
border-width: 0px!important;
z-index: 1;
position: relative;
}
}
}
.bg-primary {
&::before {
position: absolute;
top: 0;
right: -0.5rem;
content: '';
display: inline-block;
width: 0;
height: 0;
margin: 0;
padding: 0;
}
}
.btn-secondary {
&:focus {
box-shadow: none;
}
height: inherit;
//font-size: .625rem !important;
}
.btn-secondary, .btn-secondary-month, .btn-secondary-years {
font-weight: 400;
font-size: 0.75rem;
&:focus-visible {
box-shadow: 0 0 0 2px #FFFFFF, 0 0 0 4px #FFF599, 0 0 0 6px #000000!important;
border-radius: 4px!important;
border-width: 0px!important;
z-index: 1;
position: relative;
}
}
div[ngbdatepickerreplymonthview], div[ngbdatepickerreplyyearsview]{
&.btn-secondary-month, &.btn-secondary-years {
border-radius: 0 !important;
box-sizing: border-box;
text-align: center;
min-width: 4.95rem !important;
height: 2.8125rem !important;
line-height: 2.8125rem !important;
vertical-align: middle !important;
border-right-width: 1px;
border-right-style: solid;
border-top-width: 1px;
border-top-style: solid;
border-collapse: collapse;
border-spacing: 0;
&:focus-visible {
box-shadow: 0 0 0 2px #FFFFFF, 0 0 0 4px #FFF599, 0 0 0 6px #000000!important;
border-radius: 4px!important;
border-width: 0px!important;
z-index: 1;
position: relative;
}
// &.active {
// &.focused {
// box-shadow: 0 0 0 2px #FFFFFF, 0 0 0 4px #FFF599, 0 0 0 6px #000000!important;
// border-radius: 4px!important;
// border-width: 0px!important;
// z-index: 1;
// position: relative;
// }
// }
&:last-child {
border-right-style: none;
border-right-width: 0;
}
.ngbdatepickerreplymonthviewdisabled, .ngbDatepickerReplyYearsViewdisabled {
cursor: not-allowed;
opacity: 0.5;
}
.d-flex:first-child & {
border-top-width: 0;
border-top-style: none;
}
}
}
.is-weekend, .is-daypast {
cursor: default;
}
.ngb-dp-weekday, .ngb-dp-week-number {
width: 14.28% !important;
height: 2.375rem !important;
line-height: 2.4375rem;
&.small, & small {
font-size: 80%;
font-weight: 400;
}
&.text-center {
text-align: center !important;
}
&.font-italic {
font-family: 'Arial Bold', 'Arial';
font-weight: 700;
font-style: normal !important;
font-size: .875rem;
text-align: center;
text-transform: uppercase;
}
}
}
}
}
// .tab-focused {
// .active {
// box-shadow: 0 0 0 2px #FFFFFF, 0 0 0 4px #FFF599, 0 0 0 6px #000000!important;
// border-radius: 4px!important;
// border-width: 0px!important;
// z-index: 1;
// position: relative;
// }
// }

View File

@ -0,0 +1,444 @@
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ElementRef,
EventEmitter,
HostListener,
Input,
OnChanges,
OnDestroy,
OnInit,
Output,
SimpleChanges,
TemplateRef,
ViewChild,
} from "@angular/core";
import {
CalendarItem,
DayTemplateContext,
DayViewModel,
MonthViewModel,
NgbDataTemplateStruct,
NgbDate,
NgbDatepickerI18n,
NgbDatepickerService,
WeekViewModel,
} from "@isp/xdce-widget";
import { Subscription } from "rxjs";
@Component({
selector: "ngb-fid-datepicker-routing-view",
host: { class: "d-block" },
templateUrl: "./datepicker-routing-view.html",
styleUrls: ["./datepicker-routing-view.scss"],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class NgbDatepickerRoutingView implements OnInit, OnChanges, OnDestroy {
@Input() dayTemplate: TemplateRef<DayTemplateContext>;
@Input() monthTemplate: TemplateRef<DayTemplateContext>;
@Input() yearsTemplate: TemplateRef<DayTemplateContext>;
@Input() currentTemplate: number;
@Input() mesi: any;
@Input() years: any;
@Input() disabledWeekend: boolean;
@Input() date: any;
@Input() dataTemplate: NgbDataTemplateStruct;
@Input() month: MonthViewModel;
@Input() outsideDays: "visible" | "hidden" | "collapsed";
@Input() showWeekdays;
@Input() showWeekNumbers;
@Input() startDateEnabled: any;
@Input() endDateEnabled: any;
@Input() isToday: boolean;
@Input() isWeekend: boolean;
@Input() taxDeadlines: any;
@Output() select = new EventEmitter<NgbDate>();
@Output() forceClose = new EventEmitter();
@Output() changeTemplate = new EventEmitter<NgbDataTemplateStruct>();
@Output() updateYears = new EventEmitter<number>();
@ViewChild("ispDatepickerRoutingView") routingView: ElementRef;
currentYear: number;
currentMonth: number;
currentDay: number;
sub: Subscription;
tabFocusVisible: boolean;
shiftTabFromDayActive: boolean = false;
constructor(
public i18n: NgbDatepickerI18n,
private cdr: ChangeDetectorRef,
private service: NgbDatepickerService,
private _elementRef: ElementRef
) {}
ngOnInit() {
// alert("in select in routing : " + this.startDateEnabled)
// alert("in select in routing : " + this.endDateEnabled)
// this.currentYear = this.date && this.date.year;
// this.currentMonth = this.date && this.date.month;
console.info("routing init", this.currentYear, this.currentMonth);
this.service.isDayFocusView.subscribe((isDayFocusView) => {
this.tabFocusVisible = isDayFocusView;
});
this.dataTemplate.day = this.date && this.date.day;
this.dataTemplate.month = this.date && this.date.month;
this.dataTemplate.year = this.date && this.date.year;
const model = this.service._model$.getValue();
if (model && model.selectedDate) {
this.currentDay = model.selectedDate.day;
this.currentMonth = model.selectedDate.month;
this.currentYear = model.selectedDate.year;
this.selectedDay = model.selectedDate.day;
}
this.sub = this.service.model$.subscribe((modelDate) => {
if (modelDate.focusVisible) {
if (modelDate && modelDate.focusDate) {
this.currentDay = modelDate.focusDate.day;
this.currentMonth = modelDate.focusDate.month;
this.currentYear = modelDate.focusDate.year;
if (model && model.selectedDate)
this.selectedDay = model.selectedDate.day;
}
this.cdr.detectChanges();
}
this.setFocusDate();
});
this.service["subscribeIsDayFocusView"]().subscribe((tabFocusVisible) => {
this.tabFocusVisible = tabFocusVisible;
if (tabFocusVisible) {
this.shiftTabFromDayActive = false;
this.service.focusVisible = tabFocusVisible;
this.setFocusDate();
}
this.cdr.detectChanges();
});
}
private setFocusDate() {
let domElement = this._elementRef.nativeElement;
if (this.currentTemplate == 0 && this.tabFocusVisible) {
setTimeout(() => {
const elementToFocus = domElement.querySelector(
"div.ngb-dp-day > .active"
);
if (!!elementToFocus) elementToFocus.focus();
this.cdr.detectChanges();
}, 0);
}
if (this.currentTemplate == 1 && this.tabFocusVisible) {
setTimeout(() => {
const elementToFocus = domElement.querySelector(
"div.btn-secondary-month.active"
);
if (!!elementToFocus) elementToFocus.focus();
this.cdr.detectChanges();
}, 50);
}
if (this.currentTemplate == 2 && this.tabFocusVisible) {
setTimeout(() => {
const elementToFocus = domElement.querySelector(
"div.btn-secondary-years.active"
);
if (!!elementToFocus) elementToFocus.focus();
this.cdr.detectChanges();
}, 50);
}
}
isActiveCell(day) {
if (this.tabFocusVisible) {
if (!!day.context.focused && day.context.focused) {
return 0;
} else if (
this.service._model$.getValue().selectedDate &&
day.context.selected
) {
//focus all'apertura
//caso del giorno preselezionato
return 0;
} else if (
!this.service._model$.getValue().selectedDate &&
day.context.date.day == this.getToday().day &&
day.context.date.month == this.getToday().month
) {
//focus all'apertura
//quando non è preselezionato nessun giorno il focus parte dal giorno corrente
return 0;
} else {
return -1;
}
} else {
if (this.shiftTabFromDayActive) {
//focus all'apertura
//caso del giorno preselezionato
if (
this.service._model$.getValue().selectedDate &&
day.context.selected
) {
return 0;
//quando non è preselezionato nessun giorno il focus parte dal giorno corrente
} else if (
!this.service._model$.getValue().selectedDate &&
day.context.date.day == this.getToday().day &&
day.context.date.month == this.getToday().month
) {
return 0;
} else {
return -1;
}
} else {
return -1;
}
}
}
onKeyDownTab() {
//console.info("onKeyDownTab datepicker routing view")
this.service.isTabClickedFromDay.next(true);
this.service.emitIsDayFocusView(false);
}
getToday(): NgbDate {
return new NgbDate(
new Date().getFullYear(),
new Date().getMonth() + 1,
new Date().getDate()
);
}
ngOnDestroy(): void {
if (this.sub) {
this.sub.unsubscribe();
}
}
@HostListener("keydown.shift.tab", ["$event"])
onKeyDown(e) {
this.service.emitIsDayFocusView(false);
this.shiftTabFromDayActive = true;
}
selectedDay: number = -1;
ngOnChanges(changes: SimpleChanges) {
console.info(
"routing ngOnChanges",
this.currentYear,
this.currentMonth,
this.currentDay
);
if (changes.years) {
this.years = [...changes.years.currentValue];
}
if (changes.currentTemplate || changes.dataTemplate) {
//this.service.isDayFocusView.next(false);
this.service.emitTemplate(this.currentTemplate);
this.resetMesi();
this.resetAnni();
const model = this.service._model$.getValue();
if (model && model.focusDate && model.firstDate) {
//model.focusDate.month = model.firstDate.month;
//model.focusDate.year = model.firstDate.year;
//this.service._model$.next(model);
}
if (model && model.selectedDate) {
this.currentDay = model.selectedDate.day;
this.currentMonth = model.selectedDate.month;
this.currentYear = model.selectedDate.year;
}
}
if (changes["date"] && changes["date"].currentValue) {
//l'anno in focus non è compreso nel range della maschera => riscostrisco la maschera
//se il primo anno della maschera è superiore all'anno selezionato
if (this.years[0][0].number > this.date.year) {
this.updateYears.emit(this.years[0][0].number - 12);
//se l'ultimo anno della maschera è minore dell'anno selezionato
} else if (this.date.year > this.years[2][3].number) {
this.updateYears.emit(this.years[2][3].number + 1);
}
}
this.cdr.detectChanges();
}
doSelect(day: DayViewModel, $event: any) {
if (!this.abilitaGiorni(day.date)) {
return;
}
setTimeout(() => this.forceClose.emit(), 0);
if (this.dataTemplate.valid) {
// il day si prende quello selezionato e non quello del dataTemplate
// day.date.day = this.dataTemplate.day;
day.date.month = this.dataTemplate.month;
day.date.year = this.dataTemplate.year;
this.currentYear = day.date.year;
this.currentMonth = day.date.month;
this.currentDay = day.date.day;
this.select.emit(NgbDate.from(day.date));
} else {
if (!day.context.disabled && !this.isHidden(day)) {
this.currentYear = day.date.year;
this.currentMonth = day.date.month;
this.currentDay = day.date.day;
this.select.emit(NgbDate.from(day.date));
}
}
$event.stopPropagation();
}
abilitaGiorni(data) {
let buffer = new Date(data.year, data.month - 1, data.day);
let startDate = new Date(
this.startDateEnabled.year,
this.startDateEnabled.month - 1,
this.startDateEnabled.day
);
let endDate = new Date(
this.endDateEnabled.year,
this.endDateEnabled.month - 1,
this.endDateEnabled.day
);
return startDate <= buffer && buffer <= endDate;
}
abilitaMesi(data) {
return (
((this.startDateEnabled.year == this.dataTemplate.year &&
this.startDateEnabled.month <= data.number) ||
(data.number < this.startDateEnabled.month &&
this.startDateEnabled.year < this.dataTemplate.year) ||
(this.startDateEnabled.month <= data.number &&
this.startDateEnabled.year <= this.dataTemplate.year)) &&
((data.number <= this.endDateEnabled.month &&
this.dataTemplate.year <= this.endDateEnabled.year) ||
(data.number > this.endDateEnabled.month &&
this.dataTemplate.year < this.endDateEnabled.year))
);
}
abilitaAnni(data) {
return (
this.startDateEnabled.year <= data.number &&
data.number <= this.endDateEnabled.year
);
}
doSelectMonth(mese: any, $event: any) {
console.info("doSelectMonth", $event);
if (!this.abilitaMesi(mese)) {
return;
}
this.currentTemplate = 0;
this.dataTemplate.template = this.currentTemplate;
// reset giorni
this.month.weeks.forEach((week) => {
week.days.forEach((day) => {
day.context.selected =
day.date.day === this.currentDay &&
day.date.month === this.currentMonth &&
day.date.year === this.currentYear;
day.context.focused =
day.date.day === this.currentDay &&
day.date.month === this.currentMonth &&
day.date.year === this.currentYear;
});
});
this.resetMesi();
this.dataTemplate.month = mese.number;
this.dataTemplate.valid = true;
this.changeTemplate.emit(this.dataTemplate);
$event.stopPropagation();
}
doSelectYear(year: any, $event: any) {
if (!this.abilitaAnni(year)) {
return;
}
this.currentTemplate = 1;
this.dataTemplate.template = this.currentTemplate;
// resetta mesi e anno
this.resetMesi();
this.dataTemplate.year = year.number;
this.dataTemplate.valid = true;
this.changeTemplate.emit(this.dataTemplate);
$event.stopPropagation();
}
isCollapsed(week: WeekViewModel) {
return (
this.outsideDays === "collapsed" &&
week.days[0].date.month !== this.month.number &&
week.days[week.days.length - 1].date.month !== this.month.number
);
}
isHiddenWeek(week: WeekViewModel) {
let counter = 0;
for (let i = 0; i < week.days.length; i++) {
if (this.isHidden(week.days[i])) {
counter++;
}
}
return counter === 7;
}
isHidden(day: DayViewModel) {
return (
this.outsideDays === "hidden" && this.month.number !== day.date.month
);
}
getRoutingViewHeight() {
return this.routingView.nativeElement.offsetHeight;
}
getRoutingViewWidth() {
return this.routingView.nativeElement.offsetWidth;
}
private resetMesi() {
let months: CalendarItem[][] = [];
months = this.mesi.map((row) => {
return row.map((m) => {
const res = { ...m };
res.selected =
res.number === this.currentMonth &&
this.dataTemplate.year === this.currentYear;
res.focused =
res.number === this.currentMonth &&
this.dataTemplate.year === this.currentYear;
return res;
});
});
this.mesi = months;
}
private resetAnni() {
let yrs: CalendarItem[][] = [];
yrs = this.years.map((row) => {
return row.map((y) => {
const res = { ...y };
res.selected = res.number === this.currentYear;
res.focused = res.number === this.currentYear;
return res;
});
});
this.years = yrs;
}
}

View File

@ -0,0 +1,81 @@
<!-- intestazione -->
<div class="isp-main-datepicker d-none" role="dialog" aria-modal="true">
<div class="ngb-dp-header bg-faded pt-1 rounded-top" [style.height.rem]="getHeaderHeight()"
[style.marginBottom.rem]="-getHeaderMargin()">
<!-- componente per la navigazione! Seleziona il template -->
<ngb-datepicker-navigation *ngIf="navigation !== 'none'"
[date]="model.firstDate"
[minDate]="model.minDate"
[maxDate]="model.maxDate"
[months]="model.months.length"
[years]="years"
[template]="template"
[disabled]="model.disabled"
[showWeekNumbers]="showWeekNumbers"
[showSelect]="navigation === 'select'"
[disabledWeekend]="model.disabledWeekend"
[holidays]="model.holidays"
[taxDeadlines]="model.taxDeadlines"
(navigate)="onNavigateEvent($event)"
(select)="onNavigateDateSelect($event)"
(newTemplate)="setNewTemplate($event);$event.event.stopPropagation();"
[attr.label]="''"
[attr.tabindex]="-1"
[dataTemplate]="dataTemplate"
[attr.labelledby]="''"
[attr.describedby]="''">
</ngb-datepicker-navigation>
</div>
<!-- corpo componente -->
<div class="ngb-dp-months d-flex px-1 pb-1">
<ng-template ngFor let-month [ngForOf]="model.months" let-i="index">
<div class="ngb-dp-month d-block ml-3">
<!-- <div *ngIf="navigation !== 'select' || displayMonths > 1" style="min-width:150px"
class="ngb-dp-month-name text-center" (click)="setNewTemplate((template+1)%3);$event.stopPropagation();" aria-label="" [attr.role]=""> -->
<!-- <div [ngSwitch]="template" style="margin-top:1px" class="header-title">
<div role="heading" aria-level="2" *ngSwitchCase=0 [attr.aria-label]="i18n.getAriaLabel(dataTemplate)" id="id-grid-label" [attr.aria-live]="'polite'">
{{ i18n.getMonthFullName(dataTemplate.month) | translate | uppercase }} {{ dataTemplate.year }}
</div>
<div role="heading" aria-level="2" *ngSwitchCase=1 [attr.aria-label]="dataTemplate.year" id="id-grid-label" [attr.aria-live]="'polite'">
{{ dataTemplate.year }}
</div>
<div role="heading" aria-level="2" *ngSwitchCase=2 [attr.aria-label]="this.years[0][0].number+' - '+this.years[2][3].number" id="id-grid-label" [attr.aria-live]="'polite'">
{{ this.years[0][0].number }} - {{ this.years[2][3].number }}
</div>
</div> -->
<!-- </div> -->
<!-- componente routing che usa il template selezionato-->
<ngb-fid-datepicker-routing-view
[mesi]="mesi"
[years]="years"
[disabledWeekend]="disabledWeekend"
[dataTemplate]="dataTemplate"
[date]="model.firstDate"
[currentTemplate]="template"
[month]="month"
[showWeekdays]="showWeekdays"
[showWeekNumbers]="showWeekNumbers"
[startDateEnabled]="startDateEnabled"
[endDateEnabled]="endDateEnabled"
[outsideDays]="(displayMonths === 1 ? outsideDays : 'hidden')"
[taxDeadlines]="taxDeadlines"
(select)="onDateSelect($event)"
(forceClose)="emitForceClose()"
(updateYears)="updateYears($event)"
(changeTemplate)="onChangeTemplate($event)"
[attr.label]="''"
[attr.aria-label]="''"
[attr.aria-live]="polite"
[attr.role]="'table'"
[attr.labelledby]="'id-grid-label'">
</ngb-fid-datepicker-routing-view>
</div>
</ng-template>
</div>
</div>

View File

@ -0,0 +1,254 @@
:host(.isp-corporate-mode-wrapper) {
&.dropdown-menu {
margin-top: 0;
}
.isp-main-datepicker{
.ngb-dp-header {
height: 2.1875rem!important;
margin-bottom: 0 !important;
& ::ng-deep .isp-datepicker-navigation {
height: 2.1875rem !important;
border-top-left-radius: 2px;
border-top-right-radius: 2px;
span {
button.btn-link {
width: 2.1875rem;
height: 2.1875rem;
font-size: 0.9375rem;
&:disabled {
opacity: 1;
cursor: default;
.ispv2-font-chevron-left {
opacity: 0.35 !important;
}
.ispv2-font-chevron-right {
opacity: 0.35 !important;
}
}
}
}
}
}
.ngb-dp-months {
.ngb-dp-month {
.ngb-dp-month-name {
height: 2.1875rem !important;
margin-top: -2.188rem !important;
top: auto;
line-height: 0.875rem !important;
font-size: 0.75rem !important;
text-decoration: underline;
.header-title {
pointer-events: auto;
padding: 3% 15%;
&:active {
scale: 0.95;
transition: transform 0.15s ease-in-out 0s;
}
}
}
& ::ng-deep .isp-datepicker-routing-view {
.d-flex {
&:last-child{
border-bottom-width: 1px;
border-bottom-style: solid;
border-bottom-left-radius: 1px;
border-bottom-right-radius: 1px;
}
&.ngb-dp-mese:first-child {
border-top-width: 1px;
border-top-style: solid;
}
&.ngb-dp-week, &.ngb-dp-mese {
.ngb-dp-week-number {
height: inherit !important;
line-height: inherit;
width: 2.125rem !important;
font-size: 0.75rem;
font-weight: 700;
}
.ngb-dp-weekday {
height: inherit !important;
line-height: 1.875rem;
width: 2.25rem !important;
font-size: 0.625rem;
}
.ngb-dp-day {
width: 2.25rem !important;
height: 2.25rem !important;
font-size: 0.75rem;
.bg-primary, .btn-secondary {
font-size: 0.75rem;
.ngbdatepickerdayview, .ngbdatepickerdayviewdisabled {
line-height: 2.125rem !important;
}
.ngbdatepickerdayview:hover{
text-decoration: underline !important;
opacity: 1;
}
.ngbdatepickerdayview:active {
text-decoration: underline !important;
cursor: pointer;
transform: scale(0.9);
transition: transform 0.15s ease 0s;
opacity: 1;
}
}
.ngbdatepickerreplymonthview {
cursor: pointer;
}
.ngbdatepickerdayview {
}
.ngbdatepickerdayviewdisabled, .ngbdatepickerreplymonthviewdisabled {
cursor: not-allowed;
}
.ngbDatepickerReplyYearsView {
cursor: pointer;
// &:active, &:hover {
// text-decoration: underline!important;
// }
}
.ngbDatepickerReplyYearsView[disabled] {
cursor: default;
}
.ngbDatepickerReplyYearsViewdisabled {
cursor: not-allowed;
opacity: 0.35;
}
.ngbdatepickerdayviewdisabled{
cursor: not-allowed !important;
}
&.disabled.text-muted {
.ngbdatepickerdayviewdisabled {
opacity: .35;
}
}
}
.is-daypast{
.ngbdatepickerdayview {
opacity: .5;
}
}
}
div[ngbdatepickerreplymonthview], div[ngbdatepickerreplyyearsview]{
position: relative;
.ngbdatepickerreplymonthview:active, .ngbdatepickerreplymonthview:hover, .ngbDatepickerReplyYearsView:hover, .ngbDatepickerReplyYearsView:active {
text-decoration: underline!important;
}
&.btn-secondary-month, &.btn-secondary-years {
min-width: 0rem !important;
width: 3.75rem !important;
height: 2.125rem !important;
line-height: 2.125rem !important;
border-top: none;
font-size: 0.75rem;
&.is-current {
border-top-width: 1px;
border-top-style: solid;
&:hover, &:active {
.ngbdatepickerreplymonthview {
height: calc(100% - 1px);
}
}
}
.ngbdatepickerdayview, .ngbdatepickerreplymonthview {
cursor: pointer;
}
.ngbdatepickerdayviewdisabled, .ngbdatepickerreplymonthviewdisabled {
cursor: not-allowed;
opacity: 0.35;
}
.ngbDatepickerReplyYearsView {
cursor: pointer;
}
.ngbDatepickerReplyYearsView[disabled] {
cursor: default;
}
.ngbDatepickerReplyYearsViewdisabled {
cursor: not-allowed;
opacity: 0.35;
}
}
}
}
}
}
}
}
}
.isp-main-datepicker {
.justify-content-between {
-webkit-box-pack: justify !important;
-ms-flex-pack: justify !important;
justify-content: space-between !important;
}
.d-flex {
display: -webkit-box !important;
display: -ms-flexbox !important;
display: flex !important;
height: 3.125rem !important;
line-height: 1.875rem !important;
}
.collapsed {
margin-bottom: -32px;
}
.ngb-dp-header {
height: 4.625rem !important;
margin-bottom: -24px !important;
border-bottom: none !important;
&.pt-1 {
padding-top: 0 !important;
height: 4.25rem;
margin-bottom: -32px;
}
&.rounded-top {
border-radius: 0 !important;
}
}
.ngb-dp-months {
&.pb-1 {
padding: 0 !important;
}
&.px-1 {
padding-left: 0 !important;
padding-right: 0 !important;
}
.ngb-dp-month {
pointer-events: none;
&:first-child {
margin-left: 0 !important;
}
&.ml-3 {
margin-left: 16px;
}
&.d-block {
display: block !important;
}
.ngb-dp-month-name {
font-family: 'Arial', sans-serif;
font-size: 1rem !important;
font-weight: 700;
text-transform: uppercase;
position: absolute;
text-align: center !important;
top: 0;
height: 3.125rem !important;
line-height: 1.42857143rem !important;
word-wrap: break-word;
word-break: break-word;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
display:flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
}
}
}

View File

@ -0,0 +1,867 @@
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ElementRef,
EventEmitter,
forwardRef,
Input,
OnChanges,
OnDestroy,
OnInit,
Output,
SimpleChanges,
TemplateRef,
ViewChild,
} from "@angular/core";
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
import {
DatepickerViewModel,
DayTemplateContext,
EnabledRangeService,
isChangedDate,
NavigationEvent,
NgbCalendar,
NgbDataTemplateStruct,
NgbDate,
NgbDatepickerConfig,
NgbDatepickerI18n,
NgbDatepickerKeyMapService,
NgbDatepickerService,
NgbDateStruct,
} from "@isp/xdce-widget";
import { toInteger } from "@isp/xdce-widget/user-input/isp-typeahead/ng-bootstrap/util";
import { Subscription } from "rxjs";
import { NgbDatepickerRoutingView } from "./datepicker-routing-view";
const NGB_CALENDAR_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => RplCalendar),
multi: true,
};
/**
* The payload of the datepicker navigation event
*/
export interface RplCalendarNavigateEvent {
/**
* Currently displayed month
*/
current: { year: number; month: number };
/**
* Month we're navigating to
*/
next: { year: number; month: number };
}
export class CalendarItem {
name: string;
number: number;
focused: boolean;
disabled: boolean;
selected: boolean;
}
/**
* A lightweight and highly configurable datepicker directive
*/
@Component({
exportAs: "rplCalendar",
selector: "rpl-calendar",
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
class: "d-inline-block rounded",
"[attr.tabindex]": "-1",
"(focus)": "fromkeyboard ? showFocus(true) : showFocus(false)",
"(keydown.arrowdown)": "showFocus(true)",
"(keydown.arrowup)": "showFocus(true)",
"(keydown.arrowleft)": "showFocus(true)",
"(keydown.arrowright)": "showFocus(true)",
"(keydown)": "onKeyDown($event)",
"(keyup.esc)": "close()",
},
templateUrl: './datepicker.html',
styleUrls: ["./datepicker.scss"],
providers: [
NGB_CALENDAR_VALUE_ACCESSOR,
NgbDatepickerService,
NgbDatepickerKeyMapService,
],
})
export class RplCalendar
implements OnDestroy, OnChanges, OnInit, ControlValueAccessor
{
model: DatepickerViewModel;
@ViewChild(forwardRef(() => NgbDatepickerRoutingView))
datepickerRoutingView: NgbDatepickerRoutingView;
@ViewChild(forwardRef(() => NgbDatepickerRoutingView))
datepickerHeader: NgbDatepickerRoutingView;
private _subscription: Subscription;
/**
* Reference for the custom template for the day display
*/
@Input() dayTemplate: TemplateRef<DayTemplateContext>;
/**
* Number of months to display
*/
@Input() displayMonths: number;
/**
* First day of the week. With default calendar we use ISO 8601: 'weekday' is 1=Mon ... 7=Sun
*/
@Input() firstDayOfWeek: number;
/**
* Callback to mark a given date as disabled.
* 'Current' contains the month that will be displayed in the view
*/
@Input() markDisabled: (
date: NgbDateStruct,
current: { year: number; month: number }
) => boolean;
/**
* Min date for the navigation. If not provided will be 10 years before today or `startDate`
*/
_minDate: NgbDateStruct;
@Input()
get minDate() {
return this._minDate;
}
set minDate(minDate: NgbDateStruct) {
this._minDate = minDate;
this.startDateEnabled = minDate;
}
/**
* Max date for the navigation. If not provided will be 10 years from today or `startDate`
*/
_maxDate: NgbDateStruct;
@Input()
get maxDate() {
return this._maxDate;
}
set maxDate(maxDate: NgbDateStruct) {
this._maxDate = maxDate;
this.endDateEnabled = maxDate;
}
/**
* Navigation type: `select` (default with select boxes for month and year), `arrows`
* (without select boxes, only navigation arrows) or `none` (no navigation at all)
*/
@Input() navigation: "select" | "arrows" | "none";
/**
* The way to display days that don't belong to current month: `visible` (default),
* `hidden` (not displayed) or `collapsed` (not displayed with empty space collapsed)
*/
@Input() outsideDays: "visible" | "collapsed" | "hidden";
/**
* Whether to display days of the week
*/
@Input() showWeekdays: boolean;
/**
* Whether to display week numbers
*/
@Input() showWeekNumbers: boolean;
/**
* Date to open calendar with.
* With default calendar we use ISO 8601: 'month' is 1=Jan ... 12=Dec.
* If nothing or invalid date provided, calendar will open with current month.
* Use 'navigateTo(date)' as an alternative
*/
@Input() startDate: { year: number; month: number; day?: number };
@Input() startDateEnabled: any;
@Input() endDateEnabled: any;
@Input() disabledWeekend: boolean;
@Input() holidays: Array<NgbDateStruct>;
@Input() taxDeadlines: Array<NgbDateStruct>;
// /**
// * Start date Enabled
// */
// @Input() startDateEnabled: { year: number, month: number, day: number };
// /**
// * End date Enabled
// */
// @Input() endDateEnabled: { year: number, month: number, day: number };
/**
* In questa variabile sono memorizzati i dati iniziali che scenderanno l'albero dei template
*/
dataTemplate: NgbDataTemplateStruct = {
template: 0,
day: 0,
month: 0,
year: 0,
valid: false,
};
/**
* An event fired when navigation happens and currently displayed month changes.
* See NgbDatepickerNavigateEvent for the payload info.
*/
@Output() navigate = new EventEmitter<NgbDatepickerNavigateEvent>();
@Output() forceClose = new EventEmitter();
/**
* Template da Adoperare
*/
template: number = 0;
/**
* The field indicates that the datepicker was opened from the keyboard(with the enter key or the space key).
* The field is used to display the focus on the pre-selected day or today when the calendar opens by keyboard.
*/
public fromkeyboard: boolean;
/**
* The field indicates that the focus is on the month, year, day cell. If the field is false it means that the focus is positioned on the header of the calendar table
*/
private tabDayFocusVisible: boolean;
mesi: CalendarItem[][] = [
[
{
name: "JAN",
number: 1,
disabled: false,
selected: false,
focused: false,
},
{
name: "FEB",
number: 2,
disabled: false,
selected: false,
focused: false,
},
{
name: "MAR",
number: 3,
disabled: false,
selected: false,
focused: false,
},
{
name: "APR",
number: 4,
disabled: false,
selected: false,
focused: false,
},
],
[
{
name: "MAY",
number: 5,
disabled: false,
selected: false,
focused: false,
},
{
name: "JUN",
number: 6,
disabled: false,
selected: false,
focused: false,
},
{
name: "JUL",
number: 7,
disabled: false,
selected: false,
focused: false,
},
{
name: "AUG",
number: 8,
disabled: false,
selected: false,
focused: false,
},
],
[
{
name: "SEP",
number: 9,
disabled: false,
selected: false,
focused: false,
},
{
name: "OCT",
number: 10,
disabled: false,
selected: false,
focused: false,
},
{
name: "NOV",
number: 11,
disabled: false,
selected: false,
focused: false,
},
{
name: "DEC",
number: 12,
disabled: false,
selected: false,
focused: false,
},
],
];
years: CalendarItem[][] = [
[
{
name: "2018",
number: 2018,
disabled: false,
selected: false,
focused: false,
},
{
name: "2019",
number: 2019,
disabled: false,
selected: false,
focused: false,
},
{
name: "2020",
number: 2020,
disabled: false,
selected: false,
focused: false,
},
{
name: "2021",
number: 2021,
disabled: false,
selected: false,
focused: false,
},
],
[
{
name: "2022",
number: 2022,
disabled: false,
selected: false,
focused: false,
},
{
name: "2023",
number: 2023,
disabled: false,
selected: false,
focused: false,
},
{
name: "2024",
number: 2024,
disabled: false,
selected: false,
focused: false,
},
{
name: "2025",
number: 2025,
disabled: false,
selected: false,
focused: false,
},
],
[
{
name: "2026",
number: 2026,
disabled: false,
selected: false,
focused: false,
},
{
name: "2027",
number: 2027,
disabled: false,
selected: false,
focused: false,
},
{
name: "2028",
number: 2028,
disabled: false,
selected: false,
focused: false,
},
{
name: "2029",
number: 2029,
disabled: false,
selected: false,
focused: false,
},
],
];
onChange = (_: any) => {};
onTouched = () => {};
get _isNative(): boolean {
return /(ip(a|o)d|iphone|android)/gi.test(window.navigator.userAgent);
}
// startDateEnabled: string;
// endDateEnabled: string;
constructor(
private enabledRange: EnabledRangeService,
private _keyMapService: NgbDatepickerKeyMapService,
public _service: NgbDatepickerService,
private _calendar: NgbCalendar,
public i18n: NgbDatepickerI18n,
config: NgbDatepickerConfig,
private _cd: ChangeDetectorRef,
private _elementRef: ElementRef
) {
this.dayTemplate = config.dayTemplate;
this.displayMonths = config.displayMonths;
this.firstDayOfWeek = config.firstDayOfWeek;
this.markDisabled = config.markDisabled;
this.minDate = config.minDate;
this.maxDate = config.maxDate;
this.navigation = config.navigation;
this.showWeekdays = config.showWeekdays;
this.showWeekNumbers = config.showWeekNumbers;
this.startDate = config.startDate;
this.disabledWeekend = config.disabledWeekend;
this.holidays = config.holidays;
this.taxDeadlines = config.taxDeadlines;
this.startDateEnabled = enabledRange.startDate;
this.endDateEnabled = enabledRange.endDate;
// alert("finale Start : " + this.startDateEnabled)
// alert("finale End : " + this.endDateEnabled)
this._subscription = _service.model$.subscribe((model) => {
const newDate = model.firstDate;
const oldDate = this.model ? this.model.firstDate : null;
const newSelectedDate = model.selectedDate;
const oldSelectedDate = this.model ? this.model.selectedDate : null;
this.model = model;
// handling selection change
if (isChangedDate(newSelectedDate, oldSelectedDate)) {
this.onTouched();
this.onChange(
newSelectedDate
? {
year: newSelectedDate.year,
month: newSelectedDate.month,
day: newSelectedDate.day,
}
: null
);
}
// emitting navigation event if the first month changes
if (!newDate.equals(oldDate)) {
this.navigate.emit({
current: oldDate
? { year: oldDate.year, month: oldDate.month }
: null,
next: { year: newDate.year, month: newDate.month },
});
}
_cd.markForCheck();
});
}
abilitaMesi(data) {
if (
this.startDateEnabled.month <= data &&
data <= this.endDateEnabled.month &&
this.startDateEnabled.year <= this.dataTemplate.year &&
this.dataTemplate.year <= this.endDateEnabled.year
) {
return true;
}
return false;
}
abilitaAnni(data) {
if (
this.startDateEnabled.year <= data &&
data <= this.endDateEnabled.year
) {
return true;
}
return false;
}
emitForceClose() {
setTimeout(() => this.forceClose.emit(), 0);
}
setNewTemplate(obj) {
this.setMesi(this.dataTemplate.month, true);
this.updateYears(this.dataTemplate.year);
this.setYear(this.dataTemplate.year, true);
const prevTemplate = this.template;
this.template = obj.template;
this._service.emitTemplate(this.template);
if (prevTemplate === 2 && this.template === 0) {
const model = this._service._model$.getValue();
if (model && model.selectedDate) {
this.navigateTo({
month: model.selectedDate.month,
year: model.selectedDate.year,
});
}
}
obj.event.stopPropagation();
}
setMesi(position: number, selected: boolean) {
if (!this.abilitaMesi(position)) return;
let nRow = 0,
nCol = 0;
if (position == 4) nRow = 0;
else if (position == 8) nRow = 1;
else if (position == 12) nRow = 2;
else nRow = Math.trunc(position / 4);
nCol = position - nRow * 4 - 1;
console.info(
"dataTemplate",
this.dataTemplate,
"mese",
this.mesi[nRow][nCol],
"nRow",
nRow,
"nCol",
nCol
);
this.mesi[nRow][nCol].selected = selected;
this.mesi[nRow][nCol].focused = true;
}
updateYears(startYearValue: number) {
let yrs: CalendarItem[][] = [];
for (let j = 0; j < 3; j++) {
yrs[j] = [];
for (let i = 0; i < 4; i++) {
const yr = new CalendarItem();
yr.number = startYearValue + i + j * 4;
yr.name = yr.number + "";
yr.disabled = false;
yr.focused = false;
yr.selected = false;
yrs[j][i] = yr;
// this.years[j][i].number = startYearValue + i + j * 4
// this.years[j][i].name = this.years[j][i].number + "";
}
}
yrs.forEach((row) => {
row.forEach((y) => {
y.selected = this.dataTemplate.year === y.number;
y.focused = this.dataTemplate.year === y.number;
});
});
this.years = yrs;
}
setYear(yearValue: number, selected: boolean) {
if (!this.abilitaAnni(yearValue)) return;
this.years.forEach((row) => {
row.forEach((year) => {
if (year.number == yearValue) year.selected = selected;
});
});
}
/**
* Manually focus the calendar
*/
focus() {
this._elementRef.nativeElement.focus();
}
getHeaderHeight() {
const h = this.showWeekdays ? 6.25 : 4.25;
return this.displayMonths === 1 || this.navigation !== "select" ? h - 2 : h;
}
getHeaderMargin() {
const m = this.showWeekdays ? 2 : 0;
return this.displayMonths !== 1 || this.navigation !== "select" ? m + 2 : m;
}
/**
* Navigates current view to provided date.
* With default calendar we use ISO 8601: 'month' is 1=Jan ... 12=Dec.
* If nothing or invalid date provided calendar will open current month.
* Use 'startDate' input as an alternative
*/
navigateTo(date?: { year: number; month: number }) {
this._service.open(
date ? new NgbDate(date.year, date.month, 1) : this._calendar.getToday()
);
}
ngOnDestroy() {
this._subscription.unsubscribe();
}
ngOnInit() {
if (this.model === undefined) {
this._service.displayMonths = toInteger(this.displayMonths);
this._service.markDisabled = this.markDisabled;
this._service.firstDayOfWeek = this.firstDayOfWeek;
this._service.disabledWeekend = this.disabledWeekend;
this._service.holidays = this.holidays;
this._service.taxDeadlines = this.taxDeadlines;
this._setDates();
// inixializzazione dataTemplate alla data selezionata
if (!this.startDate || !this.startDate.month || !this.startDate.year) {
this.startDate = { year: null, month: null, day: null };
let today = new Date();
let dd = today.getDate();
let mm = today.getMonth() + 1; //January is 0!
let yyyy = today.getFullYear();
this.startDate.day = dd;
this.startDate.month = mm;
this.startDate.year = yyyy;
}
this.dataTemplate.day = this.startDate.day;
this.dataTemplate.month = this.startDate.month;
this.dataTemplate.year = this.startDate.year;
this.dataTemplate.valid = false;
let elem: HTMLElement = this._elementRef.nativeElement;
elem.classList.contains("isp-corporate-mode-wrapper")
? (this.outsideDays = "collapsed")
: (this.outsideDays = "visible");
}
this._service["subscribeIsDayFocusView"]().subscribe((tabFocusVisible) => {
this.tabDayFocusVisible = tabFocusVisible;
});
this._service.emitTemplate(this.template);
}
ngOnChanges(changes: SimpleChanges) {
if (changes["displayMonths"]) {
this._service.displayMonths = toInteger(this.displayMonths);
}
if (changes["markDisabled"]) {
this._service.markDisabled = this.markDisabled;
}
if (changes["firstDayOfWeek"]) {
this._service.firstDayOfWeek = this.firstDayOfWeek;
}
if (changes["taxDeadlines"]) {
this._service.taxDeadlines = this.taxDeadlines;
}
}
onDateSelect(date: NgbDate) {
this._service.focus(date);
this.writeValue(date);
}
onKeyDown(event: KeyboardEvent) {
// this.template == 0 => days template
// this.template == 1 => months template
// this.template == 2 => years template
// if I click the enter button in the months template I return to the days template
if (
this.template == 1 &&
(event.key == "Enter" || event.key == " ") &&
this.tabDayFocusVisible
) {
let selectedMounth;
this.datepickerRoutingView.mesi.map((row) => {
row.map((mounth) => {
if (mounth.number == this.datepickerRoutingView.currentMonth) {
selectedMounth = mounth;
return mounth;
}
});
});
this.datepickerRoutingView.doSelectMonth(selectedMounth, event);
}
// if I click the enter button in the years template I return to the months template
else if (
this.template == 2 &&
(event.key == "Enter" || event.key == " ") &&
this.tabDayFocusVisible
) {
let selectedYear;
this.datepickerRoutingView.years.map((row) => {
row.map((year) => {
if (year.number == this.datepickerRoutingView.currentYear) {
selectedYear = year;
}
});
});
this.datepickerRoutingView.doSelectYear(selectedYear, event);
} else {
if (this._keyMapService.processKey(event) === true) {
this.emitForceClose();
}
}
}
onNavigateDateSelect(date: NgbDate) {
this._service.open(date);
}
onNavigateEvent(event: NavigationEvent) {
let bufferData: NgbDate;
this.model.firstDate.month = this.dataTemplate.month;
this.model.firstDate.year = this.dataTemplate.year;
if (event == NavigationEvent.PREV && this.template == 0) {
bufferData = this._calendar.getPrev(this.model.firstDate, "m", 1);
this._service.open(bufferData);
this.updateDataTemplate(bufferData);
} else if (NavigationEvent.NEXT && this.template == 0) {
bufferData = this._calendar.getNext(this.model.firstDate, "m", 1);
this._service.open(bufferData);
this.updateDataTemplate(bufferData);
} else if (event == NavigationEvent.PREV && this.template == 1) {
bufferData = this._calendar.getPrev(this.model.firstDate, "m", 12);
this._service.open(bufferData);
this.updateDataTemplate(bufferData);
} else if (event == NavigationEvent.NEXT && this.template == 1) {
bufferData = this._calendar.getNext(this.model.firstDate, "m", 12);
this._service.open(bufferData);
this.updateDataTemplate(bufferData);
} else if (event == NavigationEvent.PREV && this.template == 2) {
bufferData = this._calendar.getPrev(this.model.firstDate, "m", 144);
this._service.open(bufferData);
this.updateDataTemplate(bufferData);
this.updateYears(this.dataTemplate.year);
} else if (event == NavigationEvent.NEXT && this.template == 2) {
bufferData = this._calendar.getNext(this.model.firstDate, "m", 144);
this._service.open(bufferData);
this.updateDataTemplate(bufferData);
this.updateYears(this.dataTemplate.year);
}
}
onChangeTemplate(dataTemplate: NgbDataTemplateStruct) {
this.dataTemplate = dataTemplate;
this.template = dataTemplate.template;
this.navigateTo({ month: dataTemplate.month, year: dataTemplate.year });
}
updateDataTemplate(date: NgbDate) {
const newTemplate = { ...this.dataTemplate };
newTemplate.day = date.day;
newTemplate.month = date.month;
newTemplate.year = date.year;
this.dataTemplate = newTemplate;
this.navigateTo({
month: this.dataTemplate.month,
year: this.dataTemplate.year,
});
}
registerOnChange(fn: (value: any) => any): void {
this.onChange = fn;
}
registerOnTouched(fn: () => any): void {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean) {
this._service.disabled = isDisabled;
}
showFocus(focusVisible: boolean) {
this._service.focusVisible = focusVisible;
}
writeValue(value: any) {
this._service.select(value);
}
private _setDates() {
const startDate = this._service.toValidDate(
this.startDate,
this._calendar.getToday()
);
const minDate = this._service.toValidDate(
this.minDate,
this._calendar.getPrev(startDate, "y", 10)
);
const maxDate = this._service.toValidDate(
this.maxDate,
this._calendar.getPrev(this._calendar.getNext(startDate, "y", 11))
);
this.minDate = {
year: minDate.year,
month: minDate.month,
day: minDate.day,
};
this.maxDate = {
year: maxDate.year,
month: maxDate.month,
day: maxDate.day,
};
this._service.minDate = minDate;
this._service.maxDate = maxDate;
this.navigateTo(startDate);
}
public focusOutComponent(event: any) {
if (!this._elementRef.nativeElement.contains(event.target)) {
let elem: HTMLElement = this._elementRef.nativeElement;
if (elem.parentElement) {
elem.parentElement.removeChild(elem);
}
this._subscription.unsubscribe();
}
}
}
/**
* The payload of the calendar navigation event
*/
export interface NgbDatepickerNavigateEvent {
/**
* Currently displayed month
*/
current: { year: number; month: number };
/**
* Month we're navigating to
*/
next: { year: number; month: number };
}

View File

@ -0,0 +1,111 @@
<div class="isp-calendar-generic" [ngClass]="{ 'isp-default': nbpStyle === _style.DEFAULT || corporateMode,
'isp-primary': nbpStyle === _style.PRIMARY && !corporateMode,
'isp-secondary': nbpStyle === _style.SECONDARY,
'on-dark-background': nbpDarkBackground,
'isp-focused' : (rplCalendar.isOpen() && !opened) || hasFocus,
'isp-highlight': nbpHighlightedDefault,
'opened': opened,
'disabled-background-current-month': isCurrentMonth,
'disabled-background': !isCurrentMonth }" [attr.aria-label]="'CALENDAR'| translate"
[class.enableDefaultView]="enableDefaultViewOnUnifiedVG && unifiedMode"
(keydown.space)="preventScroll($event)"
>
<div class="form-group" [ngClass]="{ 'disabled': disabled,
'tab-focused': tabFocus}">
<div class="input-group">
<input
[ngClass]="{'padding-top-15 d-flex' : unifiedMode, 'calendar-open': rplCalendar.isOpen(),'input-hidden': _nbpOutMode}"
fidRplCalendar
#rplCalendar="fidRplCalendar"
[onDateSelectedCallback]="focusButton()"
[placement]="nbpPlacement"
[nbpLabelPattern]="nbpLabelPattern"
[nbpDateSeparator]="nbpDateSeparator"
[isUnifiedVg]="unifiedMode"
[id]="id"
(click)="nativeClickHandler()"
[name]="name"
[ngModel]="_ngbModel"
[ngModelOptions]="nbpModelOptions"
(ngModelChange)='_ngbModelChanged($event)'
[required]="required"
[disabled]="disabled"
[maxDate]="ngbMaxDate"
[minDate]="ngbMinDate"
(navigate)="_onNavigate($event)"
(blur)="touchExternalInput();"
(touchstart)="handleCalendar($event)"
navigation="arrows"
class="form-control"
[pattern]="pattern"
[placeholder]="placeholder"
[type]="_type"
[disabledWeekend]="_disableWeekend"
[holidays]="_holidays"
[taxDeadlines]="_tax"
[tabindex]="tabindex"
#autoFocusCalendar
[attr.aria-labelledby]="label"
[attr.aria-describedby]="ariaInvalidDate() ? 'error_message'+ id : 'info-text' + id"
[attr.aria-required]="required"
[attr.aria-live]="ariaLive"
[attr.aria-invalid]="ariaInvalidDate() && isNative"
(focus)="onFocusIn()"
(focusout)="onFocusOut()"
(keyup.tab)="_tabFocusOn()"
(keydown.tab)="_tabFocusOff()"
(keyup.shift.tab)="_tabFocusOn()"
(keydown.shift.tab)="_tabFocusOff()"
dateValidator
autocomplete="off"
[attr.aria-label]="ariaLabel"
closeKeyboardOnScroll>
<i class="isp-font-comuni-calendario button-icon"
[ngClass]="{ 'cursor-initial': opened,
'disabled': disabled,
'input-hidden': _nbpOutMode,
'isIt': unifiedMode && isIt }"
#myIconCalendar
*ngIf="!_nbpOutMode && (retailMode || unifiedMode)"
type="'button'"
(ispClick)="handleCalendar($event)"
[attr.aria-hidden]="disabled"
[attr.tabindex]="0"
[attr.aria-live]="'off'"
[attr.role]="'button'"
[attr.aria-label]="'ARIA_CALENDAR_SELECT_DATE_AND_DIALOG'| translate"
(keyup.tab)="_tabFocusOnIcon()"
(keydown.tab)="_tabFocusOffIcon()"
(keydown.space)="manageKeydownSpaceCalendar($event)"
(focusout)="onFocusOutIcon()"
[style.pointerEvents]="enableDefaultViewOnUnifiedVG ? 'all' : null"
>
</i>
<span *ngIf="!_nbpOutMode && unifiedMode" class="calendar-label" aria-hidden="true">{{'CALENDAR' | translate}}</span>
<div class="button-icon button-icon-scale"
#myIconCalendar
*ngIf="!_nbpOutMode && !retailMode && !unifiedMode"
[ngClass]="{ 'cursor-initial': opened,
'disabled': disabled,
'input-hidden': _nbpOutMode}"
type="'button'"
(ispClick)="handleCalendar($event)"
[attr.role]="'button'"
[attr.tabindex]="disabled ? -1 : 0"
[attr.aria-label]="isNative ? 'CALENDAR': 'ARIA_CALENDAR_SELECT_DATE_AND_DIALOG'| translate"
[attr.aria-hidden]="disabled"
[attr.aria-live]="'off'"
(keyup.tab)="_tabFocusOnIcon()"
(keydown.tab)="_tabFocusOffIcon()"
(keydown.space)="manageKeydownSpaceCalendar($event)"
(focusout)="onFocusOutIcon()">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">
<path class="svg-icon"
d="m7,2c.416,0,.75.334.75.75v1.25h4.5v-1.25c0-.416.334-.75.75-.75s.75.334.75.75v1.25h1.25c1.103,0,2,.897,2,2v10c0,1.103-.897,2-2,2H5c-1.103,0-2-.897-2-2V6c0-1.103.897-2,2-2h1.25v-1.25c0-.416.334-.75.75-.75Zm8.5,6H4.5v8c0,.275.225.5.5.5h10c.275,0,.5-.225.5-.5v-8Zm-9,2h3c.275,0,.5.225.5.5v3c0,.275-.225.5-.5.5h-3c-.275,0-.5-.225-.5-.5v-3c0-.275.225-.5.5-.5Z" />
</svg>
</div>
</div>
<span class="output-mode" *ngIf="_nbpOutMode"
[ngClass]="{'output-mode-light': nbpLightMode}">{{setSpanLabel(_ngbModel)}}</span>
</div>
</div>

View File

@ -0,0 +1,570 @@
:host(.isp-corporate-mode-a11y-wrapper) {
.isp-calendar-generic {
//width: 12.65em;
input::-webkit-input-placeholder {
text-overflow: ellipsis !important;
overflow: hidden;
white-space: nowrap;
max-width: 90%;
}
input::-moz-placeholder {
text-overflow: ellipsis !important;
overflow: hidden;
white-space: nowrap;
max-width: 90%;
}
input:-moz-placeholder {
text-overflow: ellipsis !important;
overflow: hidden;
white-space: nowrap;
max-width: 90%;
}
input:-ms-input-placeholder {
text-overflow: ellipsis !important;
overflow: hidden;
white-space: nowrap;
font-size: 0.75rem;
}
input.input-hidden {
display: none !important;
}
.output-mode {
height: 2.1875rem;
padding: 11px 10px 10px 0px;
line-height: 0.875rem;
font-size: .75rem;
}
&>.form-group {
border-width: 0px;
&.tab-focused {
&:not([disabled]) {
box-shadow: 0 0 0 2px #FFFFFF, 0 0 0 4px #FFF599, 0 0 0 6px #000000 !important;
border-radius: 4px;
border-width: 0px !important;
&>.input-group {
input.form-control {
&:focus,
&:active {
border-width: 1px !important;
}
}
}
}
}
&>.input-group {
display: table;
table-layout: fixed;
input.form-control {
font-size: 0.75rem;
border-radius: 2px !important;
height: 2.25rem;
padding: 11px 25px 10px 10px;
background-clip: border-box;
line-height: 0.875rem;
white-space: nowrap;
display: table-cell;
overflow: hidden;
text-overflow: ellipsis;
/*no-shadow*/
//-webkit-box-shadow: none !important;
//box-shadow: none !important;
&:active:not([disabled]),
&:focus:not([disabled]) {
border-width: 1px;
}
&:not([disabled]) {
&.ng-touched.ng-invalid,
&.ng-dirty.ng-invalid,
&.nbp-show-validation.ng-invalid {
border-width: 2px;
&:focus,
&.calendar-open {
border-width: 2px;
}
}
&.calendar-open {
border-width: 1px;
}
}
&[disabled] {
opacity: 0.35;
}
}
}
}
.button-icon {
&.disabled {
opacity: 0.35;
}
&:active {
scale: 0.95;
transition: transform 0.15s ease 0s;
border: none !important;
}
font-size: 1.25rem;
top:50%;
transform: translateY(-50%);
right: 0.375rem;
}
.button-icon-scale {
display: flex;
justify-content: flex-end;
height: 24px;
width: 24px;
}
.svg-icon {
transform: scale(2.2) translate(1.5px, 1px);
}
}
.ng-invalid.ng-dirty.ng-touched & {
&>.form-group {
&>.input-group {
input.form-control {
&:not([disabled]) {
border-width: 2px;
border-style: solid;
&:focus {
border-width: 2px;
border-style: solid;
}
}
}
}
}
}
}
:host(.isp-isybankm-mode-a11y-wrapper),
:host(.isp-unifiedvg-mode-a11y-wrapper) {
.isp-calendar-generic {
.input-hidden {
display: none !important;
}
.output-mode {
font-size: 1.125rem;
line-height: 1.313rem;
padding: 0 15px;
}
&>.form-group {
border-width: 0px;
&>.input-group {
display: table;
table-layout: fixed;
input.form-control {
font-size: 0.75rem;
border-radius: 2px !important;
height: 2.1875rem;
padding: 11px 40px 10px 14px !important;
background-clip: border-box;
line-height: 0.875rem;
vertical-align: middle;
white-space: nowrap;
display: table-cell !important;
&.input-hidden {
display: none !important;
}
overflow: hidden;
text-overflow: ellipsis !important;
/*no-shadow*/
-webkit-box-shadow: none !important;
box-shadow: none !important;
box-shadow: none !important;
padding: 1px 15px;
border-radius: 4px !important;
&:focus:not([disabled]) {
border-width: 2px !important;
}
}
}
}
.button-icon {
top: .2em;
right: .85em;
pointer-events: none;
&.isIt {
margin-right: 5px;
}
}
.calendar-label {
margin-right: 6px;
position: absolute;
top: 2.80em;
right: 0.45em;
z-index: 3;
line-height: 1em;
font-size: 0.75rem;
letter-spacing: 0px;
opacity: 1;
cursor: pointer;
}
}
}
.error_message_visible {
color: #F51500;
}
.isp-calendar-generic {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
input.input-hidden {
display: none !important;
}
&>.form-group {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-flex: 0;
-ms-flex: 0 0 auto;
flex: 0 0 auto;
-ms-flex-flow: row wrap;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
flex-flow: row wrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
margin-bottom: 0;
border-width: 0px !important;
font-size: 1rem;
&.tab-focused {
&:not([disabled]) {
box-shadow: 0 0 0 2px #FFFFFF, 0 0 0 4px #FFF599, 0 0 0 6px #000000 !important;
border-radius: 4px !important;
border-width: 0px !important;
z-index: 1;
position: relative;
&>.input-group {
input.form-control {
&:focus,
&:active {
border-width: 1px !important;
}
}
}
}
}
border-radius: 2px;
margin:0px;
border: solid;
&>.input-group {
position: relative;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
//flex-wrap: nowrap;
width: 100%;
input.form-control {
font-family: sans-serif;
-webkit-appearance: none;
font-size: 100%;
line-height: 2.25rem;
margin: 0;
display: block;
width: 100%;
overflow: visible;
height: 3.125rem;
padding: 11px 40px 10px 10px;
background-image: none;
background-clip: padding-box;
border-radius: 2px !important;
white-space: nowrap;
display: table-cell;
overflow: hidden;
text-overflow: ellipsis !important;
transition: none !important;
border-width: 1px;
border-style: solid;
padding-left: 10px;
-ms-touch-action: manipulation;
touch-action: manipulation;
&::-ms-clear {
display: none;
width: 0;
height: 0;
}
&:focus:not([disabled]),
&:active:not([disabled]) {
border-width: 2px !important;
border-style: solid;
}
&:not([disabled]).calendar-open {
border-width: 2px;
}
&[disabled] {
border-width: 1px;
border-style: solid;
user-select: none;
}
&::-webkit-clear-button {
display: none;
}
&::-webkit-inner-spin-button {
display: none;
}
&::-webkit-calendar-picker-indicator {
&.disabled {
cursor: default;
pointer-events: none;
}
content: '';
background-color: transparent;
color: transparent;
width: 2rem;
height: 80%;
border-width: none;
cursor: pointer;
position: relative;
vertical-align: middle;
right: 0.375rem;
z-index: 5;
font-size: 1rem;
line-height: 1rem;
}
}
& ::ng-deep .dropdown-menu {
border: none;
}
}
}
.output-mode {
height: 2.1875rem;
padding: 8px 10px 10px 10px;
line-height: 0.875rem;
font-size: 1rem;
}
.input-group-addon {
padding: 10px 12px;
margin-bottom: 0;
font-size: 1rem;
font-weight: 400;
line-height: 1.25;
text-align: center;
border-top-style: solid;
border-top-width: 1px;
border-right-style: solid;
border-right-width: 1px;
border-bottom-style: solid;
border-bottom-width: 1px;
border-left-style: none !important;
border-left-width: 0 !important;
&:not(:first-child) {
border-left: 0;
}
img {
width: 1.25rem;
height: 1rem;
cursor: pointer;
}
}
.button-icon {
&.cursor-initial {
cursor: initial !important;
}
&.disabled {
opacity: 0.35;
}
&:focus-visible:not(.disabled) {
box-shadow: 0 0 0 2px #FFFFFF, 0 0 0 4px #FFF599, 0 0 0 6px #000000 !important;
border-radius: 4px !important;
border-width: 0px !important;
z-index: 1;
//position: relative;
}
margin: 0px;
border: solid;
border-width: 0px;
cursor: pointer;
position: absolute;
top: 0.45em;
right: 0.475em;
z-index: 3;
font-size: 1.6em;
line-height: 1em;
&.disabled {
cursor: not-allowed;
pointer-events: none;
}
}
//--- esempio di un template custom -----
//--- le classi successive servono nel caso del template #tpl indicato nel selettore-----
.day {
border-radius: 0 !important;
box-sizing: border-box;
text-align: center;
width: inherit !important;
height: inherit !important;
line-height: 2.6rem !important;
vertical-align: middle;
border-left-width: 1px;
border-left-style: solid;
border-right-width: 1px;
border-right-style: solid;
border-bottom-width: 1px;
border-bottom-style: solid;
border-collapse: separate;
border-spacing: 0;
&:hover {
cursor: pointer;
}
}
.icon {
width: 2rem;
height: 2rem;
}
//--- fine template custom -----
}
//fix jira 565
:host(:not(.isp-corporate-mode-a11y-wrapper)).ng-invalid.ng-dirty.ng-touched {
.isp-calendar-generic {
&>.form-group {
&>.input-group {
input.form-control {
&:not([disabled]) {
border-width: 2px;
border-style: solid;
&:focus {
border-width: 2px;
border-style: solid;
}
}
}
}
}
}
}
:host(:not(.isp-corporate-mode-a11y-wrapper)) {
.isp-calendar-generic {
&>.form-group {
&>.input-group {
input.form-control {
font-size: 1rem;
height: 3.125rem;
:host(:not(.isp-unifiedvg-mode-a11y-wrapper)) {
padding: 6px 10px 6px 10px;
}
}
}
}
}
}
.d-inline-block {
display: inline-block !important;
&.dropdown-menu {
position: absolute;
left: 0;
display: none;
float: left;
min-width: 10rem;
margin: 2px 0 0;
font-size: 1rem;
text-align: left;
list-style: none;
background-clip: padding-box;
padding: 0;
top: 1.5rem;
border-radius: 0 !important;
border: none !important;
&.rounded {
border-radius: 4px;
}
}
}
.padding-top-15 {
padding-top: 15px;
}
.padding-top-15:placeholder-shown {
padding-top: 0px;
}
:host(.isp-retail-mode-a11y-wrapper) {
input[type="date"]::-webkit-inner-spin-button,
input[type="date"]::-webkit-calendar-picker-indicator {
display: none;
-webkit-appearance: none;
}
}

View File

@ -0,0 +1,66 @@
<div class="isp-calendar-generic "
[ngClass]="{ 'isp-default': nbpStyle === _style.DEFAULT,
'isp-primary': nbpStyle === _style.PRIMARY,
'isp-secondary': nbpStyle === _style.SECONDARY,
'on-dark-background': nbpDarkBackground,
'isp-focused' : (rplCalendar.isOpen() && !opened) || hasFocus,
'isp-highlight': nbpHighlightedDefault,
'opened': opened }"
[tabIndex]="0"
[attr.aria-label]="'CALENDARIO'"
[class.enableDefaultView]="enableDefaultViewOnUnifiedVG && unifiedMode">
<div class="form-group">
<div class="input-group">
<input
[ngClass] ="{'padding-top-15 d-flex' : unifiedMode, 'calendar-open': rplCalendar.isOpen(),'input-hidden': _nbpOutMode}"
fidRplCalendarNOA11Y
#rplCalendar="fidRplCalendarNOA11Y"
[placement]="nbpPlacement"
[nbpLabelPattern]="nbpLabelPattern"
[nbpDateSeparator]="nbpDateSeparator"
[isUnifiedVg]="unifiedMode"
[id]="id"
(click)="nativeClickHandler()"
[name]="name"
[ngModel]="_ngbModel"
[ngModelOptions]="nbpModelOptions"
(ngModelChange)='_ngbModelChanged($event)'
[required]="required"
[disabled]="disabled"
[maxDate]="ngbMaxDate"
[minDate]="ngbMinDate"
(navigate)="_onNavigate($event)"
(blur) = "touchExternalInput();"
(touchstart) ="handleCalendar($event)"
navigation="arrows"
class="form-control"
[pattern]="pattern"
[placeholder]="placeholder"
[type]="_type"
[disabledWeekend]="_disableWeekend"
[holidays]="_holidays"
[taxDeadlines]="_tax"
[tabindex]="tabindex"
#autoFocusCalendar
[attr.aria-labelledby]="label"
[attr.aria-describedby]="' '"
[attr.aria-label]="ariaLabel"
(focus)="onFocusIn()"
(focusout)="onFocusOut()"
dateValidator
autocomplete="off"
closeKeyboardOnScroll>
<i class="isp-font-comuni-calendario button-icon"
[ngClass]="{ 'cursor-initial': opened,
'disabled': disabled,
'input-hidden': _nbpOutMode }"
*ngIf="!_nbpOutMode"
(ispClick)="handleCalendar($event)"
[attr.tabindex]="-1"
[attr.aria-hidden]="true"
[style.pointerEvents]="enableDefaultViewOnUnifiedVG ? 'all' : null">
</i>
</div>
<span class="output-mode" *ngIf="_nbpOutMode" [ngClass]="{'output-mode-light': nbpLightMode}">{{setSpanLabel(_ngbModel)}}</span>
</div>
</div>

View File

@ -0,0 +1,368 @@
:host(.isp-corporate-mode-wrapper) {
.isp-calendar-generic {
//width: 12.65em;
input::-webkit-input-placeholder {
text-overflow: ellipsis !important;
overflow: hidden;
white-space: nowrap;
max-width: 90%;
}
input::-moz-placeholder {
text-overflow: ellipsis !important;
overflow: hidden;
white-space: nowrap;
max-width: 90%;
}
input:-moz-placeholder {
text-overflow: ellipsis !important;
overflow: hidden;
white-space: nowrap;
max-width: 90%;
}
input:-ms-input-placeholder {
text-overflow: ellipsis !important;
overflow: hidden;
white-space: nowrap;
font-size: 0.75rem;
}
input.input-hidden {
display: none!important;
}
.output-mode {
height: 2.1875rem;
padding: 0.6875rem 0.625rem 0.625rem 0.625rem;
line-height: 0.875rem;
font-size: .75rem;
}
& > .form-group {
& > .input-group {
input.form-control {
font-size: 0.75rem;
border-radius: 0.125rem !important;
height: 2.1875rem;
padding: 0.6875rem 0.625rem 0.625rem 0.625rem;
background-clip: border-box;
line-height:0.875rem;
/*no-shadow*/
-webkit-box-shadow: none !important;
box-shadow: none !important;
&:not([disabled]) {
&.ng-touched.ng-invalid, &.ng-dirty.ng-invalid, &.nbp-show-validation.ng-invalid {
border-width: 0.0625rem;
&:focus,&.calendar-open {
border-width: 0.0625rem;
}
}
&.calendar-open {
border-width: 0.0625rem;
}
}
&[disabled] {
opacity: 0.5;
}
}
}
}
.button-icon {
&.disabled {
opacity: 0.5;
}
font-size: 1.25rem;
top:50%;
transform: translateY(-50%);
right: 0.625rem;
}
}
.ng-invalid.ng-dirty.ng-touched & {
& > .form-group {
& > .input-group {
input.form-control {
&:not([disabled]) {
border-width: 0.0625rem;
border-style: solid;
&:focus {
border-width: 0.0625rem;
border-style: solid;
}
}
}
}
}
}
}
:host(.isp-unifiedvg-mode-wrapper) {
.isp-calendar-generic {
.input-hidden {
display: none!important;
}
.output-mode {
font-size: 1.125rem;
line-height: 1.313rem;
padding: 0 0.9375rem;
}
& > .form-group {
& > .input-group {
input.form-control {
box-shadow: none!important;
padding: .0625rem .9375rem;
border-radius: .25rem!important;
&:focus:not([disabled]){
border-width: 0.125rem !important;
}
}
}
}
.button-icon {
top: .47em;
right: .60em;
pointer-events: none;
}
}
}
.error_message_visible {
color: #F51500;
}
.isp-calendar-generic {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
& > .form-group {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-flex: 0;
-ms-flex: 0 0 auto;
flex: 0 0 auto;
-ms-flex-flow: row wrap;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
flex-flow: row wrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
margin-bottom: 0;
font-size: 1rem;
& > .input-group {
position: relative;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
//flex-wrap: nowrap;
width: 100%;
input.form-control {
font-family: sans-serif;
-webkit-appearance: none;
font-size: 100%;
line-height: 2.25rem;
margin: 0;
display: block;
width: 100%;
overflow: visible;
height: 3.125rem;
background-image: none;
background-clip: padding-box;
border-radius: .125rem !important;
transition: none !important;
border-width: 0.0625rem;
border-style: solid;
padding-left: .625rem;
-ms-touch-action: manipulation;
touch-action: manipulation;
&::-ms-clear {
display: none;
width: 0;
height: 0;
}
&:focus:not([disabled]), &:active:not([disabled]) {
border-width: 0.0625rem;
border-style: solid;
}
&[disabled] {
border-width: 0.0625rem;
border-style: solid;
user-select: none;
}
&::-webkit-clear-button {
display: none;
}
&::-webkit-inner-spin-button{
display: none;
}
&::-webkit-calendar-picker-indicator{
&.disabled {
cursor: default;
pointer-events: none;
}
content: '';
background-color: transparent;
color: transparent;
width: 2rem;
height: 80%;
border-width: none;
cursor: pointer;
position: relative;
vertical-align: middle;
right: 0.375rem;
z-index: 5;
font-size: 1rem;
line-height: 1rem;
}
}
& ::ng-deep .dropdown-menu {
border: none;
}
}
}
.input-group-addon {
padding: 0.625rem 0.75rem;
margin-bottom: 0;
font-size: 1rem;
font-weight: 400;
line-height: 1.25;
text-align: center;
border-top-style: solid;
border-top-width: 0.0625rem;
border-right-style: solid;
border-right-width: 0.0625rem;
border-bottom-style: solid;
border-bottom-width: 0.0625rem;
border-left-style: none !important;
border-left-width: 0 !important;
&:not(:first-child) {
border-left: 0;
}
img {
width: 1.25rem;
height: 1rem;
cursor: pointer;
}
}
.button-icon {
&.cursor-initial{
cursor: initial !important;
}
&.disabled {
opacity: 0.5;
}
cursor: pointer;
position: absolute;
top: 0.45em;
right: 0.6em;
z-index: 3;
font-size: 1.6em;
line-height: 1em;
&.disabled {
cursor: not-allowed;
pointer-events: none;
}
}
//--- esempio di un template custom -----
//--- le classi successive servono nel caso del template #tpl indicato nel selettore-----
.day {
border-radius: 0 !important;
box-sizing: border-box;
text-align: center;
width: inherit !important;
height: inherit !important;
line-height: 2.6rem !important;
vertical-align: middle;
border-left-width: 1px;
border-left-style: solid;
border-right-width: 0.0625rem;
border-right-style: solid;
border-bottom-width: 0.0625rem;
border-bottom-style: solid;
border-collapse: separate;
border-spacing: 0;
&:hover {
cursor: pointer;
}
}
.icon {
width: 2rem;
height: 2rem;
}
//--- fine template custom -----
}
//fix jira 565
:host(:not(.isp-corporate-mode-wrapper)).ng-invalid.ng-dirty.ng-touched{
.isp-calendar-generic {
& > .form-group {
& > .input-group {
input.form-control {
&:not([disabled]) {
border-width: 0.125rem;
border-style: solid;
&:focus {
border-width: 0.125rem;
border-style: solid;
}
}
}
}
}
}
}
:host(:not(.isp-corporate-mode-wrapper)){
.isp-calendar-generic {
& > .form-group {
& > .input-group {
input.form-control {
font-size: 1rem;
height: 3.125rem;
:host(:not(.isp-unifiedvg-mode-wrapper)) {
padding: 0.375rem 0.75rem 0.375rem 0.625rem;
}
}
}
}
}
}
.d-inline-block {
display: inline-block !important;
&.dropdown-menu {
position: absolute;
left: 0;
display: none;
float: left;
min-width: 10rem;
margin: .125rem 0 0;
font-size: 1rem;
text-align: left;
list-style: none;
background-clip: padding-box;
padding: 0;
top: 1.5rem;
border-radius: 0 !important;
border: none !important;
&.rounded {
border-radius: .25rem;
}
}
}
.padding-top-15 {
padding-top:15px;
}
.padding-top-15:placeholder-shown {
padding-top:0px;
}

View File

@ -0,0 +1,571 @@
import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, EventEmitter, HostBinding, Inject, Injector, Input, Optional, Output, SimpleChanges, Type, forwardRef } from '@angular/core';
import { NG_ASYNC_VALIDATORS, NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms';
import { AsyncValidatorArray, FormTouchService, NbpFormContainerComponent, NbpInputElementBase, NbpInputElementBaseComponentA11YWrapper, NbpStyle, ValidatorArray } from '@isp/xdce-widget/base';
import { APPLICATION_CONTEXT_MANAGER, ApplicationContextManagerInterface, EventManager } from '@isp/xdce-arch-core-base';
import { EnabledRangeService, NbpCalendarGenericComponent, NbpCalendarPattern, NbpDateSeparator, NgbDateStruct } from '@isp/xdce-widget';
import { NbpCalendarGenericComponentA11Y } from './nbp-calendar-generic.component.a11y';
import { NbpCalendarGenericComponentNOA11Y } from './nbp-calendar-generic.component.noa11y';
export const NBP_CALENDAR_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NbpCalendarGenericComponent), // un riferimento al futuro componente corrente
multi: true
};
export const NBP_INPUT_CALENDAR_ELEMENT_BASE: any = {
provide: NbpInputElementBase,
useExisting: forwardRef(() => NbpCalendarGenericComponent), // un riferimento al futuro componente corrente
multi: true
};
@Component({
selector : "nbp-fid-calendar-generic",
template: "<ng-container #componentContainer></ng-container>",
providers: [
NBP_CALENDAR_CONTROL_VALUE_ACCESSOR,
NBP_INPUT_CALENDAR_ELEMENT_BASE,
]
})
export class NbpFidCalendarGeneric extends NbpInputElementBaseComponentA11YWrapper<NbpCalendarGenericComponentA11Y, NbpCalendarGenericComponentNOA11Y, any> implements AfterViewInit {
constructor(enabledRange: EnabledRangeService,
eventManager: EventManager,
@Optional() @Inject(NG_VALIDATORS) validatori: ValidatorArray,
@Optional() @Inject(NG_ASYNC_VALIDATORS) asyncValidatori: AsyncValidatorArray,
@Optional() parentFormContainer: NbpFormContainerComponent,
element: ElementRef,
inj: Injector,
@Optional() formTouchService: FormTouchService,
private changeDetectorRef: ChangeDetectorRef,
@Inject(APPLICATION_CONTEXT_MANAGER) applicationContext: ApplicationContextManagerInterface) {
super(validatori, asyncValidatori, inj);
}
ngAfterViewInit(): void {
this.model.valueChanges.subscribe(() => this.changeDetectorRef.detectChanges());
}
get A11Ycomponent(): Type<NbpCalendarGenericComponentA11Y> {
return NbpCalendarGenericComponentA11Y;
}
get noA11Ycomponent(): Type<NbpCalendarGenericComponentNOA11Y> {
return NbpCalendarGenericComponentNOA11Y;
}
protected modelFromContentChild: boolean = false;
ngOnInit(): void {
super.ngOnInit();
this.model = this.component.model;
}
private _keepDateOnDisabled: boolean = undefined;
@Input()
set keepDateOnDisabled(value: boolean) {
this._keepDateOnDisabled = value;
if (this.component) {
this.component.keepDateOnDisabled = value;
}
}
get keepDateOnDisabled(): boolean {
return this._keepDateOnDisabled;
}
private _nbpModelOptions: {
name?: string,
standalone?: boolean,
updateOn?: 'change'|'blur'|'submit'
} = undefined;
@Input()
set nbpModelOptions(value: {
name?: string,
standalone?: boolean,
updateOn?: 'change'|'blur'|'submit'
}) {
this._nbpModelOptions = value;
if (this.component) {
this.component.nbpModelOptions = value;
}
}
get nbpModelOptions(): {
name?: string,
standalone?: boolean,
updateOn?: 'change'|'blur'|'submit'
} {
return this._nbpModelOptions;
}
private _nbpHighlightedDefault: boolean = undefined;
@Input()
set nbpHighlightedDefault(value: boolean) {
this._nbpHighlightedDefault = value;
if (this.component) {
this.component.nbpHighlightedDefault = value;
}
}
get nbpHighlightedDefault(): boolean {
return this._nbpHighlightedDefault;
}
private _pattern: RegExp = undefined;
@Input()
set pattern(value: RegExp) {
this._pattern = value;
if (this.component) {
this.component.pattern = value;
}
}
get pattern(): RegExp {
return this._pattern;
}
private _name: string = undefined;
@Input()
@HostBinding('attr.name')
set name(value: string) {
this._name = value;
if (this.component) {
this.component.name = value;
}
}
get name(): string {
return this._name;
}
private _nbpDarkBackground: boolean = undefined;
@Input()
set nbpDarkBackground(value: boolean) {
this._nbpDarkBackground = value;
if (this.component) {
this.component.nbpDarkBackground = value;
}
}
get nbpDarkBackground(): boolean {
return this._nbpDarkBackground;
}
private _nbpOutput: boolean = undefined;
@Input()
set nbpOutput(value: boolean) {
this._nbpOutput = value;
if (this.component) {
this.component.nbpOutput = value;
}
}
get nbpOutput(): boolean {
return this._nbpOutput;
}
private _id: string = undefined;
@Input()
set id(value: string) {
this._id = value;
if (this.component) {
this.component.id = value;
}
}
get id(): string {
if(this.component && this._id == undefined){
this._id = this.component.getIdAutonegerato();
}
return this._id;
}
private _nbpShowValidation: boolean= undefined;
@Input()
set nbpShowValidation(value: boolean) {
this._nbpShowValidation = value;
if (this.component) {
this.component.nbpShowValidation = value;
}
}
get nbpShowValidation(): boolean {
return this._nbpShowValidation;
}
private _placeholder: string = undefined;
@Input()
set placeholder(value: string) {
this._placeholder = value;
if (this.component) {
this.component.placeholder = value;
}
}
get placeholder(): string {
return this._placeholder;
}
private _nbpErrorMessage: string = undefined;
@Input()
set nbpErrorMessage(value: string) {
this._nbpErrorMessage = value;
if (this.component) {
this.component.nbpErrorMessage = value;
}
}
get nbpErrorMessage(): string {
return this._nbpErrorMessage;
}
private _showErrorLabel: boolean = undefined;
@Input()
set showErrorLabel(value: boolean) {
this._showErrorLabel = value;
if (this.component) {
this.component.showErrorLabel = value;
}
}
get showErrorLabel(): boolean {
return this._showErrorLabel;
}
private _maxDate: Date = undefined;
@Input()
set maxDate(value: Date) {
this._maxDate = value;
if (this.component) {
this.component.maxDate = value;
}
}
get maxDate(): Date {
return this._maxDate;
}
private _minDate: Date = undefined;
@Input()
set minDate(value: Date) {
this._minDate = value;
if (this.component) {
this.component.minDate = value;
}
}
get minDate(): Date {
return this._minDate;
}
private _startDateEnabled: NgbDateStruct = undefined;
@Input()
set startDateEnabled(value: NgbDateStruct) {
this._startDateEnabled = value;
if (this.component) {
this.component.startDateEnabled = value;
}
}
get startDateEnabled(): NgbDateStruct {
return this._startDateEnabled;
}
private _endDateEnabled: NgbDateStruct = undefined;
@Input()
set endDateEnabled(value: NgbDateStruct) {
this._endDateEnabled = value;
if (this.component) {
this.component.endDateEnabled = value;
}
}
get endDateEnabled(): NgbDateStruct {
return this._endDateEnabled;
}
private _disabled: boolean = undefined;
@Input()
set disabled(value: boolean) {
this._disabled = value;
if (this.component) {
this.component.disabled = value;
}
}
get disabled(): boolean {
return this._disabled;
}
private _required: boolean = undefined;
@Input()
set required(value: boolean) {
this._required = value;
if (this.component) {
this.component.required = value;
}
}
get required(): boolean {
return this._required;
}
private _nbpStyle: NbpStyle = undefined;
@Input()
set nbpStyle(value: NbpStyle) {
this._nbpStyle = value;
if (this.component) {
this.component.nbpStyle = value;
}
}
get nbpStyle(): NbpStyle {
return this._nbpStyle;
}
private __type: string = undefined;
@Input()
set _type(value: string) {
this.__type = value;
if (this.component) {
this.component._type = value;
}
}
get _type(): string {
return this.__type;
}
private _disabledWeekend: boolean = undefined;
@Input()
set disabledWeekend(value: boolean) {
this._disabledWeekend = value;
if (this.component) {
this.component.disabledWeekend = value;
}
}
get disabledWeekend(): boolean {
return this._disabledWeekend;
}
private _holidays: Array<NgbDateStruct> = undefined;
@Input()
set holidays(value: Array<NgbDateStruct>) {
this._holidays = value;
if (this.component) {
this.component.holidays = value;
}
}
get holidays(): Array<NgbDateStruct> {
return this._holidays;
}
private _taxDeadlines: Array<NgbDateStruct> = undefined;
@Input()
set taxDeadlines(value: Array<NgbDateStruct>) {
this._taxDeadlines = value;
if (this.component) {
this.component.taxDeadlines = value;
}
}
get taxDeadlines(): Array<NgbDateStruct> {
return this._taxDeadlines;
}
private _firstFocus: boolean = undefined;
@Input()
set firstFocus(value: boolean) {
this._firstFocus = value;
if (this.component) {
this.component.firstFocus = value;
}
}
get firstFocus(): boolean {
return this._firstFocus;
}
private _focusOn: boolean = undefined;
@Input()
set focusOn(value: boolean) {
this._focusOn = value;
if (this.component) {
this.component.focusOn = value;
}
}
get focusOn(): boolean {
return this._focusOn;
}
private _tabindex: undefined = undefined;
@Input()
set tabindex(value: undefined) {
this._tabindex = value;
if (this.component) {
this.component.tabindex = value;
}
}
get tabindex(): undefined {
return this._tabindex;
}
private _label: string = undefined;
@Input()
set label(value: string) {
this._label = value;
if (this.component) {
this.component.label = value;
}
}
get label(): string {
return this._label;
}
private _ariaLabel: string = undefined;
@Input()
set ariaLabel(value: string) {
this._ariaLabel = value;
if (this.component) {
this.component.ariaLabel = value;
}
}
get ariaLabel(): string {
return this._ariaLabel;
}
private _nbpLightMode: boolean = undefined;
@Input()
set nbpLightMode(value: boolean) {
this._nbpLightMode = value;
if (this.component) {
this.component.nbpLightMode = value;
}
}
get nbpLightMode(): boolean {
return this._nbpLightMode;
}
private _nbpLabelPattern: NbpCalendarPattern = undefined;
@Input()
set nbpLabelPattern(value: NbpCalendarPattern) {
this._nbpLabelPattern = value;
if (this.component) {
this.component.nbpLabelPattern = value;
}
}
get nbpLabelPattern(): NbpCalendarPattern {
return this._nbpLabelPattern;
}
private _nbpDateSeparator: NbpDateSeparator = undefined;
@Input()
set nbpDateSeparator(value: NbpDateSeparator) {
this._nbpDateSeparator = value;
if (this.component) {
this.component.nbpDateSeparator = value;
}
}
get nbpDateSeparator(): NbpDateSeparator {
return this._nbpDateSeparator;
}
private _opened: boolean = undefined;
@Input()
set opened(value: boolean) {
this._opened = value;
if (this.component) {
this.component.opened = value;
}
}
get opened(): boolean {
return this._opened;
}
private _nbpPlacement: string = undefined;
@Input()
set nbpPlacement(value: string) {
this._nbpPlacement = value;
if (this.component) {
this.component.nbpPlacement = value;
}
}
get nbpPlacement(): string {
return this._nbpPlacement;
}
private _enableDefaultViewOnUnifiedVG: boolean = undefined;
@Input()
set enableDefaultViewOnUnifiedVG(value: boolean) {
this._enableDefaultViewOnUnifiedVG = value;
if (this.component) {
this.component.enableDefaultViewOnUnifiedVG = value;
}
}
get enableDefaultViewOnUnifiedVG(): boolean {
return this._enableDefaultViewOnUnifiedVG;
}
private _enableDynamicPosition: boolean = undefined;
@Input()
set enableDynamicPosition(value: boolean) {
this._enableDynamicPosition = value;
if (this.component) {
this.component.enableDynamicPosition = value;
}
}
get enableDynamicPosition(): boolean {
return this._enableDynamicPosition;
}
@Output() nbpOnNavigate = new EventEmitter<{ current: any, next: any }>();
@Output() modelChange = new EventEmitter<any>();
@Output() focus = new EventEmitter<boolean>();
get rplCalendar() {
return this.component.rplCalendar;
}
_ngbModelChanged(event: NgbDateStruct) {
return this.component ? this.component._ngbModelChanged(event): undefined;
}
getCalendarWidth() {
return this.component.getCalendarWidth();
}
getCalendarHeight() {
return this.component.getCalendarHeight();
}
public handleCalendar($event) {
return this.component.handleCalendar($event);
}
public setAriaLabel(date: any) {
return this.component.setAriaLabel(date);
}
public setSpanLabel(date){
return this.component.setSpanLabel(date);
}
public focusOutComponent(event: any){
return this.component.focusOutComponent(event);
}
}

View File

@ -53,28 +53,28 @@
<p class="new-part">Calendar generic (nbp-input-container + nbp-calendar-generic)</p>
<div>
<nbp-input-container [nbpStyle]="_nbpStyle.DEFAULT" [nbpLabel]="'Default'">
<nbp-calendar-generic [id]="'calendarDefault'" [name]="'calendarDefault'" [nbpStyle]="_nbpStyle.DEFAULT"
[nbpPlacement]="_nbpCalendarPosition.BOTTOM_LEFT" [nbpLabelPattern]="_nbpCalendarPattern.GGMMAAAA"
<nbp-fid-calendar-generic [id]="'calendarDefault'" [name]="'calendarDefault'" [nbpStyle]="_nbpStyle.DEFAULT"
[nbpPlacement]="_nbpCalendarPosition.BOTTOM_LEFT" [nbpLabelPattern]="_nbpCalendarPattern.GGMMAAAA"
[(ngModel)]="calendarModel">
</nbp-calendar-generic>
</nbp-fid-calendar-generic>
</nbp-input-container>
</div>
<div>
<nbp-input-container [nbpStyle]="_nbpStyle.DEFAULT" [nbpLabel]="'Default'">
<nbp-calendar-generic [id]="'calendarConstrainedDateInterval'" [name]="'calendarConstrainedDateInterval'"
<nbp-fid-calendar-generic [id]="'calendarConstrainedDateInterval'" [name]="'calendarConstrainedDateInterval'"
[nbpStyle]="_nbpStyle.DEFAULT" [nbpPlacement]="_nbpCalendarPosition.BOTTOM_RIGHT"
[nbpLabelPattern]="_nbpCalendarPattern.GGMMAAAA" [(ngModel)]="calendarModel"
[startDateEnabled]="startDate" [endDateEnabled]="endDate">
</nbp-calendar-generic>
</nbp-fid-calendar-generic>
</nbp-input-container>
</div>
<div>
<nbp-input-container [nbpStyle]="_nbpStyle.DEFAULT" [nbpLabel]="'Default'">
<nbp-calendar-generic [id]="'calendarConstrainedDateInterval'" [name]="'calendarConstrainedDateInterval'"
<nbp-fid-calendar-generic [id]="'calendarConstrainedDateInterval'" [name]="'calendarConstrainedDateInterval'"
[nbpStyle]="_nbpStyle.DEFAULT" [nbpPlacement]="_nbpCalendarPosition.BOTTOM_RIGHT" [disabled]="true"
[nbpLabelPattern]="_nbpCalendarPattern.GGMMAAAA" [(ngModel)]="calendarModel"
[startDateEnabled]="startDate" [endDateEnabled]="endDate">
</nbp-calendar-generic>
</nbp-fid-calendar-generic>
</nbp-input-container>
</div>

View File

@ -5,7 +5,10 @@ import {
NbpCalendarPattern, NbpCalendarPosition, NbpComboMultiComponent,
NbpDataSource, NbpStyle, NbpTableSelectionType, NgbDateStruct,
RowAction, RowDataExpander, RowModel,
NbpComboComponent
NbpComboComponent,
NgbDatepickerConfig,
NbpDatepickerConfiguration,
NbpCalendarGenericComponentNOA11Y
} from '@isp/xdce-widget';
@Component({
@ -17,6 +20,8 @@ export class Showcase1Component extends NbpBaseComponent {
public _nbpStyle = NbpStyle;
x : NbpCalendarGenericComponentNOA11Y
//
// TABBAR
items: Array<ITabItem<void>> = [
@ -181,8 +186,9 @@ export class Showcase1Component extends NbpBaseComponent {
campiStandardData: NbpDataSource<any>;
//
constructor(injector: Injector) {
constructor(injector: Injector, private calendarConfig: NgbDatepickerConfig) {
super(injector);
calendarConfig.outsideDays = "visible";
// table2
this.setDataRowExpander(this.table2Rows[0], 0);
this.campiStandardData = new NbpDataSource<any>(this.oggetti);