Saturday 23 July 2011

Retaining session state with disabled items

This morning I was developing a page on which some input items could be prefilled from a Before Region Process and should be disabled if containing a value. After some Googling I soon found out that this could be accomplished by setting the disabled attribute.
And indeed, the items with a value appeared correctly with a gray background and non-enterable. But when I submitted the form, the value of the items appeared to be empty.

After half an hour of trying all kinds of things I, examining session state and going through the debug output, I finally found the solution:
- when an item is disabled it's value is set to empty...

So the solution was not to use the attribute disable, but the attribute readonly in combination with the style "background-color:#CCCCCC".

With this solution, the session state is retained.
Visually the result is the same, the only difference is that the cursor can be placed inside the item, but no changes to the content can be made.

Happy Apexing

Wednesday 1 June 2011

User-controlled font size in Apex

In my current assignment I was requested to create a means for the user to control the font size in Apex, looking something like:

A A A


The font would have to change to the size of the A that was clicked on. This is meant to support people who have a hard time reading websites in the 'normal' font size.
The question can be broken down to two questions:
  • How can the font size be controlled?

  • How can it be controled within Apex


The first question is rather easy. The general font-size can be set using CSS. The entry ' * {font-size 12px; } sets the default font size to 12 px. This is overruled by more specific CSS entries like ' h1 { font-size: 15px; }'.
It is however possible to express the font size relative to the 'default' font-size. This is done by using the unit 'em', for example ' h1 { font-size:1.25em; }. This way the font size of the H1 elements is relative to the default font and changes accordingly when the default font is changed. So make sure all the font size in the CSS are expressed in em.


The second question took some more thinking. It is not so very hard to change a css property programmatically, when a button or link is clicked. But when a new page is rendered I want the change in font size to be persistent.
For this an Application Item G_FONT_SIZE is used. The following line is entered in a style section in the page template behind the CSS inclusions:

* { font-size:&G_FONT_SIZE.px; }

This makes sure that the ´default´ font size is set to the value in G_FONT_SIZE (make sure this item always has a value!).
To make this font size work for all the elements on your page make sure that the other font-size declarations are expressed in em's.

The biggest challenge is to change the value of G_FONT_SIZE once a font size is chosen. This means that the session state of Apex needs to be changed. I have given the use of Dynamic Actions a thought because it is very easy to change the session state by calling a PL/SQL process. But this would imply that I would have to create three items that I should put on Page Zero with Dynamic Actions etc... in other words a quite complex solution with lots of elements.
In the end I came up with a more simple solution with less 'moving' parts. Clicking on one of the font size selectors resends the URL to the browser with a request FONTSIZExx in which xx is the font size. So a request FONTSIZE18 will result in a font size of 18px. The request is handled by an Application Process, that fires OnLoad before Header on the PL/SQL condition v('REQUEST') like 'FONTSIZE%'.
The source of the Process is:

declare
l_request varchar2(250) := v('REQUEST');
lc_fontsize varchar2(100) := null;
ln_fontsize number;
begin
if l_request like 'FONTSIZE%' THEN
lc_fontsize := replace(l_request,'FONTSIZE');
begin
ln_fontsize := trunc(to_number(lc_fontsize));
if ln_fontsize between 5 and 100 then
:G_FONT_SIZE := ltrim(to_char(ln_fontsize))||'px';
end if;
exception
when others then null;
end;
end if;
end;

As you can see the script does not just sets the application item but is also checks whether the size is a valid number that is between 5 and 100.

The font size selectors link to:
f?p=&APP_ID.:&APP_PAGE_ID.:&APP_SESSION.:FONTSIZEfont size:&DEBUG.
in which the desired font size in pixels should replace font size.

Happy Apexing