Styling APEX Report cells conditionally

I hate it when I can’t remember how I did certain thing in the past. And I have to spend precious time “reinventing the wheel” as the famous saying states. One of those things is conditionally change the text colour or background colour of certain cells in APEX Reports (Classic Report, Interactive Report or Interactive Grid). That’s why I will do my homework and put my notes here, hopefully saving some of your precious time too.


Anatomy of a Report cell

In this blog post I’m describing some methods of styling report cells in APEX. But APEX has three types of reports – the Classic Report, Interactive Report and Interactive Grid. Since they appeared at different times in the history of APEX and serve different purposes, their HTML structure is a bit different. That is valid for the options we have in the APEX Builder for each one of them. So to better understand why I need a different approach for each one of them, let’s take a look of the HTML code for a single cell in each Report type:

Classic report ⬇️

<td class="t-Report-cell" headers="COLUMN_NAME">value</td>

Interactive Report ⬇️

<td class="u-tC" headers="COLUMN_NAME">value</td>

Interactive Grid ⬇️

<td role="gridcell" tabindex="0" class="a-GV-cell u-tC is-readonly">value</td>

Adding some CSS classes

Before we go ahead with modifying the HTML of Report cells, we will slightly modify the SQL query of our reports. This is valid for all three types (Classic Report, Interactive Report and Interactive Grid). What we add is a new column, named css_color, which will have different string value, depending on our conditions. The query would look like that:

select col1,col2,colx,
       CASE
          WHEN col1 IS NULL THEN 'u-color-22'
          ELSE 'u-color-20'
       END css_color
from some_table

In this example I will have either u-color-22 or u-color-20 as CSS class names. Those are standard APEX CSS classes, ready for use out-of-the-box. But if you like, you can define your own classes and use them instead. For the full list of CSS color modifiers, available in the Universal theme, check the following reference – something that I believe every APEX developer should have in their bookmarks.

https://apex.oracle.com/pls/apex/r/apex_pm/ut/color-and-status-modifiers

Oracle APEX Universal Theme

Adding some HTML formatting

So far so good. Having seen what a cell looks like, having added a new column with the right CSS class, let’s try to add some more styling to each column. If you take a look at the Help tab in the APEX Builder, there is the following suggestion for the Settings / HTML Expression option of your column (which is the same for Classic Report and Interactive Report):

<span class="#CSS_COLOR#">#COLUMN_NAME#</span>

… and slightly different for Interactive Grid. We should also do one additional step before we can use it there – changing the value of Identification / Type to HTML Expression in our Column settings.

<span class="&CSS_COLOR.">&COLUMN_NAME.</span>

If you use are using the CSS text modifier CSS classes (u-color-XX-text or u-color-XX-border), you are good to go and don’t need any more changes on your page. Text looks good and we are all happy. However, if you are using the background modifier classes (u-color-XX or u-color-XX-bg), they don’t look so pretty. The reason why is that they are styling just the <span> or <div> element we’ve put into Settings / HTML Expression, but not their parent <td> element.

Styling the parent <td> element

  • First step is to add another CSS class to the Settings / HTML Expression, so that we know which cells we are interested in. You will later see how this CSS class is used in our Javascript code. Let’s give that class the name colorContainer. The following HTML Expression will be the same if you have Classic Report or Interactive Report.
<div class="colorContainer #CSS_COLOR#">#COLUMN_NAME#</div>

For Interactive Grid, add the following as HTML Expression:

<div class="colorContainer &CSS_COLOR.">&COLUMN_NAME.</div>
  • Second step is to add the following Javascript code on Page level – JavaScript / Execute when Page Loads:
// Go through every div element inside of table cell, having colorContainer CSS class
$('td>div.colorContainer').each(function() {
    // find the parent td element and add the same class as the child div element
    $(this).closest('td').addClass( $(this).attr("class") ) ;
});

What this Javascript code does is basically get the CSS classes from the <div> element and add them to the parent <td> element. By doing so, now the whole cell will get the desired styling.

Here is how the Interactive Grid and Interactive Report look after applying all of the above.


Having trouble with formatting when using the Interactive Report or Interactive Grid search functionalities and Action menu? Take the following steps:

For Interactive Grid ⬇️

  • Add the following CSS style on Page level – CSS / Inline:
.colorContainer {
   position: relative;
   padding: 8px 12px;
   margin: -8px -12px;
}

For Interactive Report ⬇️

  • Create new Dynamic Action
    • Event: After Refresh
    • Selection Type: Region
    • Region: *Pick your Interactive Report from the list*
    • Event Scope: Dynamic
    • ———————–
    • True Action
      • Action: Execute JavaScript Code
      • Code: *The same JS code you used previously*
      • Fire on Initialization: True
// Go through every div element inside of table cell, having colorContainer CSS class
$('td>div.colorContainer').each(function() {
    // find the parent td element and add the same class as the child div element
    $(this).closest('td').addClass( $(this).attr("class") ) ;
});

Conditional Rows Styling in your report

The concept here is absolutely the same as styling Report columns. The only difference will be that this time we would apply our CSS class to the parent <tr> HTML element instead of the <td> one. I will also create my own CSS class this time, just to show you how you can implement that technique, valid both when styling Columns and Rows.

  • Use a similar to the following query as your Report source:
select col1,col2,colx,
       CASE
          WHEN order_status_id = 1 THEN null
          WHEN order_status_id = 2 THEN null
          ELSE 'highlight_row'
       END css_color
  from some_table
  • Use the following as HTML Expression for any of your columns (it’s important to have it on at least one of them, so the highlight CSS class exists).
<div class="#CSS_COLOR#">#COLUMN_NAME#</div>
  • Add the following CSS on Page level – CSS / Inline. What it does is style the <tr> elements, having class highlight_row.
tr.highlight_row {
   border: 2px dotted #ffffff;
   background-color: var(--u-color-20);
   color: #ffffff;
   font-style: italic;
}

tr.highlight_row:hover {
   color: #777777;
   font-style: italic;
}
  • There aren’t any highlight_row <tr> elements yet, so we will use the following Javascript code to add it (very similar for the ones used to style Report columns):
// Go through every div element inside of table cell, having highlight_row CSS class
$('td>div.highlight_row').each(function() {
    // find the parent tr element and add the same class as the child div element
    $(this).closest('tr').addClass( $(this).attr("class") ) ;
});
  • Create new Dynamic Action
    • Event: After Refresh
    • Selection Type: Region
    • Region: *Pick your Interactive Report from the list*
    • Event Scope: Dynamic
    • ———————–
    • True Action
      • Action: Execute JavaScript Code
      • Code: *The above JS code*
      • Fire on Initialization: True

Here is what the Report looks like after completing all four steps above. It is working in Classic Report, Interactive Report and Interactive Grid.

Demo

Check the demo on my apex.oracle.com free instance:

https://apex.oracle.com/pls/apex/r/gamma_dev/demo/styling-report-cells


Liked that post? Follow me on Twitter and LinkedIn!

@plamen_9 on Twitter

Plamen Mushkov on LinkedIn

23 thoughts on “Styling APEX Report cells conditionally

  1. Plamen, thanks for sharing. But I noticed the row highlighting is not working on your demo page, I also couldn’t get it to work as per your example, has something changed? Thanks

    Like

  2. Plamen, regarding the “Conditional Rows Styling in your report” section, I have followed your steps but cannot get the row to highlight. Should I implement all prior steps as well?

    Like

  3. Thank you for this tutorial. I’ve implemented it on a classic report and it works exactly as expected – until I scroll past the first page of results. The subsequent pages have the text with color behind the letters, but the cells are not filled with color. I do have the javascript code on page load. Any ideas?

    Like

  4. Plamen – I followed your tutorial for a classic report, using Apex 23.1; the rows shade beautifully – on the first page of query results. On subsequent pages, the shading is only behind the text (not filling the full cell). Should the shading work on subsequent pages? Thank you

    Like

  5. Dear Plamen,

    I am using your highligting row method in a Classic Report. It works almost as expected. The only trouble I am having is that the ‘CSS_COLOR’ column is visible. When I hide the column there is no HTML content possible.

    I have now hidden the column via CSS with:

    #MAIL_NO, /*header*/
    td[headers=”MAIL_NO”]/*rows*/
    {
    display: none;
    }

    But this is not a pretty solution since it cuts off the report, and it is hard to maintain for other developers.

    Do you have a solution for this?

    Like

  6. I am trying to apply this solution to faceted search results. You talk about classic reports and interactive reports – can you confirm which method is appropriate for a faceted search?

    Like

  7. Hi
    Are you able to share how you split the columns in a report row so they show as independent fields with space between the cells. I prefer this look and feel to the default spreadsheet look.

    Thanks
    Farhan

    Like

  8. Hi, thanks for your help. I could make it (Conditional Row Styling) work on a Interactive Report, but not in a Inetractive Grid.

    Besides the HTML Expression, is there any other difference? What is the HTML Expression I should use for Interactive Grid?

    Like

  9. Hi Plamen,

    your solution is very cool. But the APEX-Advisor (App-Builder => Your App => Utilities) throws an error:

    ORA-06592: CASE not found while executing CASE statement
    Contact your application administrator.

    That comes from the html-Expression:
    <div class="colorContainer &CSS_COLOR.">&COLUMN_NAME.</div>

    I need the advisor for preparing my app for better accessibililty.

    Have you tried the advisor with your app?

    Greetings from Thilo

    Like

Leave a reply to Plamen Mushkov Cancel reply