Sunday, June 8, 2008

Dynamic Buttons in Oracle ADF

Standard way to create buttons on the page, is to use drag-and-drop method and JDeveloper wizards. However, sometimes its not enough, especially when there are requirements to apply dynamic rules based on security roles or page groups. With dynamic buttons generation, you can use XML configuration files, this will allow to change displayed buttons and properties right on runtime. I'm writing this post, based on influence I got from Frank Nimphius post - ADF Faces RC - Implementation strategies for global buttons in page templates. Frank describes fundamental approach for global buttons, I'm in my post focusing on dynamic global buttons aspect.

You can download developed application - GlobalDynamicButtons.zip. This sample is based on two Entity objects - Countries and Locations, and provides two JSPX pages based on template JSPX. Button components for both pages are generated dynamically. Here is a navigation flow implemented in current sample:


Both of the pages are based on template. This template defines facet for data-bound components and empty toolbox for dynamically generated buttons:


You can notice, that toolbox contains two toolbar components, button objects will be added to those toolbars. Toolbox is binded to managed bean, this allows to initialize toolbox component on the page:


Next step is to bind BeforePhase property of f:view tag contained on the pages to the same managed bean where dynamic buttons are generated:


#{dynamicGenerator.addButtons} method generates dynamic buttons according to current page, information about current page is accessed through phaseEvent, for example:


Buttons are binded to actions defined in actual page definition using ActionListener, disabled property is also set programatically:


If button is not binded to page definition, and is is related to navigation flow, action expression is set:


Main advantage of described approach is that it allows to have the same code for the same actions in different pages - Commit action, for example. And only what you need to care about, is to define actions in page definition files. Actions for countries page:


Actions for locations page:


On runtime, all buttons specific to current page are generated:


First and Previous buttons are disabled, since first entry is shown, Locations button opens locations from current country:


Different set of buttons is generated and by default there are no locations defined for Argentina, we can create a couple:


When Save button is pressed, records are stored to database and sequence values for LocationId column are assigned:

7 comments:

Anonymous said...

Good demo, I have a couple of questions:
1) Would the same logic apply to page fragments? I don't think they have a view tag.

2) Could you apply this to any of the ADF controls, for instance the Data Visualization controls?

Andrejus Baranovskis said...

Hi,

Thanks!

My answers:

1) Yes, it will work in the same way with page fragments. Fragments will contain af:toolbar, but BeforePhase will be still initialized in view tag on the page. Since page fragment anyway will be included into JSPX page, it works.

2) Yes, it can be applied to any of the ADF controls, since its possible to generate everything using API. When you drag and drop component, XML representation is created, but during compilation this XML is parsed to Java code. So, when you create dynamic components, means you develop directly this final Java code and skip declarative XML.

Regards,
Andrejus

taurus16 said...

I've been trying to dynamically generate button using native Forms capability (no Java Beans). I don't think it's possible. Can't create button except for drawing it, and can't change its name at run time.

Anonymous said...

good demo

i used it to create a dynamic side menu (showdetail item with goLink insed) based on users in database. but i noticed that the code is executed each time i expand one of the showdetailitem. Is theire any manner to run the code only one time?

Joltan said...

hi,
Could anyone let me know
How can I create and assign a dynamic LOV in ADF?

Anonymous said...

Hi Andrejus,

Good post. I have used the same information to generate components at runtime. Your post helped me a lot.
I am stuck with the below issue. I have list of imagelinks generated on pageload and on click of the image link a popup is invoked.
In the popup I am doing some data update and based on those changes, I need to change the colour of the image link below.
To show the update colour i need to reexecute the method which generates the components, but the components gets appended to the exisiting components on the page.

Please suggest

Morgan.

Andrejus Baranovskis said...

I think there is no need to reexecute, just use expression language for image property and apply PPR.

Andrejus