Compare commits
9 Commits
master
...
feature/an
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d3b3d2ce61 | ||
aef2744548 | |||
28c94936d6 | |||
c9497e3afc | |||
1c8da26bd8 | |||
b1d119fe1c | |||
ad1bbbe327 | |||
ea27f0b91c | |||
1d65d5a0cf |
@ -10,7 +10,8 @@ $btn-map: (
|
|||||||
secondary-bg-color: map-get($white-palette, 100),
|
secondary-bg-color: map-get($white-palette, 100),
|
||||||
secondary-border-color: map-get($orange-palette, 100),
|
secondary-border-color: map-get($orange-palette, 100),
|
||||||
secondary-color: map-get($orange-palette, 100),
|
secondary-color: map-get($orange-palette, 100),
|
||||||
secondary-bg-color-h: map-get($gray-palette, 100),
|
secondary-bg-color-h: map-get($orange-palette, 100),
|
||||||
|
secondary-color-h: map-get($white-palette, 100),
|
||||||
);
|
);
|
||||||
|
|
||||||
$checkbox-map: (
|
$checkbox-map: (
|
||||||
@ -82,10 +83,10 @@ body {
|
|||||||
|
|
||||||
@include isp-button-colors("secondary",
|
@include isp-button-colors("secondary",
|
||||||
map-get($btn-map, "secondary-bg-color"), map-get($btn-map, "secondary-border-color"), map-get($btn-map, "secondary-color"),
|
map-get($btn-map, "secondary-bg-color"), map-get($btn-map, "secondary-border-color"), map-get($btn-map, "secondary-color"),
|
||||||
map-get($btn-map, "secondary-bg-color-h"), map-get($btn-map, "secondary-border-color"), map-get($btn-map, "secondary-color"),
|
map-get($btn-map, "secondary-bg-color-h"), map-get($btn-map, "secondary-border-color"), map-get($btn-map, "secondary-color-h"),
|
||||||
map-get($btn-map, "secondary-bg-color-h"), map-get($btn-map, "secondary-border-color"), map-get($btn-map, "secondary-color"),
|
map-get($btn-map, "secondary-bg-color-h"), map-get($btn-map, "secondary-border-color"), map-get($btn-map, "secondary-color-h"),
|
||||||
map-get($btn-map, "secondary-bg-color"), map-get($btn-map, "secondary-border-color"), map-get($btn-map, "secondary-color"),
|
map-get($btn-map, "secondary-bg-color"), map-get($btn-map, "secondary-border-color"), map-get($btn-map, "secondary-color"),
|
||||||
map-get($btn-map, "secondary-bg-color-h"), map-get($btn-map, "secondary-border-color"), map-get($btn-map, "secondary-color"), );
|
map-get($btn-map, "secondary-bg-color-h"), map-get($btn-map, "secondary-border-color"), map-get($btn-map, "secondary-color-h"), );
|
||||||
}
|
}
|
||||||
|
|
||||||
nbp-button {
|
nbp-button {
|
||||||
@ -254,7 +255,7 @@ body {
|
|||||||
|
|
||||||
nbp-modal .isp-corporate-mode-wrapper {
|
nbp-modal .isp-corporate-mode-wrapper {
|
||||||
.isp-modal-close {
|
.isp-modal-close {
|
||||||
color: map-get($blue-palette, 100);
|
color: map-get($orange-palette, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
.isp-modal-container {
|
.isp-modal-container {
|
||||||
|
@ -43,6 +43,7 @@ body {
|
|||||||
outline: none !important;
|
outline: none !important;
|
||||||
-o-transition: all 0.1s;
|
-o-transition: all 0.1s;
|
||||||
transition: all 0.1s;
|
transition: all 0.1s;
|
||||||
|
border-radius: 0.20rem !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,6 +222,15 @@ body {
|
|||||||
|
|
||||||
.isp-modal-close {
|
.isp-modal-close {
|
||||||
padding: 14px;
|
padding: 14px;
|
||||||
|
|
||||||
|
.isp-font-comuni-chiudi::before {
|
||||||
|
content: $fa-var-times;
|
||||||
|
font: 14px / 1 FontAwesome !important;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.cursor-pointer {
|
.cursor-pointer {
|
||||||
@ -229,6 +239,7 @@ body {
|
|||||||
|
|
||||||
.isp-modal-content {
|
.isp-modal-content {
|
||||||
padding: unset;
|
padding: unset;
|
||||||
|
max-height: 94vh !important;
|
||||||
|
|
||||||
&>div:nth-child(2) {
|
&>div:nth-child(2) {
|
||||||
&>* {
|
&>* {
|
||||||
@ -1180,6 +1191,10 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpl-calendar-noa11y.isp-corporate-mode-wrapper.invisible {
|
||||||
|
position: fixed;
|
||||||
|
}
|
||||||
|
|
||||||
.ag-theme-balham {
|
.ag-theme-balham {
|
||||||
|
|
||||||
.ag-header-cell::after,
|
.ag-header-cell::after,
|
||||||
|
@ -40,6 +40,9 @@ export { WidgetFideuramShowcaseComponent } from './widgetfideuram/components/wid
|
|||||||
|
|
||||||
import { AgGridModule, AngularFrameworkComponentWrapper, AngularFrameworkOverrides } from 'ag-grid-angular';
|
import { AgGridModule, AngularFrameworkComponentWrapper, AngularFrameworkOverrides } from 'ag-grid-angular';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { NbpFidCalendarGenericComponent } from './widgetfideuram/components/nbp-fid-calendar-generic/nbp-fid-calendar-generic.component';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
export { NbpFidCalendarGenericComponent } from './widgetfideuram/components/nbp-fid-calendar-generic/nbp-fid-calendar-generic.component';
|
||||||
export { AgGridModule } from 'ag-grid-angular';
|
export { AgGridModule } from 'ag-grid-angular';
|
||||||
|
|
||||||
export { DATE_STRING_FORMAT, formatDate, formatNumber, setSpinnerMessage, clearSpinnerMessage } from './widgetfideuram/Utils';
|
export { DATE_STRING_FORMAT, formatDate, formatNumber, setSpinnerMessage, clearSpinnerMessage } from './widgetfideuram/Utils';
|
||||||
@ -51,6 +54,7 @@ export { DATE_STRING_FORMAT, formatDate, formatNumber, setSpinnerMessage, clearS
|
|||||||
NbpModule,
|
NbpModule,
|
||||||
AgGridModule,
|
AgGridModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
|
TranslateModule
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
NbpBreadCrumbsComponent,
|
NbpBreadCrumbsComponent,
|
||||||
@ -70,6 +74,7 @@ export { DATE_STRING_FORMAT, formatDate, formatNumber, setSpinnerMessage, clearS
|
|||||||
ShowcaseComponent,
|
ShowcaseComponent,
|
||||||
Showcase1Component,
|
Showcase1Component,
|
||||||
WidgetFideuramShowcaseComponent,
|
WidgetFideuramShowcaseComponent,
|
||||||
|
NbpFidCalendarGenericComponent
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
NbpBreadCrumbsComponent,
|
NbpBreadCrumbsComponent,
|
||||||
@ -89,7 +94,8 @@ export { DATE_STRING_FORMAT, formatDate, formatNumber, setSpinnerMessage, clearS
|
|||||||
ShowcaseComponent,
|
ShowcaseComponent,
|
||||||
Showcase1Component,
|
Showcase1Component,
|
||||||
WidgetFideuramShowcaseComponent,
|
WidgetFideuramShowcaseComponent,
|
||||||
AgGridModule
|
AgGridModule,
|
||||||
|
NbpFidCalendarGenericComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
AngularFrameworkOverrides,
|
AngularFrameworkOverrides,
|
||||||
|
@ -0,0 +1,124 @@
|
|||||||
|
<div class="datepicker-wrapper">
|
||||||
|
<input
|
||||||
|
#dateInput
|
||||||
|
[disabled]="disabled"
|
||||||
|
[id]="id"
|
||||||
|
[name]="name"
|
||||||
|
class="datepicker-input"
|
||||||
|
type="text"
|
||||||
|
placeholder="DD/MM/YYYY"
|
||||||
|
[value]="formattedSelectedDate"
|
||||||
|
(input)="onDateInputChange($event)"
|
||||||
|
/>
|
||||||
|
<i class="datepicker-icon fa fa-calendar" (click)="toggleCalendar()"></i>
|
||||||
|
|
||||||
|
<div
|
||||||
|
#calendarPopup
|
||||||
|
class="calendar calendar-popup"
|
||||||
|
[class.view-days]="view === 'days'"
|
||||||
|
[class.view-months]="view === 'months'"
|
||||||
|
[class.view-years]="view === 'years'"
|
||||||
|
[style.display]="calendarVisible ? 'block' : 'none'"
|
||||||
|
>
|
||||||
|
<!-- Calendar Header -->
|
||||||
|
<div class="calendar-header">
|
||||||
|
<button
|
||||||
|
class="calendar-cell fa fa-chevron-left"
|
||||||
|
(click)="prev()"
|
||||||
|
></button>
|
||||||
|
<div class="calendar-cell" id="monthYear" (click)="changeView()">
|
||||||
|
{{ monthYearHeader }}
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
class="calendar-cell fa fa-chevron-right"
|
||||||
|
(click)="next()"
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Calendar Grid -->
|
||||||
|
<div
|
||||||
|
class="calendar-grid"
|
||||||
|
[class.calendar-grid-7]="view === 'days'"
|
||||||
|
[class.calendar-grid-5]="view === 'years'"
|
||||||
|
>
|
||||||
|
<!-- Days View -->
|
||||||
|
<ng-container *ngIf="view === 'days'">
|
||||||
|
<!-- Days of Week -->
|
||||||
|
<div *ngFor="let day of daysOfWeek" class="day">{{ day }}</div>
|
||||||
|
|
||||||
|
<!-- Previous Month Days -->
|
||||||
|
<div
|
||||||
|
*ngFor="let day of getPreviousMonthDays()"
|
||||||
|
class="calendar-cell other-month"
|
||||||
|
[class.disabled]="day.disabled"
|
||||||
|
(click)="onPrevMonthDayClick(day)"
|
||||||
|
>
|
||||||
|
{{ pad(day.day) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Current Month Days -->
|
||||||
|
<div
|
||||||
|
*ngFor="let day of getCurrentMonthDays()"
|
||||||
|
class="calendar-cell"
|
||||||
|
[class.today]="day.isToday"
|
||||||
|
[class.selected]="day.isSelected"
|
||||||
|
[class.disabled]="day.disabled"
|
||||||
|
(click)="onCurrentMonthDayClick(day)"
|
||||||
|
>
|
||||||
|
{{ pad(day.day) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Next Month Days -->
|
||||||
|
<div
|
||||||
|
*ngFor="let day of getNextMonthDays()"
|
||||||
|
class="calendar-cell other-month"
|
||||||
|
[class.disabled]="day.disabled"
|
||||||
|
(click)="onNextMonthDayClick(day)"
|
||||||
|
>
|
||||||
|
{{ pad(day.day) }}
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<!-- Months View -->
|
||||||
|
<ng-container *ngIf="view === 'months'">
|
||||||
|
<div
|
||||||
|
*ngFor="let month of getVisibleMonths()"
|
||||||
|
class="calendar-cell"
|
||||||
|
[class.today]="month.isCurrentMonth"
|
||||||
|
[class.selected]="month.isSelected"
|
||||||
|
[class.disabled]="month.disabled"
|
||||||
|
(click)="onMonthClick(month)"
|
||||||
|
>
|
||||||
|
{{ month.name }}
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<!-- Years View -->
|
||||||
|
<ng-container *ngIf="view === 'years'">
|
||||||
|
<div
|
||||||
|
*ngFor="let yearObj of getVisibleYears()"
|
||||||
|
class="calendar-cell"
|
||||||
|
[class.today]="yearObj.isCurrentYear"
|
||||||
|
[class.selected]="yearObj.isSelected"
|
||||||
|
[class.disabled]="yearObj.disabled"
|
||||||
|
(click)="onYearClick(yearObj)"
|
||||||
|
>
|
||||||
|
{{ yearObj.year }}
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Calendar Actions -->
|
||||||
|
<div class="calendar-actions">
|
||||||
|
<button id="todayBtn" [disabled]="isTodayDisabled()" (click)="goToday()">
|
||||||
|
{{ "CALENDARIO.OGGI" | translate }}
|
||||||
|
</button>
|
||||||
|
<button id="clearBtn" (click)="clearSelection()">
|
||||||
|
{{ "CALENDARIO.CANCELLA" | translate }}
|
||||||
|
</button>
|
||||||
|
<button id="confirmBtn" (click)="confirmDate()">
|
||||||
|
{{ "CALENDARIO.CONFERMA" | translate }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,201 @@
|
|||||||
|
// Stili del calendario
|
||||||
|
.calendar {
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 15px;
|
||||||
|
border: 1px solid #e6e6e6;
|
||||||
|
color: #333333;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-popup {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 100;
|
||||||
|
display: none;
|
||||||
|
min-width: 160px;
|
||||||
|
padding: 5px 0;
|
||||||
|
margin: 2px 0 0;
|
||||||
|
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
|
||||||
|
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-header {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view-days .calendar-header {
|
||||||
|
grid-template-columns: 1fr 5fr 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view-years .calendar-header {
|
||||||
|
grid-template-columns: 1fr 3fr 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view-months .calendar-cell,
|
||||||
|
.view-years .calendar-cell {
|
||||||
|
padding: 6px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-cell {
|
||||||
|
padding: 5px 10px;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-size: 12px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: 1px solid #e6e6e6;
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-transition: all 0.1s;
|
||||||
|
-o-transition: all 0.1s;
|
||||||
|
transition: all 0.1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-cell:not(.disabled):not(.selected):hover {
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
#monthYear {
|
||||||
|
font-weight: bold;
|
||||||
|
flex-grow: 1;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-grid-7 {
|
||||||
|
grid-template-columns: repeat(7, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-grid-5 {
|
||||||
|
grid-template-columns: repeat(5, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-grid .day {
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-grid .selected {
|
||||||
|
background-color: #1797be;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-grid .selected:hover {
|
||||||
|
background-color: #137d9f;
|
||||||
|
border-color: #0e5d76;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-grid .other-month {
|
||||||
|
color: #909fa7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-grid .today {
|
||||||
|
color: #23b7e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-grid:not(:has(.selected)) .today {
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-grid .disabled {
|
||||||
|
color: #989898;
|
||||||
|
background-color: #edf1f2;
|
||||||
|
border-color: #dde6e9;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-actions {
|
||||||
|
padding: 10px 9px 2px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-actions button {
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
line-height: 1.5;
|
||||||
|
background-color: #eb690b;
|
||||||
|
color: #fff;
|
||||||
|
border: 1px solid #e6e6e6;
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-actions button#todayBtn {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-actions button#clearBtn {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-left-width: 0;
|
||||||
|
background-color: #fff;
|
||||||
|
color: #eb690b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-actions button#confirmBtn {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stili del datepicker
|
||||||
|
.datepicker-wrapper {
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datepicker-input {
|
||||||
|
padding: 5px;
|
||||||
|
height: 22px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-right-width: 0;
|
||||||
|
background: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datepicker-input::placeholder {
|
||||||
|
color: #909fa7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datepicker-input:focus {
|
||||||
|
border-color: #66afe9;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datepicker-input.input-error {
|
||||||
|
border-color: #f05050;
|
||||||
|
background-color: #fff0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datepicker-icon {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 13.5px;
|
||||||
|
padding: 0 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 22px;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-bottom-right-radius: 5px;
|
||||||
|
border-top-right-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datepicker-icon:active,
|
||||||
|
.datepicker-icon:hover,
|
||||||
|
.datepicker-icon:focus {
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-color: #cbcbcb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datepicker-icon:hover:active {
|
||||||
|
background-color: #d4d4d4;
|
||||||
|
border-color: #aaaaaa;
|
||||||
|
}
|
@ -0,0 +1,665 @@
|
|||||||
|
import {
|
||||||
|
Component,
|
||||||
|
OnInit,
|
||||||
|
Input,
|
||||||
|
Output,
|
||||||
|
EventEmitter,
|
||||||
|
ElementRef,
|
||||||
|
ViewChild,
|
||||||
|
HostListener,
|
||||||
|
Renderer2,
|
||||||
|
forwardRef,
|
||||||
|
} from "@angular/core";
|
||||||
|
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
|
||||||
|
import { NbpCalendarPattern, NbpCalendarPosition, NbpStyle } from "@isp/xdce-widget";
|
||||||
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'nbp-fid-calendar-generic',
|
||||||
|
templateUrl: './nbp-fid-calendar-generic.component.html',
|
||||||
|
styleUrls: ["./nbp-fid-calendar-generic.component.scss"],
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: NG_VALUE_ACCESSOR,
|
||||||
|
useExisting: forwardRef(() => NbpFidCalendarGenericComponent),
|
||||||
|
multi: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class NbpFidCalendarGenericComponent
|
||||||
|
implements OnInit, ControlValueAccessor
|
||||||
|
{
|
||||||
|
@Input() id: string= "";
|
||||||
|
@Input() name: string = "";
|
||||||
|
@Input() disabled: boolean = false;
|
||||||
|
@Input() dateFormat: string = "dd/MM/yyyy";
|
||||||
|
@Input() disabledWeekdays: number[] = []; // 0=domenica, 6=sabato
|
||||||
|
@Input() disabledDateRanges: { start: Date; end: Date }[] = [];
|
||||||
|
@Input() minDate: Date;
|
||||||
|
@Input() maxDate: Date;
|
||||||
|
@Input() nbpErrorMessage: string = "";
|
||||||
|
@Input() set disabledWeekends(value: boolean) {
|
||||||
|
if (value) {
|
||||||
|
this.disabledWeekdays = [...this.disabledWeekdays, 0, 6]; // Domenica e Sabato
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Input() nbpStyle: NbpStyle = NbpStyle.DEFAULT;
|
||||||
|
@Input() nbpLabelPattern : NbpCalendarPattern = NbpCalendarPattern.GGMMAAAA;
|
||||||
|
@Input() nbpPlacement : NbpCalendarPosition = NbpCalendarPosition.BOTTOM_LEFT;
|
||||||
|
@Input() startDateEnabled : Date = null;
|
||||||
|
@Input() endDateEnabled : Date = null;
|
||||||
|
|
||||||
|
@Output() ngModelChange = new EventEmitter<Date>();
|
||||||
|
|
||||||
|
@ViewChild("dateInput") dateInput: ElementRef;
|
||||||
|
|
||||||
|
// Cache per evitare ricalcoli continui e problemi di rendering
|
||||||
|
private _previousMonthDaysCache: { day: number; disabled: boolean }[] = [];
|
||||||
|
private _currentMonthDaysCache: {
|
||||||
|
day: number;
|
||||||
|
isToday: boolean;
|
||||||
|
isSelected: boolean;
|
||||||
|
disabled: boolean;
|
||||||
|
}[] = [];
|
||||||
|
private _nextMonthDaysCache: { day: number; disabled: boolean }[] = [];
|
||||||
|
private _visibleMonthsCache: {
|
||||||
|
monthIndex: number;
|
||||||
|
name: string;
|
||||||
|
isCurrentMonth: boolean;
|
||||||
|
isSelected: boolean;
|
||||||
|
disabled: boolean;
|
||||||
|
}[] = [];
|
||||||
|
private _visibleYearsCache: {
|
||||||
|
year: number;
|
||||||
|
isCurrentYear: boolean;
|
||||||
|
isSelected: boolean;
|
||||||
|
disabled: boolean;
|
||||||
|
}[] = [];
|
||||||
|
@ViewChild("calendarPopup") calendarPopup: ElementRef;
|
||||||
|
|
||||||
|
currentDate: Date = new Date();
|
||||||
|
selectedDate: Date = null;
|
||||||
|
view: "days" | "months" | "years" = "days";
|
||||||
|
months: string[] = [
|
||||||
|
"gennaio",
|
||||||
|
"febbraio",
|
||||||
|
"marzo",
|
||||||
|
"aprile",
|
||||||
|
"maggio",
|
||||||
|
"giugno",
|
||||||
|
"luglio",
|
||||||
|
"agosto",
|
||||||
|
"settembre",
|
||||||
|
"ottobre",
|
||||||
|
"novembre",
|
||||||
|
"dicembre",
|
||||||
|
];
|
||||||
|
daysOfWeek: string[] = ["lun", "mar", "mer", "gio", "ven", "sab", "dom"];
|
||||||
|
formattedSelectedDate: string = "";
|
||||||
|
calendarVisible: boolean = false;
|
||||||
|
|
||||||
|
constructor(private renderer: Renderer2, private elementRef: ElementRef, public translate : TranslateService) {}
|
||||||
|
|
||||||
|
private onChange = (value: Date | null) => {};
|
||||||
|
private onTouched = () => {};
|
||||||
|
|
||||||
|
writeValue(value: Date | null): void {
|
||||||
|
this.selectedDate = value;
|
||||||
|
}
|
||||||
|
registerOnChange(fn: any): void {
|
||||||
|
this.onChange = fn;
|
||||||
|
}
|
||||||
|
registerOnTouched(fn: any): void {
|
||||||
|
this.onTouched = fn;
|
||||||
|
}
|
||||||
|
setDisabledState?(isDisabled: boolean): void {
|
||||||
|
this.disabled = isDisabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
// Inizializza la data selezionata se presente
|
||||||
|
if (this.selectedDate) {
|
||||||
|
this.formattedSelectedDate = this.formatDate(
|
||||||
|
this.selectedDate,
|
||||||
|
this.dateFormat
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inizializza le cache
|
||||||
|
this.updateAllCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- UTILITY ---
|
||||||
|
private pad(n: number): string {
|
||||||
|
return n < 10 ? "0" + n : n.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
formatDate(date: Date, format: string): string {
|
||||||
|
if (!date) return "";
|
||||||
|
return format
|
||||||
|
.replace("dd", this.pad(date.getDate()))
|
||||||
|
.replace("MM", this.pad(date.getMonth() + 1))
|
||||||
|
.replace("yyyy", date.getFullYear().toString())
|
||||||
|
.replace("yy", String(date.getFullYear()).slice(-2));
|
||||||
|
}
|
||||||
|
|
||||||
|
sameDate(d1: Date, d2: Date): boolean {
|
||||||
|
return (
|
||||||
|
d1.getFullYear() === d2.getFullYear() &&
|
||||||
|
d1.getMonth() === d2.getMonth() &&
|
||||||
|
d1.getDate() === d2.getDate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- GESTIONE POPUP ---
|
||||||
|
positionCalendarPopup(): void {
|
||||||
|
if (!this.calendarPopup || !this.dateInput) return;
|
||||||
|
|
||||||
|
const input = this.dateInput.nativeElement;
|
||||||
|
const popup = this.calendarPopup.nativeElement;
|
||||||
|
|
||||||
|
// Sposta il popup in fondo al body (portal)
|
||||||
|
if (popup.parentNode !== document.body) {
|
||||||
|
document.body.appendChild(popup);
|
||||||
|
}
|
||||||
|
|
||||||
|
popup.style.display = "block";
|
||||||
|
popup.style.position = "absolute";
|
||||||
|
popup.style.zIndex = "9999";
|
||||||
|
|
||||||
|
const rect = input.getBoundingClientRect();
|
||||||
|
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
||||||
|
const scrollLeft =
|
||||||
|
window.pageXOffset || document.documentElement.scrollLeft;
|
||||||
|
|
||||||
|
popup.style.top = rect.bottom + scrollTop + "px";
|
||||||
|
popup.style.left = rect.left + scrollLeft + "px";
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleCalendar(): void {
|
||||||
|
if (!this.disabled) {
|
||||||
|
this.calendarVisible = !this.calendarVisible;
|
||||||
|
if (this.calendarVisible) {
|
||||||
|
this.showCalendar();
|
||||||
|
this.updateAllCaches();
|
||||||
|
} else {
|
||||||
|
this.hideCalendar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showCalendar(): void {
|
||||||
|
this.calendarVisible = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.positionCalendarPopup();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
hideCalendar(): void {
|
||||||
|
this.calendarVisible = false;
|
||||||
|
if (this.calendarPopup) {
|
||||||
|
this.calendarPopup.nativeElement.style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.selectedDate) {
|
||||||
|
this.currentDate = new Date(this.selectedDate);
|
||||||
|
} else {
|
||||||
|
this.currentDate = new Date();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@HostListener("document:mousedown", ["$event"])
|
||||||
|
onClickOutside(event: MouseEvent): void {
|
||||||
|
if (
|
||||||
|
this.calendarVisible &&
|
||||||
|
!this.elementRef.nativeElement.contains(event.target) &&
|
||||||
|
this.calendarPopup &&
|
||||||
|
!this.calendarPopup.nativeElement.contains(event.target)
|
||||||
|
) {
|
||||||
|
this.hideCalendar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- LOGICA DATE ---
|
||||||
|
isDateDisabled(date: Date): boolean {
|
||||||
|
// Disabilita date precedenti alla minDate
|
||||||
|
if (this.minDate && date < this.minDate) return true;
|
||||||
|
|
||||||
|
// Disabilita date precedenti alla maxDate
|
||||||
|
if (this.maxDate && date > this.maxDate) return true;
|
||||||
|
|
||||||
|
// Disabilita per giorno della settimana
|
||||||
|
if (this.disabledWeekdays.indexOf(date.getDay()) !== -1) return true;
|
||||||
|
|
||||||
|
// Disabilita per range
|
||||||
|
for (const range of this.disabledDateRanges) {
|
||||||
|
if (date >= range.start && date <= range.end) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
isTodayDisabled(): boolean {
|
||||||
|
const today = new Date();
|
||||||
|
return this.isDateDisabled(today);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- NAVIGATION ---
|
||||||
|
prev(): void {
|
||||||
|
if (this.view === "days") {
|
||||||
|
this.currentDate.setMonth(this.currentDate.getMonth() - 1);
|
||||||
|
} else if (this.view === "months") {
|
||||||
|
this.currentDate.setFullYear(this.currentDate.getFullYear() - 1);
|
||||||
|
} else {
|
||||||
|
this.currentDate.setFullYear(this.currentDate.getFullYear() - 20);
|
||||||
|
}
|
||||||
|
this.currentDate = new Date(this.currentDate); // Forza refresh
|
||||||
|
this.updateAllCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
next(): void {
|
||||||
|
if (this.view === "days") {
|
||||||
|
this.currentDate.setMonth(this.currentDate.getMonth() + 1);
|
||||||
|
} else if (this.view === "months") {
|
||||||
|
this.currentDate.setFullYear(this.currentDate.getFullYear() + 1);
|
||||||
|
} else {
|
||||||
|
this.currentDate.setFullYear(this.currentDate.getFullYear() + 20);
|
||||||
|
}
|
||||||
|
this.currentDate = new Date(this.currentDate); // Forza refresh
|
||||||
|
this.updateAllCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
goToday(): void {
|
||||||
|
this.currentDate = new Date();
|
||||||
|
this.selectedDate = new Date();
|
||||||
|
this.formattedSelectedDate = this.formatDate(
|
||||||
|
this.selectedDate,
|
||||||
|
this.dateFormat
|
||||||
|
);
|
||||||
|
this.view = "days";
|
||||||
|
this.selectedDateChange.emit(this.selectedDate);
|
||||||
|
this.updateAllCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
clearSelection(): void {
|
||||||
|
this.selectedDate = null;
|
||||||
|
this.formattedSelectedDate = "";
|
||||||
|
this.selectedDateChange.emit(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
confirmDate(): void {
|
||||||
|
// Metodo usato per confermare esplicitamente la data corrente
|
||||||
|
this.selectedDateChange.emit(this.selectedDate);
|
||||||
|
this.hideCalendar();
|
||||||
|
}
|
||||||
|
|
||||||
|
changeView(): void {
|
||||||
|
if (this.view === "days") {
|
||||||
|
this.view = "months";
|
||||||
|
} else if (this.view === "months") {
|
||||||
|
this.view = "years";
|
||||||
|
}
|
||||||
|
this.updateAllCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- SELEZIONE DATE ---
|
||||||
|
selectDate(date: Date): void {
|
||||||
|
if (this.isDateDisabled(date)) return;
|
||||||
|
|
||||||
|
this.selectedDate = date;
|
||||||
|
this.formattedSelectedDate = this.formatDate(
|
||||||
|
this.selectedDate,
|
||||||
|
this.dateFormat
|
||||||
|
);
|
||||||
|
// Non emettiamo qui l'evento dateChange per evitare doppie emissioni
|
||||||
|
this.updateAllCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
selectMonth(monthIndex: number): void {
|
||||||
|
if (this.isMonthDisabled(monthIndex)) return;
|
||||||
|
|
||||||
|
this.currentDate.setMonth(monthIndex);
|
||||||
|
this.currentDate = new Date(this.currentDate); // Forza refresh
|
||||||
|
this.view = "days";
|
||||||
|
this.updateAllCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
selectYear(year: number): void {
|
||||||
|
if (this.isYearDisabled(year)) return;
|
||||||
|
|
||||||
|
this.currentDate.setFullYear(year);
|
||||||
|
this.currentDate = new Date(this.currentDate); // Forza refresh
|
||||||
|
this.view = "months";
|
||||||
|
this.updateAllCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
selectDayFromPrevMonth(day: number): void {
|
||||||
|
const year = this.currentDate.getFullYear();
|
||||||
|
const month = this.currentDate.getMonth();
|
||||||
|
const prevMonthDate = new Date(year, month - 1, day);
|
||||||
|
|
||||||
|
if (this.isDateDisabled(prevMonthDate)) return;
|
||||||
|
|
||||||
|
this.currentDate.setMonth(month - 1);
|
||||||
|
this.currentDate = new Date(this.currentDate); // Forza refresh
|
||||||
|
this.selectedDate = prevMonthDate;
|
||||||
|
this.formattedSelectedDate = this.formatDate(
|
||||||
|
this.selectedDate,
|
||||||
|
this.dateFormat
|
||||||
|
);
|
||||||
|
this.selectedDateChange.emit(this.selectedDate);
|
||||||
|
this.updateAllCaches();
|
||||||
|
this.hideCalendar(); // Chiudi il calendario dopo la selezione
|
||||||
|
}
|
||||||
|
|
||||||
|
selectDayFromNextMonth(day: number): void {
|
||||||
|
const year = this.currentDate.getFullYear();
|
||||||
|
const month = this.currentDate.getMonth();
|
||||||
|
const nextMonthDate = new Date(year, month + 1, day);
|
||||||
|
|
||||||
|
if (this.isDateDisabled(nextMonthDate)) return;
|
||||||
|
|
||||||
|
this.currentDate.setMonth(month + 1);
|
||||||
|
this.currentDate = new Date(this.currentDate); // Forza refresh
|
||||||
|
this.selectedDate = nextMonthDate;
|
||||||
|
this.formattedSelectedDate = this.formatDate(
|
||||||
|
this.selectedDate,
|
||||||
|
this.dateFormat
|
||||||
|
);
|
||||||
|
this.selectedDateChange.emit(this.selectedDate);
|
||||||
|
this.updateAllCaches();
|
||||||
|
this.hideCalendar(); // Chiudi il calendario dopo la selezione
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- UTILITY PER MESI E ANNI ---
|
||||||
|
isMonthDisabled(monthIndex: number): boolean {
|
||||||
|
// Se non ci sono restrizioni, il mese è abilitato
|
||||||
|
if (
|
||||||
|
!this.minDate &&
|
||||||
|
!this.maxDate &&
|
||||||
|
(!this.disabledDateRanges || this.disabledDateRanges.length === 0)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const year = this.currentDate.getFullYear();
|
||||||
|
const firstDayOfMonth = new Date(year, monthIndex, 1, 0, 0, 0, 0);
|
||||||
|
const lastDayOfMonth = new Date(year, monthIndex + 1, 0, 23, 59, 59, 999);
|
||||||
|
|
||||||
|
// Disabilita mese se completamente fuori dai limiti
|
||||||
|
if (this.minDate && lastDayOfMonth < this.minDate) return true;
|
||||||
|
if (this.maxDate && firstDayOfMonth > this.maxDate) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
isYearDisabled(year: number): boolean {
|
||||||
|
// Se non ci sono restrizioni, l'anno è abilitato
|
||||||
|
if (!this.minDate && !this.maxDate) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstDayOfYear = new Date(year, 0, 1, 0, 0, 0, 0);
|
||||||
|
const lastDayOfYear = new Date(year, 11, 31, 23, 59, 59, 999);
|
||||||
|
|
||||||
|
// Disabilita anno se completamente fuori dai limiti
|
||||||
|
if (this.minDate && lastDayOfYear < this.minDate) return true;
|
||||||
|
if (this.maxDate && firstDayOfYear > this.maxDate) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- INPUT HANDLING ---
|
||||||
|
onDateInputChange(event: Event): void {
|
||||||
|
const value = (event.target as HTMLInputElement).value;
|
||||||
|
const datePattern = /^(\d{2})\/(\d{2})\/(\d{4})$/;
|
||||||
|
|
||||||
|
if (datePattern.test(value)) {
|
||||||
|
const [, dd, mm, yyyy] = value.match(datePattern);
|
||||||
|
const date = new Date(parseInt(yyyy), parseInt(mm) - 1, parseInt(dd));
|
||||||
|
|
||||||
|
// Controlla che sia una data valida
|
||||||
|
if (
|
||||||
|
date &&
|
||||||
|
date.getDate() === parseInt(dd) &&
|
||||||
|
date.getMonth() + 1 === parseInt(mm) &&
|
||||||
|
date.getFullYear() === parseInt(yyyy)
|
||||||
|
) {
|
||||||
|
if (!this.isDateDisabled(date)) {
|
||||||
|
this.selectedDate = date;
|
||||||
|
this.currentDate = new Date(date);
|
||||||
|
this.formattedSelectedDate = this.formatDate(
|
||||||
|
this.selectedDate,
|
||||||
|
this.dateFormat
|
||||||
|
);
|
||||||
|
this.selectedDateChange.emit(this.selectedDate);
|
||||||
|
this.updateAllCaches();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- CALENDAR DATA ---
|
||||||
|
getDaysInMonth(year: number, month: number): number {
|
||||||
|
return new Date(year, month + 1, 0).getDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metodo per aggiornare tutte le cache quando cambiano i dati
|
||||||
|
private updateAllCaches(): void {
|
||||||
|
this.updatePreviousMonthDaysCache();
|
||||||
|
this.updateCurrentMonthDaysCache();
|
||||||
|
this.updateNextMonthDaysCache();
|
||||||
|
this.updateVisibleMonthsCache();
|
||||||
|
this.updateVisibleYearsCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metodi per aggiornare le singole cache
|
||||||
|
private updatePreviousMonthDaysCache(): void {
|
||||||
|
const year = this.currentDate.getFullYear();
|
||||||
|
const month = this.currentDate.getMonth();
|
||||||
|
const startDay = this.getFirstDayOfMonth(year, month);
|
||||||
|
const daysInPrevMonth = this.getDaysInMonth(year, month - 1);
|
||||||
|
|
||||||
|
const days = [];
|
||||||
|
for (let i = startDay; i > 0; i--) {
|
||||||
|
const day = daysInPrevMonth - i + 1;
|
||||||
|
const prevMonthDate = new Date(year, month - 1, day);
|
||||||
|
days.push({
|
||||||
|
day,
|
||||||
|
disabled: this.isDateDisabled(prevMonthDate),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this._previousMonthDaysCache = days;
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateCurrentMonthDaysCache(): void {
|
||||||
|
const year = this.currentDate.getFullYear();
|
||||||
|
const month = this.currentDate.getMonth();
|
||||||
|
const daysInMonth = this.getDaysInMonth(year, month);
|
||||||
|
const today = new Date();
|
||||||
|
|
||||||
|
const days = [];
|
||||||
|
for (let i = 1; i <= daysInMonth; i++) {
|
||||||
|
const date = new Date(year, month, i);
|
||||||
|
days.push({
|
||||||
|
day: i,
|
||||||
|
isToday: this.sameDate(today, date),
|
||||||
|
isSelected: this.selectedDate
|
||||||
|
? this.sameDate(this.selectedDate, date)
|
||||||
|
: false,
|
||||||
|
disabled: this.isDateDisabled(date),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this._currentMonthDaysCache = days;
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateNextMonthDaysCache(): void {
|
||||||
|
const year = this.currentDate.getFullYear();
|
||||||
|
const month = this.currentDate.getMonth();
|
||||||
|
const startDay = this.getFirstDayOfMonth(year, month);
|
||||||
|
const daysInMonth = this.getDaysInMonth(year, month);
|
||||||
|
|
||||||
|
const totalCells = 42; // 7 giorni x 6 settimane
|
||||||
|
const nextMonthDays = totalCells - (startDay + daysInMonth);
|
||||||
|
|
||||||
|
const days = [];
|
||||||
|
for (let i = 1; i <= nextMonthDays; i++) {
|
||||||
|
const nextMonthDate = new Date(year, month + 1, i);
|
||||||
|
days.push({
|
||||||
|
day: i,
|
||||||
|
disabled: this.isDateDisabled(nextMonthDate),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this._nextMonthDaysCache = days;
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateVisibleMonthsCache(): void {
|
||||||
|
const currentYear = this.currentDate.getFullYear();
|
||||||
|
const today = new Date();
|
||||||
|
|
||||||
|
const months = this.months.map((name, idx) => ({
|
||||||
|
monthIndex: idx,
|
||||||
|
name,
|
||||||
|
isCurrentMonth:
|
||||||
|
currentYear === today.getFullYear() && idx === today.getMonth(),
|
||||||
|
isSelected: this.selectedDate
|
||||||
|
? currentYear === this.selectedDate.getFullYear() &&
|
||||||
|
idx === this.selectedDate.getMonth()
|
||||||
|
: false,
|
||||||
|
disabled: this.isMonthDisabled(idx),
|
||||||
|
}));
|
||||||
|
|
||||||
|
this._visibleMonthsCache = months;
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateVisibleYearsCache(): void {
|
||||||
|
const base = Math.floor(this.currentDate.getFullYear() / 20) * 20;
|
||||||
|
const currentYear = new Date().getFullYear();
|
||||||
|
|
||||||
|
const years = [];
|
||||||
|
for (let y = base; y < base + 20; y++) {
|
||||||
|
years.push({
|
||||||
|
year: y,
|
||||||
|
isCurrentYear: y === currentYear,
|
||||||
|
isSelected: this.selectedDate
|
||||||
|
? y === this.selectedDate.getFullYear()
|
||||||
|
: false,
|
||||||
|
disabled: this.isYearDisabled(y),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this._visibleYearsCache = years;
|
||||||
|
}
|
||||||
|
|
||||||
|
getFirstDayOfMonth(year: number, month: number): number {
|
||||||
|
return (new Date(year, month, 1).getDay() + 6) % 7; // Lunedì=0, Domenica=6
|
||||||
|
}
|
||||||
|
|
||||||
|
getPreviousMonthDays(): { day: number; disabled: boolean }[] {
|
||||||
|
return this._previousMonthDaysCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
getCurrentMonthDays(): {
|
||||||
|
day: number;
|
||||||
|
isToday: boolean;
|
||||||
|
isSelected: boolean;
|
||||||
|
disabled: boolean;
|
||||||
|
}[] {
|
||||||
|
return this._currentMonthDaysCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
getNextMonthDays(): { day: number; disabled: boolean }[] {
|
||||||
|
return this._nextMonthDaysCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
getVisibleYears(): {
|
||||||
|
year: number;
|
||||||
|
isCurrentYear: boolean;
|
||||||
|
isSelected: boolean;
|
||||||
|
disabled: boolean;
|
||||||
|
}[] {
|
||||||
|
return this._visibleYearsCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
getVisibleMonths(): {
|
||||||
|
monthIndex: number;
|
||||||
|
name: string;
|
||||||
|
isCurrentMonth: boolean;
|
||||||
|
isSelected: boolean;
|
||||||
|
disabled: boolean;
|
||||||
|
}[] {
|
||||||
|
return this._visibleMonthsCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
get yearRange(): string {
|
||||||
|
if (this.view === "years") {
|
||||||
|
const base = Math.floor(this.currentDate.getFullYear() / 20) * 20;
|
||||||
|
return `${base} - ${base + 19}`;
|
||||||
|
}
|
||||||
|
return this.currentDate.getFullYear().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
get monthYearHeader(): string {
|
||||||
|
if (this.view === "days") {
|
||||||
|
return `${
|
||||||
|
this.months[this.currentDate.getMonth()]
|
||||||
|
} ${this.currentDate.getFullYear()}`;
|
||||||
|
}
|
||||||
|
return this.yearRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- AZIONI SUI GIORNI, MESI E ANNI ---
|
||||||
|
onPrevMonthDayClick(day: { day: number; disabled: boolean }): void {
|
||||||
|
if (day.disabled) return;
|
||||||
|
this.selectDayFromPrevMonth(day.day);
|
||||||
|
// Non serve chiamare hideCalendar() qui perché lo fa già selectDayFromPrevMonth
|
||||||
|
}
|
||||||
|
|
||||||
|
onCurrentMonthDayClick(day: {
|
||||||
|
day: number;
|
||||||
|
isToday: boolean;
|
||||||
|
isSelected: boolean;
|
||||||
|
disabled: boolean;
|
||||||
|
}): void {
|
||||||
|
if (day.disabled) return;
|
||||||
|
const date = new Date(
|
||||||
|
this.currentDate.getFullYear(),
|
||||||
|
this.currentDate.getMonth(),
|
||||||
|
day.day
|
||||||
|
);
|
||||||
|
this.selectDate(date);
|
||||||
|
this.selectedDateChange.emit(this.selectedDate);
|
||||||
|
this.hideCalendar();
|
||||||
|
}
|
||||||
|
|
||||||
|
onNextMonthDayClick(day: { day: number; disabled: boolean }): void {
|
||||||
|
if (day.disabled) return;
|
||||||
|
this.selectDayFromNextMonth(day.day);
|
||||||
|
// Non serve chiamare hideCalendar() qui perché lo fa già selectDayFromNextMonth
|
||||||
|
}
|
||||||
|
|
||||||
|
onMonthClick(month: {
|
||||||
|
monthIndex: number;
|
||||||
|
name: string;
|
||||||
|
isCurrentMonth: boolean;
|
||||||
|
isSelected: boolean;
|
||||||
|
disabled: boolean;
|
||||||
|
}): void {
|
||||||
|
if (month.disabled) return;
|
||||||
|
this.selectMonth(month.monthIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
onYearClick(yearObj: {
|
||||||
|
year: number;
|
||||||
|
isCurrentYear: boolean;
|
||||||
|
isSelected: boolean;
|
||||||
|
disabled: boolean;
|
||||||
|
}): void {
|
||||||
|
if (yearObj.disabled) return;
|
||||||
|
this.selectYear(yearObj.year);
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,18 @@
|
|||||||
<select class="nbp-fid-combo" (change)="onChange($event)" [disabled]="disabled">
|
<select
|
||||||
<option *ngIf="nbpShowEmptyValue"
|
class="nbp-fid-combo"
|
||||||
[selected]="ngModel === _emptyValue"
|
[name]="name"
|
||||||
[value]="_emptyValue">{{_emptyLabel}}</option>
|
ngDefaultControl
|
||||||
|
(change)="onValueChange($event)"
|
||||||
|
[disabled]="disabled">
|
||||||
|
<option
|
||||||
|
*ngIf="nbpShowEmptyValue"
|
||||||
|
[selected]="value === _emptyValue"
|
||||||
|
[ngValue]="_emptyValue"
|
||||||
|
[value]="_emptyValue"
|
||||||
|
>{{_emptyLabel}}</option>
|
||||||
<option *ngFor="let op of _options"
|
<option *ngFor="let op of _options"
|
||||||
[value]="optStrValue(op)"
|
[value]="op.strValue"
|
||||||
[selected]="selected(op)"
|
[ngValue]="op.value"
|
||||||
>{{optLabel(op)}}</option>
|
[selected]="op.selected"
|
||||||
|
>{{op.label}}</option>
|
||||||
</select>
|
</select>
|
||||||
|
@ -1,24 +1,35 @@
|
|||||||
.nbp-fid-combo {
|
.nbp-fid-combo {
|
||||||
border: 1px solid;
|
// border: 1px solid;
|
||||||
border-color: #DDE6E9; // map-get($gray-palette, 100);
|
// border-color: #DDE6E9; // map-get($gray-palette, 100);
|
||||||
// background: url("data:image/svg+xml,<svg height='10px' width='10px' viewBox='0 0 16 16' fill='%23000000' xmlns='http://www.w3.org/2000/svg'><path d='M7.247 11.14 2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z'/></svg>") no-repeat;
|
// background: #fff;
|
||||||
// background: #fff url("data:image/svg+xml;utf8,<svg viewBox='0 0 16 16' width='10px' height='10px' xmlns='http://www.w3.org/2000/svg'><g><path d='m121.3,34.6c-1.6-1.6-4.2-1.6-5.8,0l-51,51.1-51.1-51.1c-1.6-1.6-4.2-1.6-5.8,0-1.6,1.6-1.6,4.2 0,5.8l53.9,53.9c0.8,0.8 1.8,1.2 2.9,1.2 1,0 2.1-0.4 2.9-1.2l53.9-53.9c1.7-1.6 1.7-4.2 0.1-5.8z' fill='white'/></g></svg>") no-repeat;
|
// min-width: 2em;
|
||||||
// background: #fff url("data:image/svg+xml;utf8,<svg viewBox='0 0 16 16' width='10px' height='10px' fill='%23000000' xmlns='http://www.w3.org/2000/svg'><g><path d='m121.3,34.6c-1.6-1.6-4.2-1.6-5.8,0l-51,51.1-51.1-51.1c-1.6-1.6-4.2-1.6-5.8,0-1.6,1.6-1.6,4.2 0,5.8l53.9,53.9c0.8,0.8 1.8,1.2 2.9,1.2 1,0 2.1-0.4 2.9-1.2l53.9-53.9c1.7-1.6 1.7-4.2 0.1-5.8z'/></g></svg>") no-repeat;
|
// padding-top: 1px;
|
||||||
// background-position: calc(100% - 0.75em) center !important;
|
// padding-bottom: 1px;
|
||||||
|
// padding-left: 1px;
|
||||||
background: #fff;
|
// padding-right: 1em !important;
|
||||||
// -moz-appearance:none !important;
|
// width: 100%;
|
||||||
// -webkit-appearance: none !important;
|
display: block;
|
||||||
// appearance: none !important;
|
|
||||||
min-width: 2em;
|
|
||||||
padding-top: 1px;
|
|
||||||
padding-bottom: 1px;
|
|
||||||
padding-left: 1px;
|
|
||||||
padding-right: 1em !important;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
padding: 1px;
|
||||||
|
height: 22px;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.52857143;
|
||||||
|
color: #3a3f51;
|
||||||
|
background-color: #ffffff;
|
||||||
|
background-image: none;
|
||||||
|
border: 1px solid #dde6e9;
|
||||||
|
border-radius: 0;
|
||||||
|
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||||
|
box-shadow: 0 0 0 #000 !important;
|
||||||
|
-webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||||
|
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||||
|
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||||
|
|
||||||
&:focus,
|
&:focus,
|
||||||
&:active {
|
&:active {
|
||||||
|
outline: 0 !important;
|
||||||
|
box-shadow: 0 0 0 #000 !important;
|
||||||
border-color: #66AFE9; // map-get($blue-palette, 100);
|
border-color: #66AFE9; // map-get($blue-palette, 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,57 @@
|
|||||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, Output, OnInit, forwardRef, ChangeDetectionStrategy } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
NbpBaseComponent,
|
NbpBaseComponent,
|
||||||
NbpStyle,
|
NbpStyle,
|
||||||
NbpDataSource
|
NbpDataSource
|
||||||
} from '@isp/xdce-widget';
|
} from '@isp/xdce-widget';
|
||||||
|
|
||||||
|
import {ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR, } from '@angular/forms';
|
||||||
|
|
||||||
|
//
|
||||||
|
// auto incremental index for noname combo instance
|
||||||
|
let comboIndex = 111;
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'nbp-fid-combo',
|
selector: 'nbp-fid-combo',
|
||||||
templateUrl: './nbp-fid-combo.component.html',
|
templateUrl: './nbp-fid-combo.component.html',
|
||||||
styleUrls: ['./nbp-fid-combo.component.scss']
|
styleUrls: ['./nbp-fid-combo.component.scss'],
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: NG_VALUE_ACCESSOR,
|
||||||
|
useExisting: forwardRef(() => NbpFidComboComponent),
|
||||||
|
multi: true
|
||||||
|
}
|
||||||
|
]
|
||||||
})
|
})
|
||||||
export class NbpFidComboComponent extends NbpBaseComponent {
|
export class NbpFidComboComponent
|
||||||
constructor(){
|
extends NbpBaseComponent
|
||||||
|
implements ControlValueAccessor {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Input() name: string;
|
||||||
|
|
||||||
|
onChange: any = () => { };
|
||||||
|
onTouch: any = () => {};
|
||||||
|
|
||||||
|
compareFn(c1: any, c2: any): boolean {
|
||||||
|
return c1 && c2 ? c1.value === c2.value : c1 === c2;
|
||||||
|
}
|
||||||
|
|
||||||
|
registerOnChange(fn: any): void {
|
||||||
|
this.onChange = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
registerOnTouched(fn: any): void {
|
||||||
|
this.onTouch = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeValue(input: string) {
|
||||||
|
this.value = input;
|
||||||
|
}
|
||||||
|
|
||||||
@Input() nbpViewField : string = null;
|
@Input() nbpViewField : string = null;
|
||||||
@Input() nbpKeyField : string = null;
|
@Input() nbpKeyField : string = null;
|
||||||
|
|
||||||
@ -24,16 +61,23 @@ export class NbpFidComboComponent extends NbpBaseComponent {
|
|||||||
|
|
||||||
private _model: any;
|
private _model: any;
|
||||||
@Input()
|
@Input()
|
||||||
set ngModel(value: any) {
|
set value(value: any) {
|
||||||
this._model = value;
|
this._model = value;
|
||||||
if (this._nbpShowEmptyValue && this._model !== null && !this.nbpViewField) {
|
if (this._model === undefined)
|
||||||
this._emptyValue = this._model;
|
this._model = null;
|
||||||
this._emptyLabel = this._model;
|
|
||||||
}
|
// FUTURE handle a model value that is not present in options
|
||||||
|
// as "empty" value
|
||||||
|
// if (this._nbpShowEmptyValue && this._model !== null && !this.nbpViewField) {
|
||||||
|
// this._emptyValue = this._model;
|
||||||
|
// this._emptyLabel = this._model;
|
||||||
|
// }
|
||||||
|
|
||||||
|
this._selectOnModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Output() ngModelChange = new EventEmitter<any>();
|
@Output() ngModelChange = new EventEmitter<any>();
|
||||||
get ngModel(): any {
|
get value(): any {
|
||||||
return this._model;
|
return this._model;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,6 +120,9 @@ export class NbpFidComboComponent extends NbpBaseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
if (!this.name) {
|
||||||
|
this.name = "combo_" + (comboIndex++);
|
||||||
|
}
|
||||||
this._readOptions();
|
this._readOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,11 +168,26 @@ export class NbpFidComboComponent extends NbpBaseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
selected(op : any) {
|
_selectOnModel() {
|
||||||
return this.optValue(op) === this.ngModel;
|
const arr = this._options;
|
||||||
|
for (let a of arr) {
|
||||||
|
a.selected = false;
|
||||||
|
}
|
||||||
|
const val = this.value;
|
||||||
|
if (val === null || val === undefined)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (let a of arr) {
|
||||||
|
const v = a.value;
|
||||||
|
const sv = a.strValue;
|
||||||
|
if (sv === val) {
|
||||||
|
a.selected = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(event: Event) {
|
onValueChange(event: Event) {
|
||||||
if (this._disabled)
|
if (this._disabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -142,7 +204,9 @@ export class NbpFidComboComponent extends NbpBaseComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ngModel = sel;
|
this.value = sel;
|
||||||
this.ngModelChange.emit(this.ngModel);
|
this.ngModelChange.emit(this.value);
|
||||||
|
if (this.onChange)
|
||||||
|
this.onChange(this.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,22 +1,31 @@
|
|||||||
<div>
|
<div>
|
||||||
|
|
||||||
<p class="new-part">Tabbar (nbp-tab-bar):</p>
|
<p class="new-part">Tabbar (nbp-tab-bar):</p>
|
||||||
|
|
||||||
<nbp-tab-bar [nbpStyle]="_nbpStyle.DEFAULT" [nbpItems]="items" [(nbpSelectedIndex)]="currentSelectedIndex"
|
<nbp-tab-bar
|
||||||
[nbpTabContent]="true">
|
[nbpStyle]="_nbpStyle.DEFAULT"
|
||||||
|
[nbpItems]="items"
|
||||||
|
[(nbpSelectedIndex)]="currentSelectedIndex"
|
||||||
|
[nbpTabContent]="true"
|
||||||
|
>
|
||||||
</nbp-tab-bar>
|
</nbp-tab-bar>
|
||||||
|
|
||||||
<p class="new-part">Tabbar with title:</p>
|
<p class="new-part">Tabbar with title:</p>
|
||||||
|
|
||||||
<div class="nbp-tab-bar-title">
|
<div class="nbp-tab-bar-title">
|
||||||
<div class="tab-bar-title">Title:</div>
|
<div class="tab-bar-title">Title:</div>
|
||||||
<nbp-tab-bar [nbpStyle]="_nbpStyle.DEFAULT" [nbpItems]="items" [(nbpSelectedIndex)]="currentSelectedIndex"
|
<nbp-tab-bar
|
||||||
[nbpTabContent]="true">
|
[nbpStyle]="_nbpStyle.DEFAULT"
|
||||||
|
[nbpItems]="items"
|
||||||
|
[(nbpSelectedIndex)]="currentSelectedIndex"
|
||||||
|
[nbpTabContent]="true"
|
||||||
|
>
|
||||||
</nbp-tab-bar>
|
</nbp-tab-bar>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="new-part">Toggle Tabset (.nbp-tab-bar-title + .tab-bar-title + nbp-toggle-tabset) check devtools inspector
|
<p class="new-part">
|
||||||
elements:</p>
|
Toggle Tabset (.nbp-tab-bar-title + .tab-bar-title + nbp-toggle-tabset)
|
||||||
|
check devtools inspector elements:
|
||||||
|
</p>
|
||||||
<div class="nbp-tab-bar-title">
|
<div class="nbp-tab-bar-title">
|
||||||
<div class="tab-bar-title">Title:</div>
|
<div class="tab-bar-title">Title:</div>
|
||||||
<nbp-toggle-tabset>
|
<nbp-toggle-tabset>
|
||||||
@ -41,53 +50,120 @@
|
|||||||
|
|
||||||
<p class="new-part">Input text (nbp-input-container + nbp-input-text):</p>
|
<p class="new-part">Input text (nbp-input-container + nbp-input-text):</p>
|
||||||
<div>
|
<div>
|
||||||
<nbp-input-container [nbpLabel]="labelInput4" [nbpStyle]="_nbpStyle.PRIMARY" [infoText]="'Inserire un importo'">
|
<nbp-input-container
|
||||||
<nbp-input-text id="input-text-primary-3" [name]="'importoPrimary'" [(ngModel)]="importoprovaR"
|
[nbpLabel]="labelInput4"
|
||||||
nbpInputType=nbpImporto [nbpFormat]="currency" [nbpShowValidation]="true" [placeholder]="'placeholder'"
|
[nbpStyle]="_nbpStyle.PRIMARY"
|
||||||
[nbpErrorMessage]="errorMessageInput" [nbpRoundBorder]="false" [nbpStyle]="_nbpStyle.PRIMARY"
|
[infoText]="'Inserire un importo'"
|
||||||
[nbpIcon]="'ispv2-font-euro-sign'" [accessibleTextForIcon]="'euro'" [label]="labelInput4">
|
>
|
||||||
|
<nbp-input-text
|
||||||
|
id="input-text-primary-3"
|
||||||
|
[name]="'importoPrimary'"
|
||||||
|
[(ngModel)]="importoprovaR"
|
||||||
|
nbpInputType="nbpImporto"
|
||||||
|
[nbpFormat]="currency"
|
||||||
|
[nbpShowValidation]="true"
|
||||||
|
[placeholder]="'placeholder'"
|
||||||
|
[nbpErrorMessage]="errorMessageInput"
|
||||||
|
[nbpRoundBorder]="false"
|
||||||
|
[nbpStyle]="_nbpStyle.PRIMARY"
|
||||||
|
[nbpIcon]="'ispv2-font-euro-sign'"
|
||||||
|
[accessibleTextForIcon]="'euro'"
|
||||||
|
[label]="labelInput4"
|
||||||
|
>
|
||||||
</nbp-input-text>
|
</nbp-input-text>
|
||||||
</nbp-input-container>
|
</nbp-input-container>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="new-part">Calendar generic (nbp-input-container + nbp-calendar-generic)</p>
|
<p class="new-part">
|
||||||
|
Calendar generic (nbp-input-container + nbp-calendar-generic)
|
||||||
|
</p>
|
||||||
<div>
|
<div>
|
||||||
<nbp-input-container [nbpStyle]="_nbpStyle.DEFAULT" [nbpLabel]="'Default'">
|
<nbp-input-container [nbpStyle]="_nbpStyle.DEFAULT" [nbpLabel]="'Default'">
|
||||||
<nbp-calendar-generic [id]="'calendarDefault'" [name]="'calendarDefault'" [nbpStyle]="_nbpStyle.DEFAULT"
|
<nbp-calendar-generic
|
||||||
[nbpPlacement]="_nbpCalendarPosition.BOTTOM_LEFT" [nbpLabelPattern]="_nbpCalendarPattern.GGMMAAAA"
|
[id]="'calendarDefault'"
|
||||||
[(ngModel)]="calendarModel">
|
[name]="'calendarDefault'"
|
||||||
|
[nbpStyle]="_nbpStyle.DEFAULT"
|
||||||
|
[nbpPlacement]="_nbpCalendarPosition.BOTTOM_LEFT"
|
||||||
|
[nbpLabelPattern]="_nbpCalendarPattern.GGMMAAAA"
|
||||||
|
[(ngModel)]="calendarModel"
|
||||||
|
>
|
||||||
</nbp-calendar-generic>
|
</nbp-calendar-generic>
|
||||||
</nbp-input-container>
|
</nbp-input-container>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<nbp-input-container [nbpStyle]="_nbpStyle.DEFAULT" [nbpLabel]="'Default'">
|
<nbp-input-container [nbpStyle]="_nbpStyle.DEFAULT" [nbpLabel]="'Default'">
|
||||||
<nbp-calendar-generic [id]="'calendarConstrainedDateInterval'" [name]="'calendarConstrainedDateInterval'"
|
<nbp-calendar-generic
|
||||||
[nbpStyle]="_nbpStyle.DEFAULT" [nbpPlacement]="_nbpCalendarPosition.BOTTOM_RIGHT"
|
[id]="'calendarConstrainedDateInterval'"
|
||||||
[nbpLabelPattern]="_nbpCalendarPattern.GGMMAAAA" [(ngModel)]="calendarModel"
|
[name]="'calendarConstrainedDateInterval'"
|
||||||
[startDateEnabled]="startDate" [endDateEnabled]="endDate">
|
[nbpStyle]="_nbpStyle.DEFAULT"
|
||||||
|
[nbpPlacement]="_nbpCalendarPosition.BOTTOM_RIGHT"
|
||||||
|
[nbpLabelPattern]="_nbpCalendarPattern.GGMMAAAA"
|
||||||
|
[(ngModel)]="calendarModel"
|
||||||
|
[startDateEnabled]="startDate"
|
||||||
|
[endDateEnabled]="endDate"
|
||||||
|
>
|
||||||
</nbp-calendar-generic>
|
</nbp-calendar-generic>
|
||||||
</nbp-input-container>
|
</nbp-input-container>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<nbp-input-container [nbpStyle]="_nbpStyle.DEFAULT" [nbpLabel]="'Default'">
|
<nbp-input-container [nbpStyle]="_nbpStyle.DEFAULT" [nbpLabel]="'Default'">
|
||||||
<nbp-calendar-generic [id]="'calendarConstrainedDateInterval'" [name]="'calendarConstrainedDateInterval'"
|
<nbp-calendar-generic
|
||||||
[nbpStyle]="_nbpStyle.DEFAULT" [nbpPlacement]="_nbpCalendarPosition.BOTTOM_RIGHT" [disabled]="true"
|
[id]="'calendarConstrainedDateInterval'"
|
||||||
[nbpLabelPattern]="_nbpCalendarPattern.GGMMAAAA" [(ngModel)]="calendarModel"
|
[name]="'calendarConstrainedDateInterval'"
|
||||||
[startDateEnabled]="startDate" [endDateEnabled]="endDate">
|
[nbpStyle]="_nbpStyle.DEFAULT"
|
||||||
|
[nbpPlacement]="_nbpCalendarPosition.BOTTOM_RIGHT"
|
||||||
|
[disabled]="true"
|
||||||
|
[nbpLabelPattern]="_nbpCalendarPattern.GGMMAAAA"
|
||||||
|
[(ngModel)]="calendarModel"
|
||||||
|
[startDateEnabled]="startDate"
|
||||||
|
[endDateEnabled]="endDate"
|
||||||
|
>
|
||||||
</nbp-calendar-generic>
|
</nbp-calendar-generic>
|
||||||
</nbp-input-container>
|
</nbp-input-container>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<p class="new-part">
|
||||||
|
Fideuram Calendar generic (nbp-input-container + bp-fid-calendar-generic)
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<nbp-input-container [nbpStyle]="_nbpStyle.DEFAULT" [nbpLabel]="'Default'">
|
||||||
|
<nbp-fid-calendar-generic
|
||||||
|
[id]="'calendarId'"
|
||||||
|
[name]="'calendarName'"
|
||||||
|
[dateFormat]="'dd/MM/yyyy'"
|
||||||
|
[minDate]="fidMinDate"
|
||||||
|
[maxDate]="fidMaxDate"
|
||||||
|
[disabled]="false"
|
||||||
|
[(ngModel)]="fidCalendarModel"
|
||||||
|
(ngModelChange)="onDateChange($event)"
|
||||||
|
>
|
||||||
|
</nbp-fid-calendar-generic>
|
||||||
|
</nbp-input-container>
|
||||||
|
</div>
|
||||||
|
|
||||||
<p class="new-part">Combo (nbp-input-container + nbp-combo)</p>
|
<p class="new-part">Combo (nbp-input-container + nbp-combo)</p>
|
||||||
<div>
|
<div>
|
||||||
<nbp-input-container [nbpStyle]="_nbpStyle.DEFAULT" [nbpLabel]="'Default'">
|
<nbp-input-container [nbpStyle]="_nbpStyle.DEFAULT" [nbpLabel]="'Default'">
|
||||||
<nbp-combo [id]="'comboDefault'" [name]="'comboDefault'" [nbpStyle]="_nbpStyle.DEFAULT"
|
<nbp-combo
|
||||||
[nbpDataSource]="comboDatasource" [(ngModel)]="comboSelectedValue" [nbpShowEmptyValue]="true">
|
[id]="'comboDefault'"
|
||||||
|
[name]="'comboDefault'"
|
||||||
|
[nbpStyle]="_nbpStyle.DEFAULT"
|
||||||
|
[nbpDataSource]="comboDatasource"
|
||||||
|
[(ngModel)]="comboSelectedValue"
|
||||||
|
[nbpShowEmptyValue]="true"
|
||||||
|
>
|
||||||
</nbp-combo>
|
</nbp-combo>
|
||||||
</nbp-input-container>
|
</nbp-input-container>
|
||||||
<nbp-input-container [nbpStyle]="_nbpStyle.DEFAULT" [nbpLabel]="'Default'">
|
<nbp-input-container [nbpStyle]="_nbpStyle.DEFAULT" [nbpLabel]="'Default'">
|
||||||
<nbp-combo [id]="'comboDefault'" [name]="'comboDefault'" [nbpStyle]="_nbpStyle.DEFAULT"
|
<nbp-combo
|
||||||
[nbpDataSource]="comboDatasource" [(ngModel)]="comboSelectedValue" [nbpShowEmptyValue]="true" [disabled]="true">
|
[id]="'comboDefault'"
|
||||||
|
[name]="'comboDefault'"
|
||||||
|
[nbpStyle]="_nbpStyle.DEFAULT"
|
||||||
|
[nbpDataSource]="comboDatasource"
|
||||||
|
[(ngModel)]="comboSelectedValue"
|
||||||
|
[nbpShowEmptyValue]="true"
|
||||||
|
[disabled]="true"
|
||||||
|
>
|
||||||
</nbp-combo>
|
</nbp-combo>
|
||||||
</nbp-input-container>
|
</nbp-input-container>
|
||||||
</div>
|
</div>
|
||||||
@ -95,8 +171,14 @@
|
|||||||
<p class="new-part">Combo Filter (nbp-input-container + nbp-combo-filter)</p>
|
<p class="new-part">Combo Filter (nbp-input-container + nbp-combo-filter)</p>
|
||||||
<div>
|
<div>
|
||||||
<nbp-input-container [nbpStyle]="_nbpStyle.DEFAULT" [nbpLabel]="'Default'">
|
<nbp-input-container [nbpStyle]="_nbpStyle.DEFAULT" [nbpLabel]="'Default'">
|
||||||
<nbp-combo-filter [id]="'comboDefault'" [name]="'comboDefault'" [nbpStyle]="_nbpStyle.DEFAULT"
|
<nbp-combo-filter
|
||||||
[nbpDataSource]="comboDatasource" [(ngModel)]="comboSelectedValue" [nbpShowEmptyValue]="true">
|
[id]="'comboDefault'"
|
||||||
|
[name]="'comboDefault'"
|
||||||
|
[nbpStyle]="_nbpStyle.DEFAULT"
|
||||||
|
[nbpDataSource]="comboDatasource"
|
||||||
|
[(ngModel)]="comboSelectedValue"
|
||||||
|
[nbpShowEmptyValue]="true"
|
||||||
|
>
|
||||||
</nbp-combo-filter>
|
</nbp-combo-filter>
|
||||||
</nbp-input-container>
|
</nbp-input-container>
|
||||||
</div>
|
</div>
|
||||||
@ -104,31 +186,56 @@
|
|||||||
<p class="new-part">Combo Multi (nbp-input-container + nbp-combo-multi)</p>
|
<p class="new-part">Combo Multi (nbp-input-container + nbp-combo-multi)</p>
|
||||||
<div>
|
<div>
|
||||||
<nbp-input-container [nbpStyle]="_nbpStyle.DEFAULT" [nbpLabel]="'Default'">
|
<nbp-input-container [nbpStyle]="_nbpStyle.DEFAULT" [nbpLabel]="'Default'">
|
||||||
<nbp-combo-multi [id]="'comboMultiIndent'" [name]="'comboMultiIndent'" [nbpStyle]="_nbpStyle.DEFAULT"
|
<nbp-combo-multi
|
||||||
[nbpDataSource]="datasource" [(ngModel)]="selectedValues" [dropdownVisible]="comboMultiVisible">
|
[id]="'comboMultiIndent'"
|
||||||
|
[name]="'comboMultiIndent'"
|
||||||
|
[nbpStyle]="_nbpStyle.DEFAULT"
|
||||||
|
[nbpDataSource]="datasource"
|
||||||
|
[(ngModel)]="selectedValues"
|
||||||
|
[dropdownVisible]="comboMultiVisible"
|
||||||
|
>
|
||||||
</nbp-combo-multi>
|
</nbp-combo-multi>
|
||||||
</nbp-input-container>
|
</nbp-input-container>
|
||||||
|
|
||||||
<nbp-input-container [nbpStyle]="_nbpStyle.PRIMARY" [nbpLabel]="'Default'">
|
<nbp-input-container [nbpStyle]="_nbpStyle.PRIMARY" [nbpLabel]="'Default'">
|
||||||
<nbp-combo-multi [id]="'combomultiDefault'" [name]="'combomultiDefault'" [nbpStyle]="_nbpStyle.PRIMARY"
|
<nbp-combo-multi
|
||||||
[nbpDataSource]="datasource" [(ngModel)]="selectedValues">
|
[id]="'combomultiDefault'"
|
||||||
|
[name]="'combomultiDefault'"
|
||||||
|
[nbpStyle]="_nbpStyle.PRIMARY"
|
||||||
|
[nbpDataSource]="datasource"
|
||||||
|
[(ngModel)]="selectedValues"
|
||||||
|
>
|
||||||
</nbp-combo-multi>
|
</nbp-combo-multi>
|
||||||
</nbp-input-container>
|
</nbp-input-container>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="new-part">Textarea (nbp-input-container + nbp-textarea)</p>
|
<p class="new-part">Textarea (nbp-input-container + nbp-textarea)</p>
|
||||||
<div>
|
<div>
|
||||||
<nbp-input-container [nbpLabel]="'Textarea stile default'" [nbpStyle]="_nbpStyle.DEFAULT">
|
<nbp-input-container
|
||||||
<nbp-textarea [name]="'default-a'" [(ngModel)]="contenutoEmpty" [required]="required"
|
[nbpLabel]="'Textarea stile default'"
|
||||||
[placeholder]="'placeholder'" [maxlength]="lunghezzamax" [minlength]="lunghezzamin"
|
[nbpStyle]="_nbpStyle.DEFAULT"
|
||||||
[nbpStyle]="_nbpStyle.DEFAULT"></nbp-textarea>
|
>
|
||||||
|
<nbp-textarea
|
||||||
|
[name]="'default-a'"
|
||||||
|
[(ngModel)]="contenutoEmpty"
|
||||||
|
[required]="required"
|
||||||
|
[placeholder]="'placeholder'"
|
||||||
|
[maxlength]="lunghezzamax"
|
||||||
|
[minlength]="lunghezzamin"
|
||||||
|
[nbpStyle]="_nbpStyle.DEFAULT"
|
||||||
|
></nbp-textarea>
|
||||||
</nbp-input-container>
|
</nbp-input-container>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="new-part">Card (nbp-card)</p>
|
<p class="new-part">Card (nbp-card)</p>
|
||||||
<div style="width: 250px">
|
<div style="width: 250px">
|
||||||
<nbp-card [id]="'crd5'" [nbpStyle]="_nbpStyle.DEFAULT" [title]="cardTitle" [description]="cardDescr"
|
<nbp-card
|
||||||
[templateRef]="template4">
|
[id]="'crd5'"
|
||||||
|
[nbpStyle]="_nbpStyle.DEFAULT"
|
||||||
|
[title]="cardTitle"
|
||||||
|
[description]="cardDescr"
|
||||||
|
[templateRef]="template4"
|
||||||
|
>
|
||||||
</nbp-card>
|
</nbp-card>
|
||||||
<ng-template #template4>
|
<ng-template #template4>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -145,16 +252,31 @@
|
|||||||
|
|
||||||
<p class="new-part">Table (nbp-table)</p>
|
<p class="new-part">Table (nbp-table)</p>
|
||||||
<div>
|
<div>
|
||||||
<nbp-table [scrollBar]="'auto'" ariaLabel="table" [nbpId]="'defTable1'" [nbpOptions]="tableOptions"
|
<nbp-table
|
||||||
[nbpDataSource]="tableDs" [nbpAutoBind]="true" [nbpSelectionType]="tableSelectionType"
|
[scrollBar]="'auto'"
|
||||||
[nbpLayoutAuto]="true">
|
ariaLabel="table"
|
||||||
|
[nbpId]="'defTable1'"
|
||||||
<nbp-table-column nbpId='headerField' nbpTitle='Header field' nbpField='headerField'
|
[nbpOptions]="tableOptions"
|
||||||
[nbpVisible]='true'>
|
[nbpDataSource]="tableDs"
|
||||||
|
[nbpAutoBind]="true"
|
||||||
|
[nbpSelectionType]="tableSelectionType"
|
||||||
|
[nbpLayoutAuto]="true"
|
||||||
|
>
|
||||||
|
<nbp-table-column
|
||||||
|
nbpId="headerField"
|
||||||
|
nbpTitle="Header field"
|
||||||
|
nbpField="headerField"
|
||||||
|
[nbpVisible]="true"
|
||||||
|
>
|
||||||
</nbp-table-column>
|
</nbp-table-column>
|
||||||
|
|
||||||
<nbp-table-column nbpId='headerField2' nbpTitle='Header field 2' nbpField='headerField2'
|
<nbp-table-column
|
||||||
[nbpSortable]="true" [nbpVisible]='true'>
|
nbpId="headerField2"
|
||||||
|
nbpTitle="Header field 2"
|
||||||
|
nbpField="headerField2"
|
||||||
|
[nbpSortable]="true"
|
||||||
|
[nbpVisible]="true"
|
||||||
|
>
|
||||||
</nbp-table-column>
|
</nbp-table-column>
|
||||||
</nbp-table>
|
</nbp-table>
|
||||||
</div>
|
</div>
|
||||||
@ -162,22 +284,42 @@
|
|||||||
<p class="new-part">Tree-table</p>
|
<p class="new-part">Tree-table</p>
|
||||||
<div>
|
<div>
|
||||||
<!-- [paginationOptions]="table2PageConfig" -->
|
<!-- [paginationOptions]="table2PageConfig" -->
|
||||||
<isp-turbo-table [columns]="table2Columns" [datasource]="table2Data" [hasAccordionRows]="true"
|
<isp-turbo-table
|
||||||
[rowExpander]="table2RowExpander" tableMinWidth='35rem' ariaLabel="table with children"></isp-turbo-table>
|
[columns]="table2Columns"
|
||||||
|
[datasource]="table2Data"
|
||||||
|
[hasAccordionRows]="true"
|
||||||
|
[rowExpander]="table2RowExpander"
|
||||||
|
tableMinWidth="35rem"
|
||||||
|
ariaLabel="table with children"
|
||||||
|
></isp-turbo-table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="new-part">Checkbox-table</p>
|
<p class="new-part">Checkbox-table</p>
|
||||||
<nbp-table [scrollBar]="'auto'" [nbpId]="'defTable'" [nbpOptions]="simpleOptions"
|
<nbp-table
|
||||||
[nbpDataSource]="campiStandardData" ariaLabel="multi selection table" [nbpAutoBind]="true"
|
[scrollBar]="'auto'"
|
||||||
[nbpSelectionType]="multi">
|
[nbpId]="'defTable'"
|
||||||
|
[nbpOptions]="simpleOptions"
|
||||||
<nbp-table-column nbpId='headerField' nbpTitle='Header field' nbpField='headerField'
|
[nbpDataSource]="campiStandardData"
|
||||||
[nbpSortable]='true' [nbpVisible]='true'>
|
ariaLabel="multi selection table"
|
||||||
|
[nbpAutoBind]="true"
|
||||||
|
[nbpSelectionType]="multi"
|
||||||
|
>
|
||||||
|
<nbp-table-column
|
||||||
|
nbpId="headerField"
|
||||||
|
nbpTitle="Header field"
|
||||||
|
nbpField="headerField"
|
||||||
|
[nbpSortable]="true"
|
||||||
|
[nbpVisible]="true"
|
||||||
|
>
|
||||||
</nbp-table-column>
|
</nbp-table-column>
|
||||||
|
|
||||||
<nbp-table-column nbpId='headerField2' nbpTitle='Header field 2' nbpField='headerField2'
|
<nbp-table-column
|
||||||
[nbpSortable]='true' [nbpVisible]='true'>
|
nbpId="headerField2"
|
||||||
|
nbpTitle="Header field 2"
|
||||||
|
nbpField="headerField2"
|
||||||
|
[nbpSortable]="true"
|
||||||
|
[nbpVisible]="true"
|
||||||
|
>
|
||||||
</nbp-table-column>
|
</nbp-table-column>
|
||||||
|
|
||||||
</nbp-table>
|
</nbp-table>
|
||||||
</div>
|
</div>
|
@ -43,6 +43,19 @@ export class Showcase1Component extends NbpBaseComponent {
|
|||||||
|
|
||||||
startDate: NgbDateStruct = { year: 2023, month: 3, day: 15 };
|
startDate: NgbDateStruct = { year: 2023, month: 3, day: 15 };
|
||||||
endDate: NgbDateStruct = { year: 2023, month: 8, day: 15 };
|
endDate: NgbDateStruct = { year: 2023, month: 8, day: 15 };
|
||||||
|
|
||||||
|
// FIDEURAM CALENDAR GENERIC
|
||||||
|
fidCalendarModel: Date = null;
|
||||||
|
|
||||||
|
// Date di limite per l'esempio min/max
|
||||||
|
fidMinDate: Date = new Date(2025, 4, 1); // 1 maggio 2025
|
||||||
|
fidMaxDate: Date = new Date(2025, 5, 30); // 30 giugno 2025
|
||||||
|
|
||||||
|
// Range di date disabilitate per l'esempio
|
||||||
|
fidDisabledDateRanges: { start: Date, end: Date }[] = [
|
||||||
|
{ start: new Date(2025, 4, 10), end: new Date(2025, 5, 15) }, // 10-15 maggio 2025
|
||||||
|
{ start: new Date(2025, 4, 25), end: new Date(2025, 4, 28) } // 25-28 maggio 2025
|
||||||
|
];
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -192,6 +205,12 @@ export class Showcase1Component extends NbpBaseComponent {
|
|||||||
array = array.map(convertPageToRowModel);
|
array = array.map(convertPageToRowModel);
|
||||||
this.table2Data.setData(array, pageNumber, sortField, pageSize);
|
this.table2Data.setData(array, pageNumber, sortField, pageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Metodo per gestire il cambio di data nel calendario Fideuram
|
||||||
|
onDateChange(date: Date): void {
|
||||||
|
console.log('Data selezionata:', date);
|
||||||
|
// Puoi aggiungere qui la logica per gestire il cambio di data
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RowExpanderTreeExpandedTest implements RowDataExpander {
|
export class RowExpanderTreeExpandedTest implements RowDataExpander {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user