Thursday, May 1, 2014

Adaptive Form with Dynamic ADF Attribute Value Binding

You can implement adaptive forms, generated on runtime using ADF Dynamic Form component in 11g R1 or 11g R2 (keep in mind - ADF Dynamic Form component is not supported with Facelets). In 12c you could use new ADF Dynamic Component to generate adaptive forms. All good, but customisation options are limited. For example, if you would need to define Value Change Listener for adaptive form UI component, this would be quite tricky as there is no direct access to ADF UI component properties.

If you need to control how UI is generated, you could implement your own ADF UI generation procedure. This would allow to manage ADF UI and ADF Bindings construction on runtime. I'm going to explain high level framework for such task and share sample application with ADF dynamic UI and ADF Bindings implementation.

Here you can download sample application - DynamicAttributeBindingApp.zip. The key part of this application is in the method below:


This method creates attribute binding dynamically, so you don't need to define attributeValues property in page definition on design time - this will be created on runtime. PNAME_TextField identifies simple binding (you could create different binding for LOV or Check Box). Iterator name must be set, along with attribute name and binding ID (exactly as it is defined in Page Definition XML, only programmatically this time). This code is not documented, you must check ADF source code for different scenarios.

Sample application contains ADF BC components, there is regular VO for Employees with a list of attributes defined:


There are no bindings for these attributes in Page Definition, all of them will be generated automatically on runtime. In real use case, you would have dynamic VO in the background or switch Iterator to use different VO's at runtime. This would allow to synchronise and generate adaptive form on runtime:


There are 3 steps to follow. Firstly we would need to construct on runtime a list of attributes to be displayed. This could be a custom method invoked from forEach ADF UI component:


This method gets a list of attributes from iterator and constructs a list of attributes to be displayed (some attributes could be hidden):


Second step is to render different attribute types. Text, number and date should be rendered differently, with different formatters or ADF UI components. For this purpose, we could use ADF UI switcher component and call custom method to return current attribute type:


Custom method retrieves information about given attribute and returns type to be used in the switcher (here I'm checking for text, date and numeric type only):


Third step is to provide properties for actual ADF UI component we are going to display. All properties as value, label, columns, validator, etc. should be provided. Expression language points to our custom method:


Custom method checks, if such attribute binding was already created, if not - it will be created. Attribute binding is created through a method described in the beginning of this post:


This is how it looks on UI - form is rendered same way, as it would be prepared on design time. I was checking if validation is executed correctly - as you can see, validation message is displayed properly:

4 comments:

HusainD said...

Very cool, Andrejus.

A lot of components are now automatically generated by framework and we have control over display and ordering. But your framework extension opens up tons of possibilities. :)

Andrejus Baranovskis said...

Thanks Husain :)

Anonymous said...

Hello Andrejus,

Very GOOD work.

The application link is not working, could you fix it?

Regards

KM

Andrejus Baranovskis said...

I tested just now, it works fine. Something wrong with your internet.

Andrejus