Using the APEX Template Application with parameters, directives, and functions allows developers to create highly dynamic and reusable templates in Oracle APEX. These features enable customization of the look and feel of reports, forms, and other UI components by inserting variable content, controlling conditional logic, and looping through data. By leveraging parameters, directives, and functions within templates, developers can build flexible applications that adapt to different contexts and data scenarios, improving both efficiency and user experience.
Using APEX Template Application with parameters, directives, and functions is a powerful way to build flexible, reusable, and dynamic templates in Oracle APEX. These features enable you to customize the rendering of reports, forms, cards, and other UI components by injecting dynamic content, controlling flow logic, and iterating through collections of data within templates.
Parameters are placeholders inside a template that you define and then substitute with actual values at runtime. For example, you might create a parameter like {P1_NAME} to represent a user name or a database column value. When the page renders, APEX replaces this placeholder with the corresponding value. This allows the same template to be reused across different pages or reports, with the content dynamically tailored to the context.
Directives control the logic flow inside templates. The most common directives include conditional directives such as {if}
, {elsif}
, {else}
, and {endif}
. These let you define conditional blocks so certain content only appears when specific criteria are met. For example, you can show a special badge or highlight a field only when its value meets a condition. This conditional rendering enhances user experience by making the UI more responsive to data context.
Another set of directives are loop directives like {for}
and {endfor}
, which allow you to iterate over a list or collection of data inside the template. This is particularly useful when you want to display repeating elements, such as a list of items or rows within a card layout. Loop directives automate the repetition of HTML or other template markup for each item in the data set, eliminating the need for manual repetition.
Functions in APEX templates allow you to perform inline operations or transformations on data before rendering. For example, you might use functions to format dates, truncate text, or convert values to uppercase within the template itself. This lets you keep formatting logic close to the display code rather than spreading it throughout your PL/SQL or SQL queries.
To use these features effectively:
-
Define Template Parameters: In the template definition, use curly braces
{}
to create named placeholders. For example,{ITEM_NAME}
or{COLUMN_VALUE}
. -
Implement Conditional Directives: Use
{if condition}
,{elsif condition}
,{else}
, and{endif}
to control what parts of the template render based on dynamic conditions. The conditions typically reference parameters or data values. -
Use Loop Directives: Structure your template to repeat content by enclosing the repeatable section within
{for item in collection}
and{endfor}
. Inside the loop, use{item.property}
to refer to the current element’s properties. -
Apply Functions: Invoke built-in or custom functions within the template to transform parameters. For example,
{UPPERCASE{PARAMETER}}
could display the parameter value in uppercase. -
Test and Debug: Use the Template Options and Preview features in APEX to test how parameters and directives behave. Adjust your template logic to handle different data scenarios gracefully.
By combining parameters, directives, and functions, you can create highly adaptable templates that reduce duplication, improve maintainability, and provide a richer user interface. This method also aligns well with the modular design principles in Oracle APEX development, enabling you to build consistent, reusable UI components that respond intelligently to the application data.
Mastering APEX Template Application with these features significantly enhances your ability to deliver dynamic, data-driven user experiences with minimal coding effort.
1. applyTemplate Function
Purpose:
The applyTemplate function allows you to process a template string with placeholders and directives, substituting them with values or expressions.
Example:
You can create a template where placeholders like &P1_PROFILE_IMAGE_FILE are dynamically replaced with actual data from the page items or objects.
var options = { placeholders: { MESSAGE: "All is well." } };
apex.jQuery("#notification").html(
apex.util.applyTemplate("<div>#MESSAGE#</div>", options)
);
This will render the message "All is well." inside a <div> element with the id #notification.
Use case:
Dynamically updating parts of the page (like messages or images) based on page items or variables.
2. arrayEqual Function
Purpose:
Compares two arrays and returns true if the arrays have the same number of elements and each element is strictly equal.
Example:
var result1 = apex.util.arrayEqual([1, "two", 3], [1, "two", 3]); // true
var result2 = apex.util.arrayEqual([1, "two", 3], [1, "two", "3"]); // false
Use case:
Compare arrays to check if the data has not changed.
Useful when validating if two arrays in a form are equal.
3. debounce Function
Purpose:
Returns a debounced version of a function. It delays execution of the function until after a certain amount of time has passed since the last call.
Example:
function formatValue() {
var value = $v("P1_PHONE_NUMBER");
$s("P1_PHONE_NUMBER_DISPLAY", value);
}
apex.jQuery("#P1_PHONE_NUMBER").on("keypress", apex.util.debounce(formatValue, 100));
Here, formatValue is called only after the user has stopped typing for 100 milliseconds, which reduces unnecessary function calls.
Use case:
To optimize handling of user input events like typing in form fields.
Avoid unnecessary server calls or updates when typing.
4. escapeCSS Function
Purpose:
Escapes CSS meta-characters in a string, ensuring that it can be safely used as part of a CSS selector.
Example:
apex.jQuery("#" + apex.util.escapeCSS("my.id"));
Use case:
Dynamically generating CSS selectors when element IDs or class names may contain special characters like periods (.), which could interfere with CSS selectors.
5. escapeHTML Function
Purpose:
Escapes special HTML characters to prevent XSS (Cross-Site Scripting) attacks when inserting untrusted data into the DOM.
Example:
apex.jQuery("#show_user").append(apex.util.escapeHTML($v("P1_UNTRUSTED_NAME")));
Use case:
When inserting user-generated content or external data into HTML, always escape it to prevent potential security vulnerabilities.
6. escapeHTMLAttr Function
Purpose:
Escapes special HTML characters in attribute values to avoid XSS attacks.
Example:
apex.jQuery("#show_user").attr("title", apex.util.escapeHTMLAttr($v("P1_UNTRUSTED_NAME")));
Use case:
Safely injecting user data into HTML attributes like title, alt, etc., to prevent XSS vulnerabilities.
7. getDateFromISO8601String Function
Purpose:
Converts an ISO 8601 date string into a JavaScript Date object.
Example:
var date1 = apex.util.getDateFromISO8601String("1987-01-23T13:05:09.040Z");
Use case:
Convert ISO 8601 date strings into JavaScript Date objects for manipulation or formatting.
Useful for dealing with date strings returned from APIs or databases.
8. getNestedObject Function
Purpose:
Returns a nested object at a specific path within a complex object structure.
Example:
var options = {
views: {
grid: {
features: {
cellRangeActions: true
}
}
}
};
var o = apex.util.getNestedObject(options, "views.grid.features");
o.cellRangeActions = false; // now options.views.grid.features.cellRangeActions === false
Use case:
Used when you need to manipulate deeply nested properties within an object, ensuring that missing properties are created dynamically.
9. getScrollbarSize Function
Purpose:
Returns the size of the system scrollbar (if present).
Example:
var size = apex.util.getScrollbarSize();
console.log(size); // { width: 17, height: 17 }
Use case:
Helps in layout adjustments when adding or removing scrollbars dynamically.
10. htmlBuilder Function
Purpose:
Returns an htmlBuilder interface, which allows you to build HTML dynamically.
Example:
var builder = apex.util.htmlBuilder();
builder.div().content("Hello World").end();
var html = builder.toString();
apex.jQuery("#container").html(html);
Use case:
Dynamically constructing HTML elements in a more programmatic and reusable manner.
11. invokeAfterPaint and cancelInvokeAfterPaint Functions
Purpose:
invokeAfterPaint: Executes a function before the next browser paint (reflow/repaint).
cancelInvokeAfterPaint: Cancels the previously scheduled function call.
Example:
var id = apex.util.invokeAfterPaint(function() {
console.log("This will be executed before the next repaint.");
});
// Optionally cancel the execution before the paint happens
apex.util.cancelInvokeAfterPaint(id);
Use case:
Perform tasks like animations or layout adjustments before the page is visually updated.
12. showSpinner Function
Purpose:
Displays a loading spinner on the page, indicating that some processing is taking place.
Example:
var lSpinner$ = apex.util.showSpinner($("#container_id"));
lSpinner$.remove(); // Removes the spinner once processing is complete.
Use case:
Display a spinner while processing a form or making an AJAX request to give users feedback that something is happening in the background.
13. stripHTML Function
Purpose:
Removes all HTML tags from a string.
Example:
var text = "Please <a href='www.example.com/ad'>click here</a>";
var strippedText = apex.util.stripHTML(text);
console.log(strippedText); // "Please click here"
Use case:
Strip unwanted HTML tags from user input or data that will be displayed as plain text.
14. toArray Function
Purpose:
Converts a value into an array. If the value is a string, it splits it based on a separator. If it's already an array or jQuery object, it converts it into a true JavaScript array.
Example:
var products = apex.util.toArray("Bags:Shoes:Shirts", ":");
console.log(products); // ["Bags", "Shoes", "Shirts"]
Use case:
Convert values into arrays for easier processing, such as when working with lists of items or elements on the page.
EXAMPLE:
Table – Table name: Requests
Code:
CREATE TABLE "CARDTEST"
( "ID" NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE,
"DISPLAYTHENAME" VARCHAR2(200 CHAR),
"USERNAME" VARCHAR2(200 CHAR),
"TITLE" VARCHAR2(200 CHAR),
"MAINPHONE" VARCHAR2(200 CHAR),
"MOBILEPHONE" VARCHAR2(200 CHAR),
"EMAIL" VARCHAR2(200 CHAR),
"SERVICEREQUEST_TEST1A" VARCHAR2(200 CHAR),
"SERVICEREQUEST_TEST2A" VARCHAR2(200 CHAR),
"SERVICEREQUEST_TEST3A" VARCHAR2(200 CHAR),
"MAINTENANCEREQUEST_TEST1B" VARCHAR2(200 CHAR),
"MAINTENANCEREQUEST_TEST2B" VARCHAR2(200 CHAR),
"MAINTENANCEREQUEST_TEST3B" VARCHAR2(200 CHAR),
"OTHERREQUEST_TEST1C" VARCHAR2(200 CHAR),
"OTHERREQUEST_TEST2C" VARCHAR2(200 CHAR),
"OTHERREQUEST_TEST3C" VARCHAR2(200 CHAR),
CONSTRAINT "CARDTEST_PK" PRIMARY KEY ("ID")
USING INDEX ENABLE
) ;
Add the Data
We’ll be looking to display to cards (one for each data row)
Report Card-1 (row 1 data)
Report Card-2 (row 2 data)
Create a “CARDS” Page
Step 1
Display of the web page with two cards, one for each data row.
We want to make the data display something like this:
Lets set up the name header area:
Notes:
We want this area to display ONLY when DisplayTheName =Y
Any othe value will display a blank area.
Place this code in a Notepad for easier use and edit
To implement this logic we have to use the following:
#{if <condition>}
<content>
#{else}
<alternative_content>
#{/if}
In the code we will enter the following:
<div class="t-Report t-Report--stretch " style="width:100%">
{case DisplayTheName /}
{when Y/}
<!--- Code for the table goes here when the value is “Y” -->
{when N/}
<!--- Code for the table goes here when the value is “N” -->
{otherwise/}
<!--- Code for the table goes here when the value is neither “Y” or “N”-->
{endcase/}
</div>
Then we will add the HTML code for the table where the value is “Y”:
<table class="t-Report-report u-textCenter">
<thead class="t-Report-report u-textCenter">
<tr>
<th class="t-Report-colHead u-bold ">Display Name</th>
<th class="t-Report-colHead u-bold ">Job Title </th>
<th class="t-Report-colHead u-bold ">Business Phone </th>
<th class="t-Report-colHead u-bold ">Mobile Phone </th>
<th class="t-Report-colHead u-bold ">Email </th>
</tr>
</thead>
<tbody>
<tr>
<td class="t-Report-cell"> &USERNAME. </td>
<td class="t-Report-cell"> &TITLE. </td>
<td class="t-Report-cell"> &PRIMARYPHONE. </td>
<td class="t-Report-cell"> &MOBILEPHONE. </td>
<td class="t-Report-cell"> &EMAIL. </td>
</tr>
</tbody>
</table>
Here is the code inserted into the “IF” loop
<div class="t-Report t-Report--stretch " style="width:100%">
{case DisplayTheName /}
{when Y/}
<!--- Code for the table goes here when the value is “Y” -->
<table class="t-Report-report u-textCenter">
<thead class="t-Report-report u-textCenter">
<tr>
<th class="t-Report-colHead u-bold ">Display Name</th>
<th class="t-Report-colHead u-bold ">Job Title </th>
<th class="t-Report-colHead u-bold ">Business Phone </th>
<th class="t-Report-colHead u-bold ">Mobile Phone </th>
<th class="t-Report-colHead u-bold ">Email </th>
</tr>
</thead>
<tbody>
<tr>
<td class="t-Report-cell"> &USERNAME. </td>
<td class="t-Report-cell"> &TITLE. </td>
<td class="t-Report-cell"> &PRIMARYPHONE. </td>
<td class="t-Report-cell"> &MOBILEPHONE. </td>
<td class="t-Report-cell"> &EMAIL. </td>
</tr>
</tbody>
</table>
{when N/}
<!--- Code for the table goes here when the value is “N” -->
{otherwise/}
<!--- Code for the table goes here when the value is neither “Y” or “N”-->
{endcase/}
</div>
Now, where go to the page in order to add the new code.
Select the Report in the page
Select the attribute:
Navigate to the “Body” region on the right hand side, below the “Attributes” section and turn on the “Advanced Formating”
Select the Arrow button
Add the code in the window:
Your page should now look something like this:
If you run the page you will see that nothing has changed:
So what went wrong?
We need to make the search criteria upper case, so we will change the code
from {case DisplayTheName /}
to {case DISPLAYTHENAME /}
Now save and run the page and we get the following result:
Next, we will add the rest of the HTML code, making sure that all of the replacement variables
Have a “&” at the start of the variable name.
Are in upper case.
Have a “.” Period at the end of the name.
They should look something like this “&XXXXXXXXXXX.”
<br>
<!-- second line-->
<div class="t-Report t-Report--stretch" style="width:100%">
<table class="t-Report-report u-textCenter">
<thead class="t-Report-report u-textCenter">
<tr>
<th class="t-Report-colHead u-bold ">Service Request</th>
<th class="t-Report-colHead u-bold ">Maintenance Request </th>
<th class="t-Report-colHead u-bold ">Other </th>
</tr>
</thead>
<tbody>
<tr>
<td class="t-Report-cell"> Test1A: &SERVICEREQUEST_TEST1A. </td>
<td class="t-Report-cell"> Test1B: &MAINTENANCEREQUEST_TEST1B. </td>
<td class="t-Report-cell"> Test1C: &OTHERREQUEST_TEST1C.</td>
</tr>
<tr>
<td class="t-Report-cell"> Test2A: & SERVICEREQUEST_TEST 2A.</td>
<td class="t-Report-cell"> Test2B: & MAINTENANCEREQUEST_TEST2B. </td>
<td class="t-Report-cell"> Test2C: & OTHERREQUEST_TEST 2C. </td>
</tr>
<tr>
<td class="t-Report-cell"> Test3A: & SERVICEREQUEST_TEST 3A.</td>
<td class="t-Report-cell"> Test3B: & MAINTENANCEREQUEST_TEST3B. </td>
<td class="t-Report-cell"> Test3C: & OTHERREQUEST_TEST 3C. </td>
</tr>
</tbody>
</table>
</div>
Make sure that you add the code outside of the “IF” loop
<br>
<!-- second line-->
<div class="t-Report t-Report--stretch" style="width:100%">
<table class="t-Report-report u-textCenter">
<thead class="t-Report-report u-textCenter">
<tr>
<th class="t-Report-colHead u-bold ">Service Request</th>
<th class="t-Report-colHead u-bold ">Maintenance Request </th>
<th class="t-Report-colHead u-bold ">Other </th>
</tr>
</thead>
<tbody>
<tr>
<td class="t-Report-cell">TEST1A: &SERVICEREQUEST_TEST1A. </td>
<td class="t-Report-cell"> TEST1B: &MAINTENANCEREQUEST_TEST1B. </td>
<td class="t-Report-cell"> TEST1C: &OTHERREQUEST_TEST1C.</td>
</tr>
<tr>
<td class="t-Report-cell"> TEST2A: &SERVICEREQUEST_TEST2A.</td>
<td class="t-Report-cell"> TEST2B: &MAINTENANCEREQUEST_TEST2B. </td>
<td class="t-Report-cell"> TEST2C: &OTHERREQUEST_TEST2C. </td>
</tr>
<tr>
<td class="t-Report-cell"> TEST3A: &SERVICEREQUEST_TEST3A.</td>
<td class="t-Report-cell"> TEST3B: &MAINTENANCEREQUEST_TEST3B. </td>
<td class="t-Report-cell"> TESTC: &OTHERREQUEST_TEST3C. </td>
</tr>
</tbody>
</table>
Here are the results:
When the “DISPLAYTHENAME” value is “Y” we display the header, otherwise nothing displays.
Mastering the use of APEX Template Application with parameters, directives, and functions is a powerful way to enhance the customization and scalability of your Oracle APEX applications. These tools help reduce repetitive coding by enabling reusable template components that dynamically adjust content and behavior. Incorporating these techniques leads to cleaner, more maintainable code and delivers richer, more interactive user interfaces.
No comments:
Post a Comment