Thursday, December 6, 2012

Force browser to prompt to save password

Today I've got one interesting question from my co-worker that I've never think of (because I always have this option turned off in my browser). How to force browser running APEX application to prompt to save password on login page? With a little googling about HTML from elements in a few seconds I've got answer. It's pretty simple. The only thing you have to do is to set page property "Form Auto Complete" (under Security region of page properties) of login page to "On".

If you have turned on right properties in your browser it should work as a charm (even in IE).

There are some security issues regarding turning this option on, but this is not topic of this post.
Personally, I don’t use this option and probably never will. :)

Thursday, November 22, 2012

Condition Type – Request Is Contained within Expression

I've just remembered the issue that I've had few months ago with unexpected (at least for me) behavior of condition type Request Is Contained within Expression. A real headache to debug and figure out.

At first glance, when I saw this condition type, I’ve expected that requests must be in Expression 1, comma delimited, and that there must be an exact match on condition evaluation. But that’s not the case.

For example, if you have three buttons with requests CREATE, CREATE_ANOTHER and CREATE_AND_RETURN, and process condition with condition type Request Is Contained within Expression where Expression 1 equals CREATE_ANOTHER,CREATE_AND_RETURN:

the process will be executed no matter which button you press, even the one with request CREATE, because condition is evaluated as true when request string is contained within Expression 1 (without exact match).

So to avoid such behavior I always use condition type PL/SQL Expression with condition “:REQUEST in (...)”, for example:

Crazy little thing called dialog... cost me a lot of nerves. I had a simple form and after every page submit, session state value of items were sequentially shifted (after page submit, value of first item become value of second item, value of second item become value of third item and so on...).

Initial form state

Form state after first submit

Form state after third submit

The first time after many years working with APEX I’ve got really pissed off. I’ve tried to isolate the problem, so I’ve deleted most of page items and had a form with only two items, with no processes, branches, dynamic actions...and it happened again – after submit, item values sequentially shifted. Then I’ve tried to create new page and all worked fine.

No matter what, I wanted to discover what’s the problem on the old page. After some time I got to POST request and found a clue. The items were submitted, but the sequence wasn’t right. I’ve got items posted in order from p_t02 to p_t03 and the p_t01 was missing. So I’ve opened FireBug and found it just before </BODY> HTML tag in jQuery UI Dialog. And the answer was here!

POST request

On page 0 there was a region (with “missing” item – p_t01) used for jQuery Dialog. After initialization of jQuery dialog, dialogs HTML was generated just before </BODY> HTML tag and the dialog region was pulled from its original position (inside <form id=” wwvFlowForm “> HTML tag) and moved just before the end of HTML body. As you may guess, only items inside <FORM> element are submitted to session state.

Quick solution of this problem was to put regions used for jQuery dialogs as last regions on page, so its items will get the last p_tXX values for name HTML attribute.

You can find test example here.

I hope that this post will help someone someday! :)

Edit on July 29, 2015:
More about this problem and order of submited items you can find here

Friday, November 16, 2012

View data from APEX collections in PL/SQL IDE

If you ever wondered, there's an easy way to see data from APEX collections in your favorite PL/SQL IDE (PL/SQL Developer, TOAD, SQL Developer...).

You only have to run short anonymous PL/SQL block and define:

  • workspace name (workspace ID)
  • application ID
  • session ID.

Here's the script:

  v_workspace_id apex_workspaces.workspace_id%type;
  select workspace_id
    into v_workspace_id
    from apex_workspaces
   where workspace = '&WORKSPACE_NAME';
   -- Set Workspace ID

   -- Set Application ID
   apex_application.g_flow_id  := &APP_ID;     
   -- Set Session ID
   apex_application.g_instance := &APP_SESSION;  

After you run this script you can easily do query from apex_collections view and you'll see the result.

Thursday, October 11, 2012

Dynamically changing item labels

Today I’ve got one idea how to simply change (in my example translate) item label dynamically with value from database using shortcuts.

First of all you have to create database table to store translated labels, associated to item name and language. For example:

  create table item_labels (
      item_name varchar2(255)
    , item_label varchar2(4000) 
    , lang varchar2(10));

After that you have to create function for fetching label for specific item and current language (that can be set in some application item):

  create or replace function get_item_label (p_item_name varchar2
                                           , p_lang      varchar2 default 'EN')
    return varchar2
    v_item_label item_labels.item_label%type;
      select item_label
        into v_item_label
        from item_labels
       where upper(item_name) =  upper(p_item_name)
         and upper(lang)      = upper(p_lang);
     return v_item_label;
    when no_data_found then
      select pi.label
        into v_item_label
        from apex_application_page_items pi
       where pi.application_id = v('APP_ID')
         and pi.page_id = v('APP_PAGE_ID')
         and pi.item_name = p_item_name;
      return v_item_label;
  end get_item_label;

To dynamically change item label you have to modify definition of item label template to hide default label and to show one from database (using TRANSLATE_LABEL shortcut).

And the last step should be creation of shortcut (in my example named TRANSLATE_LABEL) that for source has PL/SQL function body that returns translated label:

At the end just add data to item_labels table and apply item label template. Don’t forget to create application item CURRENT_LANGUAGE that can be set dynamically.

For item label with help definition should look like this: