1
\$\begingroup\$

I have an input array of month-year strings of disabled months selected by the user:

disabledDates = [
    "2020-01",
    "2014-07",
    "2020-03",
    "2011-08"
    "2011-10"
]

(But it can be much longer)

The user is displayed a calendar with years and months only - he can select an year using a dropdown. For each year I want to grey out the month cubes that are disabled in the given array.

Right now my solution does not seem too performant: I convert each string to date and get the year using new Date().getFullYear() every time a user selects an year and check for every date if it matches the current selected year and if so I use getMonth() to grey out matching months:

let disabledMonths = [];
let dateObject;

disabledDates.forEach(function(date) {
    dateObject = new Date(date);
    if (dateObject.getFullYear() === currentSelectedYear) {
    disabledMonths.push(dateObject.getMonth());
    }
}

for (let i = 0; i < 12; i++) {
    if (disabledMonths.includes(i)) {
        calendarElement.innerHtml += `<div class="disabled_month"...>`;
    } else {
        calendarElement.innerHtml += `<div ...>`;
    }
} 

But I think it does unnecessary iterations every time. Maybe there's a better way, such as "grouping" all the dates by years, then only if there's a matching year in this group - get the months and grey them out. But is something like that possible?

( Also, I want to also add the same feature but when displaying days as well, so it can be an array of full dates:

disabledDates = [
    "2020-01-01",
    "2014-07-12",
    "2020-03-30",
    "2011-08-11"
    "2011-10-05"
]

so that might add more iterations )

\$\endgroup\$
2
  • 2
    \$\begingroup\$ I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Please check that I haven't misrepresented your code, and correct it if I have. \$\endgroup\$ Feb 15, 2023 at 11:09
  • \$\begingroup\$ The "month-year" strings appear to be "year-month" order instead. \$\endgroup\$
    – radarbob
    Feb 19, 2023 at 5:11

1 Answer 1

1
\$\begingroup\$

There's no need to first map the disabled months for the year. You can directly check with disabledDates.includes() by prefixing the month with the selected year.

for (let month = 1; month <= 12; month++) {
    const date = currentSelectedYear + "-" + String(month).padStart(2, '0');
    
    if (disabledDates.includes(date)) {
        calendarElement.innerHtml += `<div class="disabled_month"...>`;
    } else {
        calendarElement.innerHtml += `<div ...>`;
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.