Generating HTML Tags to Present Data
When requirements demand total control over HTML markup, use a Dynamic Content region.
Harkening back to a time when enterprise applications used character mode displays, consider a simple example of an “ASCII art” chart of employee salaries. Of course using an APEX Chart region would look more polished, but this is a fun way to reminisce while learning the basics of the Dynamic Content region. The goal is producing an old-school chart that looks like a Dec VT220 terminal of yore like in the figure below.

Description of the illustration dynamic-content.png
After setting the region type to Dynamic Content, you write a PL/SQL block to generate the HTML markup to include in the page. The example below is a function body that returns a CLOB containing the data and HTML tags the chart requires. First you select the maximum salary used for scaling the salary bars, then loop over the employee rows in descending order by salary. For each employee, you calculate the number of block characters for a 40-character-wide result. The block count is the rounded result of dividing the current employee’s salary by the maximum salary to get a percentage, multiplied by 40. Using the rpad() function, you produce a string of l_blocks bar characters. Then you include this “bar” in the contents of an HTML <pre> tag for preformatted text, along with the current employee’s name and a vertical bar symbol. The code relies on the p() local helper function to incrementally “print” each line of HTML tags and data to the l_content variable. The PL/SQL block returns this variable as its result at the end.
declare
l_max_sal number;
l_bar varchar2(1000);
l_blocks number;
l_content clob;
procedure p(p_text varchar2)
is
begin
l_content := l_content || p_text;
end p;
begin
select max(sal)
into l_max_sal
from emp;
for j in (select ename, sal from emp order by sal desc) loop
l_blocks := round(j.sal / l_max_sal * 40);
l_bar := rpad('▒', l_blocks, '▒');
p('<pre>' || rpad(j.ename, 10) || ' | ' || l_bar
|| ' ' || j.sal || '</pre>');
end loop;
return l_content;
end;