Wednesday, July 29, 2015

APEX and the Order Items are Submitted

This is the last post in a multi-part series on how APEX submits and processes input elements from your browser to the server. The goal is to understand the effects of moving elements around the page. It is important to read these articles in the following order.

Back to Basics
APEX and the HTML Form
APEX and the Order Items are Submitted
Why does APEX do this? (by John Snyders)

The goal of this article is to highlight the effects of moving items and regions around on a page. This article will be broken into four sections, a high level recap from the previous two articles, moving an APEX item, moving an APEX item along with its corresponding p_arg_names element, and finally a conclusion. It will reference and build upon the example from the previous article.

Recap

I can't stress enough how important it is to read the previous two articles. To recap, when APEX submits the page it'll use the following values to map the HTML elements to their corresponding APEX items.

APEX Item ID    |  APEX Item      |  Element Name
p_arg_names[1]  |  P1_FIRST_NAME  |  p_t01
p_arg_names[2]  |  P1_LAST_NAME   |  p_t02


Moving APEX items

They're some times where it is required to move APEX items around the page after it has rendered. This example will highlight what happens when an item (and only the item) is moved.

Using the example from the previous article suppose you move P1_LAST_NAME before P1_FIRST_NAME using jQuery. 
$('#P1_LAST_NAME').insertBefore('#P1_FIRST_NAME');

The page will look like:


When the page is submitted, everything still works as expected. P1_FIRST_NAME = Martin and P2_LAST_NAME = D'Souza. In this case, it was safe to the move the item around the page since only the p_t02 element was moved. The order of p_arg_names (which APEX uses to map to apex_application_page_items.item_id an p_txx) was not changed.

Moving an APEX item along with its corresponding p_arg_names element.

Using the previous example, suppose the items were split up into two regions as shown below. To help out, each region has been assigned a static id of region-one and region-two respectively.


Using the following code, Region Two is moved above Region One:
$('#region-two').insertBefore('#region-one');

The screen then looks like:


Referring to the previous article not only has the input element for P1_LAST_NAME moved, but it's corresponding p_arg_names hidden element was moved and its overall order has changed. Now when the page is submitted the following is sent to the server (note the order):

p_arg_names[1] = 32629863123858907 - Maps to APEX item P1_LAST_NAME
p_arg_names[2] = 32629789701858906 - Maps to APEX item P1_FIRST_NAME

p_t01 = Martin
p_t02 = D'Souza

Just to recap and highlight what is about to happen:

p_arg_names[1] (P1_LAST_NAME) maps to p_t01 (Martin)
p_arg_names[2] (P1_FIRST_NAME) maps to p_t02 (D'Souza)

You can see the mis-match occur below once the page has been submitted. Martin is stored in P1_LAST_NAME and D'Souza is stored in P1_FIRST_NAME.

Conclusion

Be very careful when moving APEX items around the page. As a guideline, it's usually safe to move individual items, provided you're not moving any p_arg_names hidden elements. If you're moving a region and/or any p_arg_names elements you may get invalid data assignments if the order of p_arg_names is changed.

This issue was first discussed a very long time ago between myself and Dan McGhan on the Oracle Forums: https://community.oracle.com/message/3182532

Tuesday, July 28, 2015

APEX and the HTML Form

This is the second post in a multi-part series on how APEX submits and processes input elements from your browser to the server. The goal is to understand the effects of moving elements around the page. It is important to read these articles in the following order.

Back to Basics
APEX and the HTML Form
APEX and the Order Items are Submitted
Why does APEX do this? (by John Snyders)

The goal of this article is to highlight how APEX actually processes the data that is sent data from the browser to the server when a submit button is pressed.

Suppose you have a simple page with two elements: P1_FIRST_NAME and P1_LAST_NAME as shown below:


Stripping out a lot code, the underlying HTML code for this page looks like:
You'll notice that despite their being four input elements they're really only three unique sets of names that are used: p_arg_names, p_t01, and p_t02.  When the page is submitted the web server (APEX) will get/processes the following elements:

p_arg_names[1] = 32629789701858906
p_arg_names[2] = 32629863123858907

p_t01 = Martin 
p_t02 = D'Souza

None of the data sent back to the server make reference of P1_FIRST_NAME or P2_LAST_NAME. As well, p_arg_names is stored in a top down order of how they are in the page.

p_arg_names values are actually the IDs for each of the of the page items as highlighted in the following query:
select item_id, item_name
from apex_application_page_items
where 1=1
  and application_id = 118
  and page_id = 1;

ITEM_ID           ITEM_NAME
----------------- -------------
32629789701858906 P1_FIRST_NAME
32629863123858907 P1_LAST_NAME
APEX is able to map the data back to their corresponding APEX items by first mapping the values in p_arg_names to the apex_application_page_items view and then using the values in the p_txx to retrieve the data that was submitted for each item.

The order that the values are submitted in for p_arg_names must match the p_txx values for APEX to correctly map the values to their appropriate APEX item. I.e. p_args_names[1] will link to p_t01 and p_arg_names[2] will link to p_t02 etc.

Monday, July 27, 2015

Back to Basics: The HTML Form

This is the first post in a multi-part series on how APEX submits and processes input elements from your browser to the server. The goal is to understand the effects of moving elements around the page. It is important to read these articles in the following order.

- Back to Basics
APEX and the HTML Form
APEX and the Order Items are Submitted
Why does APEX do this? (by John Snyders)

As the above note suggests, the next few articles will cover how APEX submits and processes input elements in a page. This article is specifically focused on the basics: HTML forms. It's important to understand how the HTML form tag works and posts input elements. They're other articles that cover this in much more detail and this article will only cover the high level concepts.

Any web page that submits data to it has the following structure:
First name: Last Name:
This will produce a page that looks like:

When the page is submitted the following is sent to the server:

firstname = Martin
lastname = D'Souza

Despite what most developers think, the element's IDs (in this case foo and bar) are not submitted to the server. The server never sees/knows about them. Instead it must use the element's name attribute.

HTML form behaviour has another nice feature that allows for the same name to be used multiple times. Modifying the previous example, the next example will use the name person for both the first and last name elements:
First name: Last Name:
Now when submitting the page the following is sent to the server:

person[1] = Martin
person[2] = D'Souza

The server processes the person attribute as an array of data. Using pseudo code, this is how a web server scripting language may process the data:

...
firstName = htmlForm.person[1];
lastName = htmlForm.person[2];
...

The two key items to take away from this article are:

- When elements are submitted, only the name attribute is sent to the web server and is used to reference the element.
- A form can contain multiple elements with the same name. In this case the web server will view them as an array of data.