fideuram sync commits
This commit is contained in:
parent
28c94936d6
commit
aef2744548
@ -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,
|
||||||
|
@ -53,6 +53,7 @@ export { DATE_STRING_FORMAT, formatDate, formatNumber, setSpinnerMessage, clearS
|
|||||||
NbpModule,
|
NbpModule,
|
||||||
AgGridModule,
|
AgGridModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
NbpBreadCrumbsComponent,
|
NbpBreadCrumbsComponent,
|
||||||
|
@ -1,583 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="it">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
|
||||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600&display=swap" rel="stylesheet">
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Datepicker Multi-Livello</title>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: 'Open Sans', Arial, sans-serif;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
margin-top: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
body * {
|
|
||||||
font-family: 'Open Sans', Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.datepicker-input::placeholder {
|
|
||||||
color: #909fa7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.datepicker-input:focus {
|
|
||||||
border-color: #66afe9;
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="datepicker-wrapper">
|
|
||||||
<input id="dateInput" class="datepicker-input" type="text" placeholder="DD/MM/YYYY" />
|
|
||||||
<i id="calendarIcon" class="datepicker-icon fa fa-calendar"></i>
|
|
||||||
<div class="calendar calendar-popup" id="calendarPopup"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
|
||||||
// Utility per posizionare il popup sotto l'input
|
|
||||||
function positionCalendarPopup() {
|
|
||||||
const input = document.getElementById('dateInput');
|
|
||||||
const popup = document.getElementById('calendarPopup');
|
|
||||||
// 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';
|
|
||||||
// popup.style.minWidth = rect.width + 'px';
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- CONFIGURAZIONE FORMATO DATA ---
|
|
||||||
let dateFormat = 'dd/MM/yyyy'; // Cambia qui il formato come preferisci
|
|
||||||
|
|
||||||
// --- ELEMENTI ---
|
|
||||||
const calendarPopup = document.getElementById("calendarPopup");
|
|
||||||
const dateInput = document.getElementById("dateInput");
|
|
||||||
// Questi saranno definiti dopo il rendering del calendario:
|
|
||||||
let calendarEl, monthYearEl;
|
|
||||||
|
|
||||||
let currentDate = new Date();
|
|
||||||
let selectedDate = null;
|
|
||||||
let view = 'days'; // 'days' | 'months' | 'years'
|
|
||||||
|
|
||||||
// CONFIGURAZIONE: giorni della settimana da disabilitare (0=domenica, 6=sabato)
|
|
||||||
const disabledWeekdays = [0, 6]; // es: weekend
|
|
||||||
// CONFIGURAZIONE: range di date da disabilitare (array di oggetti {start, end})
|
|
||||||
const disabledDateRanges = [
|
|
||||||
{ start: new Date(2025, 4, 10), end: new Date(2025, 4, 15) }, // 10-15 maggio 2025
|
|
||||||
// aggiungi altri range se necessario
|
|
||||||
];
|
|
||||||
|
|
||||||
// --- FORMATTAZIONE DATA ---
|
|
||||||
function pad(n) {
|
|
||||||
return n < 10 ? '0' + n : n;
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatDate(date, format) {
|
|
||||||
if (!date) return '';
|
|
||||||
const pad = n => n < 10 ? '0' + n : n;
|
|
||||||
return format
|
|
||||||
.replace('dd', pad(date.getDate()))
|
|
||||||
.replace('MM', pad(date.getMonth() + 1))
|
|
||||||
.replace('yyyy', date.getFullYear())
|
|
||||||
.replace('yy', String(date.getFullYear()).slice(-2));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- MOSTRA/NASCONDI CALENDARIO ---
|
|
||||||
function showCalendar() {
|
|
||||||
positionCalendarPopup();
|
|
||||||
renderCalendar();
|
|
||||||
setTimeout(() => {
|
|
||||||
document.addEventListener('mousedown', onClickOutside);
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleCalendar() {
|
|
||||||
if (calendarPopup.style.display === 'block') {
|
|
||||||
hideCalendar();
|
|
||||||
} else {
|
|
||||||
showCalendar();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function hideCalendar() {
|
|
||||||
calendarPopup.style.display = 'none';
|
|
||||||
document.removeEventListener('mousedown', onClickOutside);
|
|
||||||
|
|
||||||
if (selectedDate) {
|
|
||||||
currentDate = new Date(selectedDate);
|
|
||||||
} else {
|
|
||||||
currentDate = new Date();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function onClickOutside(e) {
|
|
||||||
if (!calendarPopup.contains(e.target) && e.target !== dateInput && e.target !== document.getElementById('calendarIcon')) {
|
|
||||||
hideCalendar();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- SOVRASCRIVI RENDERING ---
|
|
||||||
function renderCalendar() {
|
|
||||||
// Gestione classi view-* su calendarPopup
|
|
||||||
calendarPopup.classList.remove('view-days', 'view-months', 'view-years');
|
|
||||||
if (view === 'days') calendarPopup.classList.add('view-days');
|
|
||||||
else if (view === 'months') calendarPopup.classList.add('view-months');
|
|
||||||
else if (view === 'years') calendarPopup.classList.add('view-years');
|
|
||||||
calendarPopup.innerHTML = `<div class='calendar-header'><button id='prevBtn' class="calendar-cell fa fa-chevron-left"></button><div id='monthYear' class="calendar-cell"></div><button id='nextBtn' class="calendar-cell fa fa-chevron-right"></button></div><div class='calendar-grid' id='calendar'></div><div class='calendar-actions'><button id='todayBtn'>Oggi</button><button id='clearBtn'>Cancella</button><button id='confirmBtn'>Conferma</button></div>`;
|
|
||||||
calendarEl = document.getElementById("calendar");
|
|
||||||
monthYearEl = document.getElementById("monthYear");
|
|
||||||
if (view === 'days') renderDays();
|
|
||||||
else if (view === 'months') renderMonths();
|
|
||||||
else renderYears();
|
|
||||||
// Eventi header e azioni
|
|
||||||
document.getElementById('prevBtn').onclick = prev;
|
|
||||||
document.getElementById('nextBtn').onclick = next;
|
|
||||||
document.getElementById('todayBtn').onclick = goToday;
|
|
||||||
document.getElementById('clearBtn').onclick = clearSelection;
|
|
||||||
document.getElementById('confirmBtn').onclick = confirmDate;
|
|
||||||
monthYearEl.onclick = changeView;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- LOGICA MODIFICATA: disabilita tutte le date inferiori al 9/05/2025 ---
|
|
||||||
function isDateDisabled(date) {
|
|
||||||
const minDate = new Date(2025, 4, 9, 0, 0, 0, 0); // 9 maggio 2025
|
|
||||||
if (date < minDate) return true;
|
|
||||||
// Disabilita per giorno della settimana
|
|
||||||
if (disabledWeekdays.includes(date.getDay())) return true;
|
|
||||||
// Disabilita per range
|
|
||||||
for (const range of disabledDateRanges) {
|
|
||||||
if (date >= range.start && date <= range.end) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderDays() {
|
|
||||||
calendarEl.classList.add('calendar-grid-7');
|
|
||||||
const months = ['gennaio', 'febbraio', 'marzo', 'aprile', 'maggio', 'giugno', 'luglio', 'agosto', 'settembre', 'ottobre', 'novembre', 'dicembre'];
|
|
||||||
const daysOfWeek = ['lun', 'mar', 'mer', 'gio', 'ven', 'sab', 'dom'];
|
|
||||||
monthYearEl.textContent = `${months[currentDate.getMonth()]} ${currentDate.getFullYear()}`;
|
|
||||||
|
|
||||||
// Intestazione dei giorni della settimana
|
|
||||||
for (let day of daysOfWeek) {
|
|
||||||
const div = document.createElement("div");
|
|
||||||
div.classList.add("day");
|
|
||||||
div.textContent = day;
|
|
||||||
calendarEl.appendChild(div);
|
|
||||||
}
|
|
||||||
|
|
||||||
const year = currentDate.getFullYear();
|
|
||||||
const month = currentDate.getMonth();
|
|
||||||
|
|
||||||
const firstDayOfMonth = new Date(year, month, 1);
|
|
||||||
const startDay = (firstDayOfMonth.getDay() + 6) % 7; // Luned<65>=0, Domenica=6
|
|
||||||
|
|
||||||
const daysInCurrentMonth = new Date(year, month + 1, 0).getDate();
|
|
||||||
const daysInPrevMonth = new Date(year, month, 0).getDate();
|
|
||||||
|
|
||||||
// Giorni del mese precedente
|
|
||||||
for (let i = startDay; i > 0; i--) {
|
|
||||||
const day = daysInPrevMonth - i + 1;
|
|
||||||
const div = document.createElement("div");
|
|
||||||
div.textContent = pad(day);
|
|
||||||
div.classList.add("other-month");
|
|
||||||
div.classList.add("calendar-cell");
|
|
||||||
|
|
||||||
const prevMonthDate = new Date(year, month - 1, day);
|
|
||||||
if (isDateDisabled(prevMonthDate)) {
|
|
||||||
div.classList.add("disabled");
|
|
||||||
} else {
|
|
||||||
div.onclick = () => {
|
|
||||||
currentDate.setMonth(month - 1);
|
|
||||||
selectedDate = prevMonthDate;
|
|
||||||
dateInput.value = formatDate(selectedDate, dateFormat); // aggiorna subito input
|
|
||||||
renderCalendar();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
calendarEl.appendChild(div);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Giorni del mese corrente
|
|
||||||
for (let i = 1; i <= daysInCurrentMonth; i++) {
|
|
||||||
const div = document.createElement("div");
|
|
||||||
div.textContent = pad(i);
|
|
||||||
div.classList.add("calendar-cell");
|
|
||||||
const thisDate = new Date(year, month, i);
|
|
||||||
if (selectedDate && sameDate(selectedDate, thisDate)) div.classList.add("selected");
|
|
||||||
if (sameDate(new Date(), thisDate)) div.classList.add("today");
|
|
||||||
if (isDateDisabled(thisDate)) {
|
|
||||||
div.classList.add("disabled");
|
|
||||||
} else {
|
|
||||||
div.onclick = () => {
|
|
||||||
selectedDate = thisDate;
|
|
||||||
dateInput.value = formatDate(selectedDate, dateFormat); // aggiorna subito input
|
|
||||||
renderCalendar();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
calendarEl.appendChild(div);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Giorni del mese successivo
|
|
||||||
const totalCells = 42; // 7 giorni x 6 settimane
|
|
||||||
const filledCells = startDay + daysInCurrentMonth;
|
|
||||||
const nextMonthDays = totalCells - filledCells;
|
|
||||||
for (let i = 1; i <= nextMonthDays; i++) {
|
|
||||||
const div = document.createElement("div");
|
|
||||||
div.textContent = pad(i);
|
|
||||||
div.classList.add("other-month");
|
|
||||||
div.classList.add("calendar-cell");
|
|
||||||
const nextMonthDate = new Date(year, month + 1, i);
|
|
||||||
if (isDateDisabled(nextMonthDate)) {
|
|
||||||
div.classList.add("disabled");
|
|
||||||
} else {
|
|
||||||
div.onclick = () => {
|
|
||||||
currentDate.setMonth(month + 1);
|
|
||||||
selectedDate = nextMonthDate;
|
|
||||||
dateInput.value = formatDate(selectedDate, dateFormat); // aggiorna subito input
|
|
||||||
renderCalendar();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
calendarEl.appendChild(div);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderMonths() {
|
|
||||||
const months = ['gennaio', 'febbraio', 'marzo', 'aprile', 'maggio', 'giugno', 'luglio', 'agosto', 'settembre', 'ottobre', 'novembre', 'dicembre'];
|
|
||||||
monthYearEl.textContent = currentDate.getFullYear();
|
|
||||||
months.forEach((m, idx) => {
|
|
||||||
const div = document.createElement("div");
|
|
||||||
div.textContent = m;
|
|
||||||
div.classList.add("calendar-cell");
|
|
||||||
const now = new Date();
|
|
||||||
if (currentDate.getFullYear() === now.getFullYear() && idx === now.getMonth()) {
|
|
||||||
div.classList.add("today");
|
|
||||||
}
|
|
||||||
// Aggiungi la classe 'selected' se il mese corrisponde a selectedDate
|
|
||||||
if (selectedDate && currentDate.getFullYear() === selectedDate.getFullYear() && idx === selectedDate.getMonth()) {
|
|
||||||
div.classList.add("selected");
|
|
||||||
}
|
|
||||||
// Disabilita mese se tutto il mese è inferiore alla data minima
|
|
||||||
const minDate = new Date(2025, 4, 9, 0, 0, 0, 0);
|
|
||||||
const firstDay = new Date(currentDate.getFullYear(), idx, 1);
|
|
||||||
const lastDay = new Date(currentDate.getFullYear(), idx + 1, 0, 23, 59, 59, 999);
|
|
||||||
let disableMonth = lastDay < minDate;
|
|
||||||
if (disableMonth) {
|
|
||||||
div.classList.add("disabled");
|
|
||||||
} else {
|
|
||||||
div.onclick = () => {
|
|
||||||
currentDate.setMonth(idx);
|
|
||||||
view = 'days';
|
|
||||||
renderCalendar();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
calendarEl.appendChild(div);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderYears() {
|
|
||||||
calendarEl.classList.remove('calendar-grid-7');
|
|
||||||
calendarEl.classList.add('calendar-grid-5');
|
|
||||||
// 20 anni, 5x4
|
|
||||||
const base = Math.floor(currentDate.getFullYear() / 20) * 20;
|
|
||||||
monthYearEl.textContent = `${base} - ${base + 19}`;
|
|
||||||
for (let y = base; y < base + 20; y++) {
|
|
||||||
const div = document.createElement("div");
|
|
||||||
div.textContent = y;
|
|
||||||
div.classList.add("calendar-cell");
|
|
||||||
if (y === new Date().getFullYear()) div.classList.add("today");
|
|
||||||
if (selectedDate && y === selectedDate.getFullYear()) div.classList.add("selected");
|
|
||||||
// Disabilita anno se tutto l'anno è inferiore alla data minima
|
|
||||||
const minDate = new Date(2025, 4, 9, 0, 0, 0, 0);
|
|
||||||
const lastDayOfYear = new Date(y, 11, 31, 23, 59, 59, 999);
|
|
||||||
let disableYear = lastDayOfYear < minDate;
|
|
||||||
if (disableYear) {
|
|
||||||
div.classList.add("disabled");
|
|
||||||
} else {
|
|
||||||
div.onclick = () => {
|
|
||||||
currentDate.setFullYear(y);
|
|
||||||
view = 'months';
|
|
||||||
renderCalendar();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
calendarEl.appendChild(div);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeView() {
|
|
||||||
if (view === 'days') view = 'months';
|
|
||||||
else if (view === 'months') view = 'years';
|
|
||||||
renderCalendar();
|
|
||||||
}
|
|
||||||
|
|
||||||
function prev() {
|
|
||||||
if (view === 'days') currentDate.setMonth(currentDate.getMonth() - 1);
|
|
||||||
else if (view === 'months') currentDate.setFullYear(currentDate.getFullYear() - 1);
|
|
||||||
else currentDate.setFullYear(currentDate.getFullYear() - 20);
|
|
||||||
renderCalendar();
|
|
||||||
}
|
|
||||||
|
|
||||||
function next() {
|
|
||||||
if (view === 'days') currentDate.setMonth(currentDate.getMonth() + 1);
|
|
||||||
else if (view === 'months') currentDate.setFullYear(currentDate.getFullYear() + 1);
|
|
||||||
else currentDate.setFullYear(currentDate.getFullYear() + 20);
|
|
||||||
renderCalendar();
|
|
||||||
}
|
|
||||||
|
|
||||||
function goToday() {
|
|
||||||
currentDate = new Date();
|
|
||||||
selectedDate = new Date();
|
|
||||||
dateInput.value = formatDate(selectedDate, dateFormat);
|
|
||||||
view = 'days';
|
|
||||||
renderCalendar();
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearSelection() {
|
|
||||||
selectedDate = null;
|
|
||||||
dateInput.value = '';
|
|
||||||
renderCalendar();
|
|
||||||
}
|
|
||||||
|
|
||||||
function confirmDate() {
|
|
||||||
hideCalendar();
|
|
||||||
}
|
|
||||||
|
|
||||||
function sameDate(d1, d2) {
|
|
||||||
return d1.getFullYear() === d2.getFullYear() &&
|
|
||||||
d1.getMonth() === d2.getMonth() &&
|
|
||||||
d1.getDate() === d2.getDate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inizializza input (opzionale: mostra la data di oggi)
|
|
||||||
dateInput.value = selectedDate ? formatDate(selectedDate, dateFormat) : '';
|
|
||||||
// Eventi su input e icona
|
|
||||||
|
|
||||||
// Permetti inserimento manuale della data
|
|
||||||
document.getElementById('dateInput').addEventListener('input', function (e) {
|
|
||||||
const value = e.target.value;
|
|
||||||
// Regex base per dd/MM/yyyy
|
|
||||||
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 (!isDateDisabled(date)) {
|
|
||||||
selectedDate = date;
|
|
||||||
currentDate = new Date(date);
|
|
||||||
dateInput.value = formatDate(selectedDate, dateFormat);
|
|
||||||
dateInput.classList.remove('input-error');
|
|
||||||
renderCalendar();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Se non valido, evidenzia errore
|
|
||||||
dateInput.classList.add('input-error');
|
|
||||||
});
|
|
||||||
document.getElementById('calendarIcon').addEventListener('click', toggleCalendar);
|
|
||||||
// Espone showCalendar globalmente solo se serve (compatibilità)
|
|
||||||
window.showCalendar = showCalendar;
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -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,7 +120,10 @@ export class NbpFidComboComponent extends NbpBaseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this._readOptions();
|
if (!this.name) {
|
||||||
|
this.name = "combo_" + (comboIndex++);
|
||||||
|
}
|
||||||
|
this._readOptions(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
optStrValue(opt: any) {
|
optStrValue(opt: any) {
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user