jQuery UI Datepicker日期格式失效、回显异常及整月禁用问题咨询
Hey there! Let's work through your three Datepicker problems step by step—they're all common hurdles when customizing datepickers for year/month-only selection, so we'll get them sorted.
1. Thymeleaf Date Format Not Applying on Load
When loading dates from the database via Thymeleaf, your Datepicker's dateFormat isn't kicking in because the raw Date object is being rendered with Thymeleaf's default yyyy-MM-dd format.
Solution: Format the date directly in Thymeleaf before rendering it into the input field. Use Thymeleaf's date utility to output exactly the format your Datepicker expects (e.g., yyyy-MM):
<input type="text" class="datepickerSchedule" th:value="${#dates.format(yourDateModel, 'yyyy-MM')}" />
This way, the input starts with a string that matches your Datepicker's dateFormat, so it won't fall back to the full yyyy-MM-dd format. Replace yourDateModel with your actual Date-type model attribute.
2. Datepicker Doesn't Recognize Existing Dates with "yy-mm" or "mm-yy" Format
The issue here is that Datepicker can't parse a full yyyy-MM-dd string when your dateFormat only includes year and month. If your input has 2017-11-01 but your Datepicker is set to yy-mm, it won't map correctly, leading to it defaulting to the current month.
Fix:
- First, ensure the input value is stripped of the day component (as we did in the Thymeleaf step above) so it's just
2017-11. - If you need to handle cases where the input might still have a day, add an initialization step to parse and set the date correctly:
$(".datepickerSchedule").each(function() { const inputVal = $(this).val(); if (inputVal) { // Split the date string (handles both "yyyy-mm-dd" and "yyyy-mm") const parts = inputVal.split('-'); const year = parseInt(parts[0]); const month = parseInt(parts[1]) - 1; // Convert to 0-based for Date object $(this).datepicker('setDate', new Date(year, month, 1)); } }).datepicker({ // Your existing options here: showOn, changeMonth, changeYear, etc. dateFormat: "yy-mm", // ... rest of your config });
This ensures Datepicker starts with the correct month/year instead of defaulting to today.
3. Disabling Entire Months
To disable an entire month (not just specific dates), you can combine two Datepicker hooks: beforeShowDay to disable all days in the forbidden month, and onChangeMonthYear to block users from selecting the forbidden month via the dropdowns.
Example Code:
// Define forbidden months (year, 0-based month) const forbiddenMonths = [ { year: 2024, month: 2 }, // March 2024 { year: 2023, month: 11 } // December 2023 ]; $(".datepickerSchedule").datepicker({ // Your existing options here beforeShowDay: function(date) { // Check if the date falls in any forbidden month const isForbidden = forbiddenMonths.some(month => date.getFullYear() === month.year && date.getMonth() === month.month ); // Return [false, class] to disable the day, [true, ''] to enable return isForbidden ? [false, 'ui-disabled-month'] : [true, '']; }, onChangeMonthYear: function(year, month, inst) { // Convert month to 0-based to match our forbiddenMonths array const zeroBasedMonth = month - 1; const isForbidden = forbiddenMonths.some(m => m.year === year && m.month === zeroBasedMonth ); if (isForbidden) { // Revert to the previous valid date (or current date if none exists) const currentDate = $(this).datepicker('getDate') || new Date(); $(this).datepicker('setDate', currentDate); alert('This month is disabled and cannot be selected.'); } }, // ... rest of your existing config });
- The
beforeShowDayhook disables every day in the forbidden months, making them unclickable on the calendar. - The
onChangeMonthYearhook prevents users from selecting the forbidden month via the dropdowns by reverting to a valid date and showing a message.
You can style the disabled days with CSS using the ui-disabled-month class to make them visually distinct (e.g., grayed out).
内容的提问来源于stack exchange,提问作者kyrpav

