Friday, March 20, 2009

APEX Global AJAX variables - gotta love them

I've just added a fully AJAX enabled editable tree on my demo site.
All modifications to the tree are transmitted to the database via an application process using AJAX.

Values are submitted using wwv_flow package variables:
  g_x01 .. g_x10

The application process simply calls a database package, which references the wwv_flow package variables and updates the data.
The key to AJAX functionality in Oracle Apex is based around these "Global input variables for AJAX utilities".

Using these variables, a little javascript to call a simple application process and then we handover to PL/SQL - back in every Oracle developers comfort zone.

This example has a fair bit going on, to see a simpler example check out:


Louis-Guillaume Carrier-Bédard said...

Hi Mark,

This is a good demo.

Can you give us more information about the following variables:

I want to use them the good way. What are your standards?

example: When I edit a tree element, I can use firebug to look at the HTTPRequest. I see g_widget_num_return=15 and the interactive report shows 15 rows. Why not use g_x10=15 to do the same? Give me some advices plz. :)


Louis-Guillaume Carrier-Bédard said...

I found the article Carl wrote about those variables.

Anonymous said...

The link in your article goes to page 2011 where as your Tree Editor is actually on page 2013.

Did you mean for this?

Mark Lancaster said...

Hi Louis-Guillaume

The g_widget_num_return call your referring to is from a call to refresh the interactive report.
It's a left over call from when I was debugging.

Carl indicated in his post in the replies that he was passing a value all the time, so g_widget_num_return was just convenient.
He also said to avoid using g_widget_name (did not elaborate), and that g_clob_01 may not survive in future releases.

Ultimately, the variables are simply PL/SQL package variables that we are free to use, safe in the knowledge that we aren't causing nasty side effects.

As far as the variables go, all I have to go on is the wwv_flow spec:

g_widget_name varchar2(255);
g_widget_mod varchar2(255);
g_widget_action varchar2(255);
g_widget_action_mod varchar2(255);
g_widget_num_return varchar2(255);

g_x01 varchar2(32767);
g_x02 varchar2(32767);
g_x03 varchar2(32767);
g_x04 varchar2(32767);
g_x05 varchar2(32767);
g_x06 varchar2(32767);
g_x07 varchar2(32767);
g_x08 varchar2(32767);
g_x09 varchar2(32767);
g_x10 varchar2(32767);
g_clob_01 clob;

My standards:
- g_x01 .. g_x10 are much bigger, so I save them for my data
- g_widget_name identifies the module (package) to call
- g_widget_action identifies the operation to perform
- other variables future use ???

I use a single application process for all my AJAX code which simply calls an ajax "gateway" package.

The "gateway" package delegates to an appropriate package based on the g_widget_name value.

Each package spec contains a widget procedure and looks like this:

procedure widget;
END ext_tree_editor;

The widget procedure then calls a private procedure, determined by the g_widget_action value.

i.e. application process -> gateway package -> widget package [g_widget_name] -> widget procedure [g_widget_action]

Andy Seddon said...

Hi Mark,
Sorry if this a dumb question, but... once inside APEX, are you updating an existing list (As in a "Shared Component -> List"). Or are you using another mechanism within APEX?

Mark Lancaster said...

Hi Andy

For this demo I'm loading a APEX list into a collection. Any changes made by a user are applied to the collection using the WWV_FLOW_COLLECTION package.

I'm using a collection so changes are limited to an individual users session, and aren't permanent.

To apply the changes permanently back to the APEX list, you would use the WWV_FLOW_API package to do so. Just do a component export of a list to see the steps required.

Of course, you could also create your own tables and manipulate as you wish.