Let's build a Region Plug-In

Kscope26

Philipp Hartenfeller and Vito Van Hecke

| Aurora

$whoami

Philipp Hartenfeller

  • Düsseldorf, Germany
  • Oracle APEX Dev since 2016
  • Product Lead at United Codes
  • Web Dev and Databases

$whoami

Vito Van Hecke

  • Hasselt Belgium
  • Oracle APEX since 2022
  • Consultant at United Codes
  • Web/Mobile dev and databases

Agenda

(Shift + A: jump to Agenda, Shift + O: overview)

Introduction

What is a Region Plug-In?

  • A reusable, server-side component that renders custom HTML into a region
  • Written in PL/SQL — a render callback streams the markup
  • Optionally adds an AJAX callback + client-side JS for interactivity
  • Configurable through custom attributes — build once, reuse everywhere
  • Reach for one when a Dynamic Content region or a Template Component is no longer enough

Anatomy of a Region Plug-In

  • Render function — PL/SQL that emits the region's HTML
  • Custom attributes — declarative settings the developer fills in
  • AJAX callback — PL/SQL that answers asynchronous requests
  • Client-side JS — registers the region and wires up behaviour

Demo

Step 1 — Create the Plug-In

  • Shared Components > Plug-ins > Create > From Scratch
  • Name: Dice — the label developers see
  • Internal Name: COM.UNITEDCODES.DICE
  • Reverse-domain internal names avoid clashes between vendors.
  • Type: Region

Step 2 — The Render Callback

  • APEX calls your render procedure to draw the region
  • Four parameters carry everything you need:
    • p_plugin — plug-in metadata
    • p_region — this region (id, attributes, …)
    • p_param — render-time context
    • p_result — tell APEX what you did
  • apex_util.prn renders HTML

Step 2 — A first render

           
              

Step 3 — Rolling the dice

           
              

Step 4 — Custom Attributes

Make the plug-in configurable without touching code — Custom Attributes > Add Attribute.

static_id Label Type Required Default
minimum Minimum Number Yes 1
maximum Maximum Number Yes 6

Reading attributes in render

           
              

AJAX

Refresh without a page reload

  • APEX regions support a standard refresh action (e.g. a button, a dynamic action)
  • To opt in, the plug-in needs two new pieces:
    • Register the region on the client with apex.region.create
    • Add an AJAX callback on the server to recompute data
  • The render function bootstraps the client-side code on page load

Wiring up the client

  • apex_javascript.add_onload_code runs JS once the page is ready
  • p_region.static_id — the region's DOM id, so JS can find it
  • apex_plugin.get_ajax_identifier — the secure handle for AJAX calls back to this plug-in

Demo

Wiring up the client

           
              

Client-side init

  • apex.region.create(id, { type, refresh }) registers the region with APEX
  • The refresh callback fires whenever something asks the region to refresh

Client-side init — naive refresh

           
              

The AJAX callback

  • A second procedure, ajax, answers asynchronous requests from the client
  • It recomputes the dice on the server — honouring the configured range
  • apex_json.open_object / write / close_object build the JSON response

The AJAX callback

           
              

Client-side refresh via AJAX

           
              

Recap — the full picture

  • Render emits the HTML and bootstraps the client JS
  • Custom attributes make the range configurable per region
  • AJAX callback recomputes the dice on the server
  • Client JS registers the region and handles refresh
  • Refresh flow: button → refresh callback → apex.server.pluginajax proc → JSON → DOM update

Advanced techniques

One callback, many actions

  • A plug-in has a single secure AJAX identifier — but you often need several server actions (load, save, stats, …)
  • The client passes a method name in a parameter — e.g. x01
  • The ajax proc reads apex_application.g_x01 and routes with a CASE
  • Remaining x02x10 / f01 carry that action's payload

Dispatching on a method name

           
              

Picking the method on the client

           
              

APEX_EXEC

  • Query any data source (local DB, REST source, …) with one API
  • Built-in pagination (p_first_row, p_max_rows) and a total row count
  • Bind parameters and add filters — no string concatenation, injection-safe
  • Iterate with next_row + typed getters (get_varchar2, get_number)
  • Always apex_exec.close the context — also in your exception handler

APEX_EXEC + APEX_JSON

           
              
           
              

APEX_EXEC — custom row processing

           
              

APEX_EXEC — add_filter

           
              

APEX_EXEC — execute_plsql

           
              

Evaluating developer PL/SQL

  • Let developers configure behaviour with a PL/SQL expression attribute
  • apex_plugin_util.get_plsql_expr_result_* evaluates it at runtime — returning varchar2, number or boolean
  • Great for dynamic default values or a read-only condition
  • APEX handles parsing, binding of :APP_ITEM & caching for you

get_plsql_expr_result

           
              

Handling large payloads

  • htp.p / htp.prn cap at ~32k characters per call
  • Outbound: apex_util.prn takes a CLOB and chunks it for you (escapes HTML by default — mind p_escape)
  • Inbound: send p_clob_01 in the AJAX data and read apex_application.g_clob_01 in PL/SQL

Sending a CLOB to the server

           
              
           
              

Encapsulate the frontend in a Web Component

  • Build the UI as a Web Component first — all markup, styles and JS logic live in one custom element
  • The render proc just emits the tag: <my-dice-region region-id="...">
  • Develop & test it standalone (local HTML page) — no APEX round-trips
  • Reusable beyond the plug-in: same component works in any other app or framework

A minimal Web Component

           
              
           
              

Q&A

Scan for speaker evaluation

Speaker evaluation QR code

Thank you!

Speaker evaluation slide

philipp@united-codes.com