Search code examples
jquerycsscalendaroracle-apexstyling

Marking holidays, for example Easter, in the Oracle Apex calendar


I have a select statement that returns public holiday dates and they are displayed as events in the calendar. I can give them a css class to identify them ('apex-cal-green'), however, I have many events in the calendar each day and it would be better to display holidays by another background color for the day (since they are not events anyway).

I found a solution that uses jQuery here, but it is not working properly since it highlights the wrong dates.

It would be ideal if there is a built in css class to use, such as the fc-past class.

Thanks in advance, Ulrik


Solution

  • The key is the dayRender function which is mentioned here: How can I change the css of a day cell by date?

    The question is: how can one use that in APEX? The trick is to first load up the holidays in the DOM and then configure the calendar region to work with them.

    For this example, install the Sample Database Application. Run the app, navigate to the Orders page, then click the Calendar button. That's the calendar I'll be working with.

    1. Navigate to the Page Designer for the calendar page. Right-click Content Body under the rendering tab, then select Create Region. Set Name to <script> Add holidays to DOM, Type to PL/SQL Dynamic Content, then enter the following code in PL/SQL Code:

      htp.p('<script>');
      
      htp.p('  var holidays = [];');
      
      for rec in (
        select sysdate - 7 holiday
        from dual
        union
        select sysdate holiday
        from dual
        union
        select add_months(sysdate, 2) holiday
        from dual
      )
      loop
        htp.p('  holidays.push("' || to_char(rec.holiday, 'yyyy/mm/dd') || '")');
      end loop;
      
      htp.p('</script>');
      

      Finally, set Template to - Select - (unselecting the template).

      This will add some JavaScript to the page that adds some fake holidays to an array as strings. Normally, I would use Ajax to bring in the dates after the page has rendered, but this is needed to render the calendar correctly the first time.

    2. Select the Attributes node under the Order Calendar region. Scroll down through the properties until you see JavaScript Initialization Code under Advanced and add the following code there:

      function (options) {
        options.dayRender = function (date, cell) {
          for (let idx = 0; idx < holidays.length; idx++) {
            let holiday = $.fullCalendar.moment.utc(holidays[idx]);
      
            if (date.isSame(holiday)) {
              cell.css('background-color', 'red');
            }
          }
        };
      
        return options;
      }
      

      This code will add the dayRender function to the calendar. The function will check the days being rendered in the calendar against the list of holidays added from the previous step. If the day being rendered matches a holiday, then the cell's background is set to red.

    You should be able to customize this solution to better meet your needs.