如何配置InfiniteCalendar以仅允许选择当月周末日期(周五、周六、周日)
Hey there! Let's work through your problem step by step. First, we'll fix the gaps in your current code and implement logic to block all dates except Fridays, Saturdays, and Sundays within the current month.
Step 1: Fix the Max Date Calculation
Your current maxDate uses date + 30, which isn't reliable (since months have varying days). Instead, calculate the last day of the current month accurately with this snippet:
const lastDayOfMonth = new Date(year, month + 1, 0).getDate(); const maxDate = new Date(year, month, lastDayOfMonth);
This ensures you never go beyond the actual end of the month, no matter if it's February or December.
Step 2: Create a Date Validation Helper
We need a function to check if a given date falls on a Friday, Saturday, or Sunday. Remember in JavaScript, Date.getDay() returns:
- 0 = Sunday
- 5 = Friday
- 6 = Saturday
Add this helper inside your component:
const isWeekendDate = (date) => { const day = date.getDay(); // Return true if it's Friday, Saturday, or Sunday return day === 0 || day === 5 || day === 6; };
Step 3: Configure InfiniteCalendar to Disable Non-Weekend Dates
InfiniteCalendar provides the isDateDisabled prop, which lets you define a callback to mark dates as unselectable. We'll use our helper function here, plus add a safeguard to ensure dates stay within the current month (even though minDate and maxDate already handle this):
const isDateDisabled = (date) => { const isOutsideMonth = date.getMonth() !== month || date.getFullYear() !== year; // Disable if it's not a weekend date OR outside the current month return !isWeekendDate(date) || isOutsideMonth; };
Step 4: Update Your InfiniteCalendar Component
Replace your existing resultCalendar code with this updated version, incorporating all the fixes above:
render() { let newDate = new Date(); let date = newDate.getDate(); let month = newDate.getMonth(); let year = newDate.getFullYear(); const lastDayOfMonth = new Date(year, month + 1, 0).getDate(); const {label, t, value = '', loading, error, width, height, displayOptions, locale, key, required, validateOnBlur, theme, name, proposed, disabled = false, onChange, minDateBeforeToday, setError, available=true} = this.props; const {selected} = this.state; const _locale ={...locale, ...{weekdays: locale.weekdays.map(day => t(day))}} // Helper to check if date is part of a weekend const isWeekendDate = (date) => { const day = date.getDay(); return day === 0 || day === 5 || day === 6; }; // Define which dates to disable const isDateDisabled = (date) => { const isOutsideMonth = date.getMonth() !== month || date.getFullYear() !== year; return !isWeekendDate(date) || isOutsideMonth; }; const resultCalendar = this.state.open && !disabled ? ( <InfiniteCalendar width={width} height={height} selected={value||selected||proposed} displayOptions={displayOptions} locale={_locale} theme={theme} minDate={new Date(year, month, date)} maxDate={new Date(year, month, lastDayOfMonth)} isDateDisabled={isDateDisabled} max={new Date(year, month, lastDayOfMonth)} min={new Date(year, month, date)} onSelect={(e) => this.onClick(e, onChange)} /> ) : null; // ... rest of your render code }
Bonus: Handling Weekend Date Combinations
If you want users to select entire weekend blocks (like Fri-Sun) instead of individual days, enhance the onSelect handler to map selected dates to their full weekend range:
const handleSelect = (selectedDate) => { let weekendRange; const day = selectedDate.getDay(); if (day === 5) { // Selected Friday const sunday = new Date(selectedDate); sunday.setDate(selectedDate.getDate() + 2); weekendRange = [selectedDate, sunday]; } else if (day === 6) { // Selected Saturday const friday = new Date(selectedDate); friday.setDate(selectedDate.getDate() - 1); const sunday = new Date(selectedDate); sunday.setDate(selectedDate.getDate() + 1); weekendRange = [friday, sunday]; } else { // Selected Sunday const friday = new Date(selectedDate); friday.setDate(selectedDate.getDate() - 2); weekendRange = [friday, selectedDate]; } // Pass the full weekend range to your onChange handler onChange(weekendRange); this.setState({ selected: weekendRange }); };
Then update the onSelect prop in InfiniteCalendar to onSelect={handleSelect}.
That should do it! This setup will disable all non-weekend dates in the current month, and optionally let users select full weekend blocks as you described in your example.
内容的提问来源于stack exchange,提问作者michaelpnrs

