动态更改callendar视图的问题

问题描述 投票:0回答:1

基本上我想了解一些日历知识,日历从谷歌获取事件,但这不是问题。那部分已经完成了。我有这个逻辑,但我无法实现。所需的行为是仅显示未来日期,例如:我们现在是 2024 年 7 月,因此在选择 2024 年时的月份下拉列表中,它应该只显示当前月份及以后的月份,而当选择当前年份之后的任何其他年份时,它应该显示所有月份。这部分运作良好。 现在最大的问题是,当我查看例如 2025 年 3 月(即当年的一年和本月的前一个月)时,如果我尝试将视图切换到 2024 年,则月份下拉列表应默认为 7 月(当前月份),并且与日历渲染相关的变量也应该更新。但这并没有发生,它会转到下拉列表中不存在的选项。我已经寻找并尝试了几个小时,所以我来到 stackoverflow 希望找到解决方案。抱歉,我很累,我可能写了一些令人困惑的事情,所以问我一些事情,我显然很乐意回复!预先感谢。

function populateMonths() {
    const selectMonth = document.getElementById('selectMonth');
    const currentYear = new Date().getFullYear();
    const currentMonth = new Date().getMonth();
    const months = [
        'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 
        'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'
    ];

    selectMonth.innerHTML = ''; // Clear existing options

    let startMonth = 0;
    if (selectedYear === currentYear) {
        startMonth = currentMonth; // Show from current month onwards
    }

    console.log(`currentYear: ${currentYear}`);
    console.log(`currentMonth: ${currentMonth}`);
    console.log(`selectedYear: ${selectedYear}`);
    console.log(`selectedMonth: ${selectedMonth}`);
    console.log(`startMonth: ${startMonth}`);

    months.slice(startMonth).forEach((month, index) => {
        const monthIndex = startMonth + index;
        const option = document.createElement('option');
        option.value = monthIndex; // Adjust value to reflect actual month index
        option.textContent = months[monthIndex];
        selectMonth.appendChild(option);
    });

    selectMonth.selectedIndex = selectedMonth - startMonth;

    console.log(`Final selectedIndex: ${selectMonth.selectedIndex}`);
}






function populateYears() {
    const selectYear = document.getElementById('selectYear');
    const currentYear = new Date().getFullYear();
    const yearsToShow = 3; // Number of years to show, starting from the current year

    selectYear.innerHTML = ''; // Clear existing options

    for (let i = 0; i < yearsToShow; i++) {
        const year = currentYear + i;
        const option = document.createElement('option');
        option.value = year;
        option.textContent = year;
        selectYear.appendChild(option);
    }

    selectYear.value = selectedYear;
}

function changeMonth() {
    selectedMonth = parseInt(document.getElementById('selectMonth').value);
    renderCalendar(selectedYear, selectedMonth);
}

function changeYear() {
    selectedYear = parseInt(document.getElementById('selectYear').value);
    populateMonths();
    renderCalendar(selectedYear, selectedMonth);
}

function renderCalendar(year, month) {
    const calendar = document.getElementById('calendar');
    calendar.innerHTML = '';

    const firstDayOfMonth = new Date(year, month, 1);
    const lastDayOfMonth = new Date(year, month + 1, 0);
    const daysInMonth = lastDayOfMonth.getDate();

    const startingDay = firstDayOfMonth.getDay(); // 0 (Sunday) to 6 (Saturday)
    const daysOfWeek = ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'];

    // Create header row for days of the week
    for (let day = 0; day < 7; day++) {
        const cell = document.createElement('div');
        cell.classList.add('cell', 'header-cell');
        cell.textContent = daysOfWeek[day];
        calendar.appendChild(cell);
    }

    // Create blank cells for the days before the first day of the month
    for (let i = 0; i < startingDay; i++) {
        const cell = document.createElement('div');
        cell.classList.add('cell', 'empty-cell');
        calendar.appendChild(cell);
    }

    // Create cells for each day in the month
    for (let i = 1; i <= daysInMonth; i++) {
        const date = new Date(year, month, i);
        const dateString = formatDate(date); // Format date to 'YYYY-MM-DD'

        const cell = document.createElement('div');
        cell.classList.add('cell');
        cell.textContent = i;

        const dayEvents = events.filter(event => event.date === dateString);

        if (isFullyBooked(dateString)) {
            cell.classList.add('booked');
            cell.title = 'Totalmente reservado';
        } else if (isHalfBooked(dayEvents)) {
            cell.classList.add('half-booked');
            cell.title = 'Parcialmente reservado';
            cell.addEventListener('mouseover', () => showAvailableHoursTooltip(cell, dayEvents));
            cell.addEventListener('mouseout', hideTooltip);
        } else {
            cell.classList.add('available');
            cell.title = 'Disponível';
        }

        calendar.appendChild(cell);
    }
}
javascript html calendar logic
1个回答
0
投票

希望这有帮助,代码比我想象的要简单得多。尝试一下 select 以查看功能,以帮助您了解此代码的作用。我还没有实现填充年,所以我认为这已经是正确的。您可以将事件侦听器转换为原始代码中相应的changeMonth 和changeYears 函数。下面的代码只是帮助您让选择功能按您的预期工作。

const months = [
  'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 
  'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'
]



const selectMonth = document.getElementById('selectMonth')
const selectYear = document.getElementById('selectYear')



function filteredMonths(year) {
    const currentYear = new Date().getFullYear();
    const currentMonth = new Date().getMonth();
    
    if (year > currentYear) return months // return all months if future year
    
    return months.slice(currentMonth, months.length)
}


let lastMonthSelected = null // helps with month memory


function populateMonths(year) {
    const validMonths = filteredMonths(year)
    const currentMonth = new Date().getMonth();
    
    selectMonth.innerHTML = ''

    validMonths.forEach(monthName => {
        const option = document.createElement('option');
        option.value = months.indexOf(monthName); 
        option.textContent = monthName
        selectMonth.appendChild(option);
    });
    
    // if month = 'Outubro' and year change to 2025, stay selected on 'Outubro' still
    if (lastMonthSelected && validMonths.indexOf(lastMonthSelected) > -1) {
      selectMonth.selectedIndex = validMonths.indexOf(lastMonthSelected);
      return
    }
    
    const currentMonthIndex = validMonths.indexOf(months[currentMonth])
    const startIndex = currentMonthIndex > -1 ? currentMonthIndex : 0

    selectMonth.selectedIndex = startIndex;
    lastMonthSelected = months[currentMonth]
}



function updateMonthOptions() {
  const year = selectYear.value || 2024; // set defaults too
  populateMonths(year)
  // you dont need to store the selected year or month in a variable unless you need it for another part of your program, but if you did need it, add it here
}



selectYear.addEventListener('change', updateMonthOptions);
selectMonth.addEventListener('change', () => {
   lastMonthSelected = selectMonth.options[selectMonth.selectedIndex].text
});
updateMonthOptions() // call once in beginning to set defaults
<select id="selectYear">
  <option value="2024">2024</option>
  <option value="2025">2025</option>
  <option value="2026">2026</option>
</select>
<select id="selectMonth">
    <!-- Options will be dynamically populated -->
</select>

© www.soinside.com 2019 - 2024. All rights reserved.