APEX 22.2+ Dynamic Content Regions

Search for a command to run...

Jon, i do appreciate for clear view on that great APEX 222 feature! But would You clarify APEX Advisor of that? I mean that Advisor don't like any new Dynamic region...
Region Source (Identifies the source of the region, reference Region Source Type)
Check Is Valid SQL or PL/SQL Code
Category Error
Message
Compilation error - ORA-06550: line 33, column 3:
PLS-00372: In a procedure, RETURN statement cannot contain an expression
Appreciate for Your answer. Would You clarify, have You checked page with Your dynamic example in APEX Advisor? On my APEX 22.2.0 even code exactly from APEX Help fails in that warning. Yes, code works, but Advisor says "Code Category Error Message Compilation error - ORA-06550" etc.
Oracle APEX ideas and insights that you can read in four minutes or less.
Introduction APEX 21.2 introduced several enhancements to APEX Confirmation and Alert Dialogs. These enhancements replace previous homegrown solutions that required Dynamic Actions and various APEX message JavaScript APIs. There are two flavors of co...
Introduction One of the marquee features of APEX 26.1 was AI Interactive Reports. When I started testing this new feature, I was interested to see what was going on behind the scenes. In this post, I

Introduction One of the marquee features of APEX 26.1 is APEX AI Agents. APEX AI Agents allow you to use an LLM and your own PL/SQL and JS tools to perform actions on your data instead of just chattin

Introduction In my previous post, I looked at logging APEX AI Agent requests and responses with Request and Response handlers. Logging is the first step because it shows you what is actually moving th

Introduction Logging is one of the first things you need when building serious AI Agents. Without it, debugging quickly becomes guesswork. You can see the final answer, but not always why the model ch

Context management patterns from building agents in Oracle APEX

For the longest time, as APEX developers, we have had to utilize workarounds to refresh Dynamic Content regions in APEX dynamically. I even wrote a blog post with an approach I use to solve this problem Solving the APEX PL/SQL Dynamic Content Region Partial Page Refresh Problem. APEX 22.2 brought a new Dynamic Content Region that supports CLOBs and dynamic refreshing out of the box. This post will demonstrate how the new APEX Dynamic Content Region works.
Before starting, let's look at why you would want to use an APEX Dynamic Content Region in the first place. I typically only use them when standard APEX components and templates (e.g., Card Regions, Comments, Content Row, Value Attribute Pairs, etc.) do not fit my requirements. Even then, I would suggest using CSS to modify standard APEX templates before using a Dynamic Content Region.
Dynamic Content Regions are helpful when you need to build HTML content dynamically using PL/SQL. For example, you may need to show data in a non-tabular layout, or you may need to show HTML that has been generated from multiple sources (DB table, REST Services, etc.).
In my demo, we have provided users with a Rich text editor field where they can enter notes. These notes are appended to a CLOB column in a table, and the Dynamic Content Region is refreshed to show the CLOB with all of the notes.
An APEX Dynamic Content Region emits whatever HTML you return in the Dynamic Content Region PL/SQL Function Body returning a CLOB attribute. The simplest possible example would look like this:

The output for the above example looks like this:

I made my demo a little more complicated to illustrate all of the features of Dynamic Content Regions.

Let's look at the code and the APEX page behind this:
The Enter a New Note field is a simple Rich Text Editor Item. There is a button + Add Note which runs a Dynamic Action to:
1. Append the New Note to notes history CLOB in a table
Clear the Enter a New Note field
Refresh the Note History Region so that we see the new notes. ⭐ This is one of the aspects of the new Dynamic Content Region, which differs from APEX versions before 22.2. Being able to refresh a Dynamic Content Region from a Dynamic Action gives us the ability to generate dynamic content without having to submit the page

The complete code for the Server Side code can be seen below. In real life, this code would be inside a PL/SQL package.
DECLARE
l_notes cndemo_table.notes%TYPE;
l_new_note CLOB;
l_clob_len NUMBER;
GC_ACTIVITY_TPL CONSTANT VARCHAR2(32000) := q'[
<ul class="t-ContentRow t-ContentRow--styleCompact t-ContentRow--hideDescription activity-header t-Report--hideNoPagination u-color-21 margin-bottom-md" id="1" data-region-id="RX_1">
<li class="t-ContentRow-item ">
<div class="t-ContentRow-wrap">
<div class="t-ContentRow-body">
<div class="t-ContentRow-content">
<h3 class="t-ContentRow-title">Entry Date: #ACTIVITY_NAME#</h3>
</div>
</div>
</div>
</li>
</ul>]';
l_tpl VARCHAR2(32000);
BEGIN
-- Replace the token #ACTIVITY_NAME# with the current date and time.
l_tpl := REPLACE(GC_ACTIVITY_TPL, '#ACTIVITY_NAME#', TO_CHAR(CURRENT_TIMESTAMP,('DD-MON-YYYY HH:MI:SS pm')));
-- Create a CLOB for the New Note.
dbms_lob.createtemporary(lob_loc => l_new_note, cache => true, dur => dbms_lob.call);
l_new_note := :P11_TODAYS_NOTES;
-- Get the existing note history from a CLOB in a table.
SELECT notes INTO l_notes
FROM cndemo_table
WHERE id = 1 FOR UPDATE;
-- Append the new note content to the CLOB from the table.
l_clob_len := dbms_lob.getlength(l_notes);
IF NVL(l_clob_len,0) = 0 THEN
-- If there is no note history.
dbms_lob.createtemporary(lob_loc => l_notes, cache => true, dur => dbms_lob.call);
l_notes := l_tpl || l_new_note;
ELSE
dbms_lob.append(l_notes, l_tpl || l_new_note);
END IF;
-- Update the Notes Table with the combined CLOB.
UPDATE cndemo_table
SET notes = l_notes
WHERE id = 1;
-- Free up the temporary CLOB.
dbms_lob.freetemporary(l_new_note);
END;
GC_ACTIVITY_TPL, is there to illustrate that we can use APEX Universal Theme CSS classes to format HTML content in a Dynamic Content Region. I have picked out CSS classes from the 'Content Region' to format the date heading I have between each noteThis is the Dynamic Content Region.

Here is the code from the PL/SQL Function Body returning a CLOB attribute from the screenshot above. Note: this code is just here as an example. Your code could be fetching HTML from a web service, looping through hundreds of records, etc. If you return a CLOB, it will be rendered in the region.
DECLARE
l_notes cndemo_table.notes%TYPE;
l_note_len NUMBER;
BEGIN
-- Fetch the Notes History CLOB from a table.
SELECT notes
, dbms_lob.getlength(notes) note_len
INTO l_notes
, l_note_len
FROM cndemo_table
WHERE id = 1;
-- If the size of the note is
IF NVL(l_note_len,0) = 0 THEN
-- If there is no current note then return message to indicate there are no notes. Similar to a Classic Or Interactive Reports region where we have No Data Found.
RETURN '<h4>You do not have any notes</h4>';
ELSE
-- Return the CLOB containing the HTML for the notes.
-- APEX will display whatever HTML you have in the region.
RETURN l_notes;
END IF;
END;
⭐ In the code above, you will notice the other change to Dynamic Content Regions that was introduced in APEX 22.2. In previous versions, you had to output HTML using htp.p or apex_util.prn. From APEX 22.2 on, you simply build a CLOB and return it.

In the Attributes section of the region, we have the option to enable Lazy Loading. This will defer the fetching and rendering of the HTML in the Dynamic Content Region until after the page is rendered. This can be useful if the Dynamic Content Region takes a long time to process, and you don't want the user to have to wait for this before the main page is loaded.
And that is all there is to it!
One thing I should point out is that APEX will not attempt to do any escaping of the HTML that you emit in a Dynamic Content Region. This means you must either completely trust the content does not have any javascript embedded in it, or you must use APEX_ESCAPE to escape the content yourself.
See the WASP XSS Guide for more details on Cross-Site Scripting (XSS) Attacks.
You should not need to use Dynamic Content Regions often, but they are essential when you do need them. Having the ability to refresh them dynamically (since APEX 22.2) makes them even more useful.
🩳 [APEX Shorts](https://blog.cloudnueva.com/series/apex-shorts)
#️⃣ [APEX Posts](https://blog.cloudnueva.com/tag/orclapex)