<div th:fragment="date-input" class="datepicker-container">
<input type="text" class="date-input" placeholder="Select date" />
<div class="datepicker">
<div class="datepicker-header">
<i class="prev ki-outline ki-left"></i>
<div>
<span class="month-input">January</span>
<span class="year">2024</span>
</div>
<i class="next ki-outline ki-right"></i>
</div>
<div class="days">
<span>Sun</span>
<span>Mon</span>
<span>Tue</span>
<span>Wed</span>
<span>Thu</span>
<span>Fri</span>
<span>Sat</span>
</div>
<div class="dates"></div>
<div class="datepicker-footer">
<button class="cancel">Cancel</button>
<button class="apply">Apply</button>
</div>
</div>
</div>
SCSS:
.datepicker-container {
position: relative;
.date-input {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
.datepicker {
position: absolute;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 8px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
padding: 20px;
z-index: 999;
display: none;
.datepicker-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
.month-input {
font-size: 18px;
font-weight: bold;
cursor: pointer;
}
.prev, .next {
background: none;
border: none;
font-size: 18px;
cursor: pointer;
padding: 5px;
}
}
.days {
display: grid;
grid-template-columns: repeat(7, 1fr);
grid-gap: 10px;
font-weight: bold;
margin-bottom: 10px;
span {
text-align: center;
}
}
.dates {
display: grid;
grid-template-columns: repeat(7, 1fr);
grid-gap: 10px;
button {
background-color: transparent;
border: none;
font-size: 16px;
padding: 8px;
cursor: pointer;
&.today {
color: red;
font-weight: bold;
}
&.selected {
background-color: #007bff;
color: white;
border-radius: 50%;
}
&:disabled {
color: #ccc;
cursor: not-allowed;
}
&:hover:not(:disabled) {
background-color: #f0f0f0;
}
}
}
.datepicker-footer {
display: flex;
justify-content: space-between;
margin-top: 15px;
button {
padding: 5px 10px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
&:hover {
background-color: #0056b3;
}
}
}
.month-selection {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 10px;
padding: 10px;
background-color: #fff;
border: 1px solid #ccc;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
border-radius: 8px;
z-index: 9999;
button {
background: none;
border: 1px solid #007bff;
padding: 8px;
cursor: pointer;
&.selected {
background-color: #007bff;
color: white;
}
&:hover {
background-color: #f0f0f0;
}
}
}
}
}
.today {
background-color: gray;
color: white;
border-radius: 50%;
}
.selected {
background-color: green;
color: white;
border-radius: 50%;
}
.current-month {
background-color: gray;
color: white;
border-radius: 50%;
}
.selected-month {
background-color: green;
color: white;
border-radius: 50%;
}
JQUERY JS:
$(document).ready(function () {
const datepicker = $(".datepicker");
const dateInput = $(".date-input");
const monthInput = $(".month-input");
const yearInput = $(".year");
const cancelBtn = $(".cancel");
const applyBtn = $(".apply");
const nextBtn = $(".next");
const prevBtn = $(".prev");
const dates = $(".dates");
let activeInput = null;
let selectedDate = new Date();
let year = selectedDate.getFullYear();
let month = selectedDate.getMonth();
let isMonthPickerOpen = false;
dateInput.on("click", function () {
activeInput = $(this);
const rect = activeInput[0].getBoundingClientRect();
datepicker.css({
top: `${rect.bottom + window.scrollY + 10}px`,
left: `${rect.left + window.scrollX}px`,
});
selectedDate = new Date(activeInput.data("date") || new Date());
year = selectedDate.getFullYear();
month = selectedDate.getMonth();
displayDates();
datepicker.show();
});
cancelBtn.on("click", function () {
datepicker.hide();
});
applyBtn.on("click", function () {
if (activeInput) {
activeInput.val(selectedDate.toLocaleDateString("cs-CZ", {
year: "numeric",
month: "2-digit",
day: "2-digit",
}));
activeInput.data("date", selectedDate);
}
datepicker.hide();
});
nextBtn.on("click", function () {
if (month === 11) {
year++;
}
month = (month + 1) % 12;
displayDates();
});
prevBtn.on("click", function () {
if (month === 0) {
year--;
}
month = (month - 1 + 12) % 12;
displayDates();
});
monthInput.on("click", function () {
isMonthPickerOpen = !isMonthPickerOpen;
if (isMonthPickerOpen) {
displayMonthPicker();
} else {
displayDates();
}
});
const updateMonthYear = () => {
monthInput.text(new Date(year, month).toLocaleString('default', { month: 'long' }));
yearInput.text(year);
};
const handleMonthPick = function () {
month = $(this).data("month");
isMonthPickerOpen = false;
displayDates();
};
const createMonthButton = (monthName, monthIndex) => {
const button = $("<button>").text(monthName).data("month", monthIndex).on("click", handleMonthPick);
return button;
};
const displayMonthPicker = () => {
dates.empty();
const months = [
"Leden", "únor", "Březen", "Duben", "Květen", "Červen",
"Červenec", "Srpen", "Září", "Říjen", "Listopad", "Prosinec"
];
months.forEach((monthName, index) => {
const button = createMonthButton(monthName, index);
if (index === new Date().getMonth()) {
button.addClass("current-month");
}
if (index === month) {
button.addClass("selected-month");
}
dates.append(button);
});
};
const createButton = (text, isDisabled = false, type = 0) => {
const currentDate = new Date();
let comparisonDate = new Date(year, month + type, text);
const isToday = currentDate.getDate() === text && currentDate.getFullYear() === year && currentDate.getMonth() === month;
const selected = selectedDate.getTime() === comparisonDate.getTime();
const button = $("<button>").text(text).prop("disabled", isDisabled)
.addClass(isToday && !isDisabled ? "today" : "")
.addClass(selected ? "selected" : "");
return button;
};
const displayDates = () => {
updateMonthYear();
dates.empty();
if (isMonthPickerOpen) {
displayMonthPicker();
return;
}
const lastOfPrevMonth = new Date(year, month, 0);
for (let i = 0; i <= lastOfPrevMonth.getDay(); i++) {
const text = lastOfPrevMonth.getDate() - lastOfPrevMonth.getDay() + i;
const button = createButton(text, true, -1);
dates.append(button);
}
const lastOfMonth = new Date(year, month + 1, 0);
for (let i = 1; i <= lastOfMonth.getDate(); i++) {
const button = createButton(i, false);
button.on("click", function () {
const button = $(this);
dates.find(".selected").removeClass("selected");
button.addClass("selected");
selectedDate = new Date(year, month, parseInt(button.text()));
});
dates.append(button);
}
const firstOfNextMonth = new Date(year, month + 1, 1);
for (let i = firstOfNextMonth.getDay(); i < 7; i++) {
const text = firstOfNextMonth.getDate() - firstOfNextMonth.getDay() + i;
const button = createButton(text, true, 1);
dates.append(button);
}
};
displayDates();
});
У меня не совсем получаеться сделать. В низу изображения как я представляю функционал. Когда я кликаю на input показивается date picker, серым цветом показывается текущый день/месяц, зеленым показывается выбраный день/месяц. Когда открыт выбор месяца то кнопки prev/next меняют год, когда открыт выбор даты то кнопки prev/next меняют месяц. Буду признателен за помощь.