Adventures in building a Form with APEX_ITEM
Recently I needed to build a dynamic form whereby the fields were based on data and it was not possible to use the APEX flex fields plugin.
The way forward then was to create input fields on screen using APEX_ITEM.
In this example I’ll create 6 fields: A hidden item, a Name and Job to hold alphanumeric character input, a hire date shown as date picker and two number fields to hold the salary & commission.
I first created a PL/SQL Dynamic Content Region and used htp.p to output 6 different calls to APEX_ITEM
and the result was….awful.
The issues we have are:
- All fields are placed horizontal
- None of the fields have labels even though I specifically gave one in the call to APEX_ITEM
- All the fields are basic HTML with no styling
When I inspected the page, I found that the labels do indeed exist but the class u-VisuallyHidden prevents them from being shown.
If I remove the class with jQuery it looks even more wrong. There’s something very wrong with these Text Fields I thought.
Then it struck me; when you use a Text Field page item in APEX, it is automatically set to the Optional Label Template and APEX_ITEM components do not have assigned templates.
Based on the Optional Label Template, I set about creating a function to format the output of APEX_ITEM to add more HTML tags, classes and a container tag to more closely resemble the template.
Once this function was in place, the form started to take shape.
I modified this function further by adding right alignment to number fields (remember there is no APEX_ITEM.NUMBER function) and a required class (together with an asterisk icon) for required fields, even adding tooltips on the labels. All this was researched by inspecting the HTML of how APEX draws page items.
The next issue encountered was validation – and this was a big issue.
When the page is submitted, (in my example I used a save button) and validation fails, then the alert region is displayed. The region is redrawn and, frustratingly, the user loses all their input.
This called for a change of approach; to solve this issue I created a single member collection called DYNAMIC_FORM and. I then created an After Submit Process which updated the member with the values from the form items (easily accessed through APEX_APPLICATION.G_F0X). Then when the validation failed, I could restore the users input from the collection back in to the form fields.
This also meant I had to modify the way the region is created. I used the p_value parameter to pre-populate the items when they are drawn with values from the collection.
This worked a treat. When the page is submitted, the form values are placed in to session. Then when the validation fails, the user input is not lost. If the validation succeeds I can clear the member details ready for the next record.
An alternative way of retaining the apex_item values is by setting p_value directly to the APEX_APPLICATION.G_F0X values. Although the first time the user accessed this region an error was raised because it was trying to access a value in the array which wasn’t set yet. In this case a simple wrapper function can be used to determine if array values exist.
Next issue was with the datepicker: The problem was, if the user has typed in an invalid date and the page is submit; then the dynamic region produces an error as it cannot be redrawn with an invalid date. I already knew the solution to this as I had seen this before. Instead of calling apex_item.date_popup2 with the parameter p_value just use p_validation_date instead. This way the date picker can be displayed without a problem whatever the input.
And finally; my form needed to hold up to 90 fields however apex_item only supports 50 fields on a page (F01 to F50). Not a problem, in this case I stored all 90 fields in a single array of F01. This is fine since I knew that job was the 2nd value in the array and commission was the 5th value.
In summary, APEX_ITEM is a powerful package and has helped my out on numerous occasions. However when building a dynamic form there are styling and validation hurdles to overcome.
Matt is an experienced APEX solution designer having designed numerous complex systems using a broad range of Oracle Technologies. Building on his previous experience of Oracle Forms & PL/SQL, he is entirely focused on providing functionally rich APEX solutions. Matt promotes APEX as a software platform and openly shares best practises, techniques & approaches. Matt has a passion for excellence and enjoys producing high quality software solutions which provide a real business benefit.