1

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

2 Answers2

1

You can customize the calendar query and

  • add your own class as a column in the query - for the holidays

  • And specify the column as CSS class in the attributes

  • and then add your custom CSS for the class.

Query

Attributes section

HTML output

Edit:

@ulrik-larsen I see what you mean.
I do not think that is possible straight away. But I think we can do a work around

  • Add a class that includes the date - take the sub string of the class so that we will only get the date
  • Select the td using the data-date attribute
  • Add the class to the td that way
  • Hide the event anchor tag

Calendar query

   select ORDER_ID,
     CUSTOMER_ID,
     ORDER_TOTAL,
     ORDER_TIMESTAMP,
     USER_NAME,
     TAGS,
     'apex-cal-green' css_class
    from DEMO_ORDERS

   union

   select 1,
         1,
         1,
         to_date('06/12/2020', 'MM/DD/YYYY'),
         'e',
         'TAGS',
         'hol-sel-class hol-class-'||to_char(to_date('06/12/2020', 'MM/DD/YYYY'), 'YYYY-MM-DD') css_class
   from dual  

   union

   select 1,
         1,
         1,
         to_date('06/13/2020', 'MM/DD/YYYY')+1,
         'e',
         'TAGS',
         'apex-cal-green' css_class
   from dual

Function and Global Variable Declaration

function holidayCss(){
      $(".hol-sel-class").each(function(){
        var classList = this.className.split(/\s+/);
        for (var i = 0; i < classList.length; i++) {
            console.log('classList[i] - ',classList[i]);
            console.log('classList[i].substring(0, 10) - ',classList[i].substring(0, 10));
            if (classList[i].substring(0, 10) == "hol-class-") {
                console.log('in loop - '+classList[i].substring(10));
                // data-date="2020-05-26"
                $('td[data-date="'+classList[i].substring(10)+'"]').addClass('apex-cal-test-class');
                console.log('td[data-date='+classList[i].substring(10)+']');
                console.log('td[data-date="'+classList[i].substring(10)+'"]');
                console.log($('td[data-date="'+classList[i].substring(10)+'"]').attr( "class" ));
                $(".hol-sel-class").addClass('am-hidden');
          }
        }
    });
}

Execute when page loads

setTimeout(holidayCss, 500);

We need to delay the JS execution because calendar is loaded after the page is loaded

CSS Inline

td.fc-day.ui-widget-content.fc-fri.fc-future.apex-cal-test-class {
    background-color: darkgray;
}

a.fc-day-grid-event.fc-h-event.fc-event.fc-start.fc-end.hol-sel-class.am-hidden {
    display: none;
}

Holiday getting class

The holiday even hidden

Hope this helps :)

Anuswadh
  • 542
  • 1
  • 11
  • 19
  • 1
    Thanks for your answer. This is what I got so far, but perhaps my question is not properly described. What I need to do is apply styling to the actual day, like in the way that 'today' is styled with gray background. I.e., not display an event, because it is not actually an event, but rather a description of the day. – Ulrik Larsen May 26 '20 at 19:23
  • 1
    @UlrikLarsen Did you still need help with this? – Dan McGhan Jun 05 '20 at 13:18
  • @Dan McGhan Yes, if you have an alternative solution to the one provided by Anuswadh – Ulrik Larsen Jun 06 '20 at 20:26
  • Thanks again @Anuswadh. I am going with Dan's answer since it is simpler and more reliable I think. – Ulrik Larsen Jun 10 '20 at 19:46
1

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.

Dan McGhan
  • 4,479
  • 1
  • 11
  • 15