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:

Friday, June 6, 2008

Oracle Forms Modernization on Oracle Mix

I have created Oracle Forms Modernization group on Oracle Mix. Everyone for whom this topic is interesting are welcome to join.

I want to see this group as place where Oracle Forms to SOA modernization methodology and strategies will be discussed, as well as technical issues. It should be a good place to share experience and best practices from related projects.

Wednesday, June 4, 2008

Greece in One Day

This time I'm not only providing Oracle Fusion Middleware consulting in Greece, Athens. But doing some active tourism activities as well. If someone will be in Greece, I can recommend to take 1-day Saronic Island Cruise, it will help you to understand this country in short period of time.

I have visited three islands - Aegina, Poros and Hydra. Last one became my favorite one:


Yeah, sometimes it is good to be away from my MacBook ;-)

Wednesday, May 28, 2008

ADF Task Flows - Managing Transactions Based on Different Appication Modules

In March, I was blogging about cool feature available in JDeveloper 11g: ADF Task Flows - Managing Transactions. In this post, I want to update the same topic and to describe one more nice specific of this feature. This specific is a possibility that allows to use Data Control elements from different Application Modules in the same transaction. You know, Commit action is done per Application Module, but with ADF Task Flow we can commit transaction ones and don't care how many Application Modules will be involved.

You can download sample application for this post - ADFTaskFlowTransactAppModules.zip. It contains two Application Modules, one for Jobs and second for Locations:


Created Application Modules are exposed to ViewController layer:


Data Control elements - JobsView1 and LocationsView1 are dropped into two different pages. Those two pages are implemented in Bounded ADF Task Flow. New transaction is initialized, when defined task flow is opened. Changes are commited when Return activity is reached, where Commit is set:


And main advantage of all this - possibility to concentrate on transaction logic and be independent from manual handling of different Application Modules.

How it works - we run transaction that is based on two tables - jobs and locations:


We change data that comes from first Application Module, press button and move to next table:


Second Application Module supplies data to locations table, here we change data again and press button to return from transaction - changes in both tables based on different Application Modules are saved to database automatically:

Sunday, May 18, 2008

LOV in Create Form with Mandatory Fields

One more reason why Oracle Rocks Again - JDeveloper 11g TP4, its a solved issue with LOV fields in Create form that contains mandatory fields. I have documented this issue some time ago on OTN. Also I have described it in my previous post with sample application - Hints for List-Of-Values (LOV) in JDeveloper 11g TP3. The main problem was, that it was impossible to use LOV in Create form with even one or several not associated mandatory fields - validation errors were shown when value was selected in LOV window. Actually, similar problem was in JDeveloper 10.1.3.x also, but now it is solved. In this post I will describe how it works now.

You can download sample application I have developed - LOV11Create.zip. This application contains two fragments, one is used for Search and Edit forms and second for Create form. Fragments are implemented in Task Flow, which is dropped to JSPX page as Region. I have developed Create form for Employees entity and have defined two LOV components - one for JobId and second for DepartmentId attributes.

In 10.1.3.x to develop Create form, you was using invokeAction in Page Definition. However, it is changed now. In 11g you need to use Method Call activity in your Task Flow to invoke Create mode and pass navigation to a form - it's a key point now. In diagram below, create navigation rule points to invokeCreate Method Call activity. This activity executes Create action associated with your Data Control and pass navigation to a form that will be displayed in Create mode:


Don't forget to set SkipValidation = true property in Page Definition file created for invokeCreate Method Call activity. This will allow to open our form with mandatory fields in Create mode.

In Property Inspector you can see that invokeCreate activity invokes #{bindings.Create.execute} action, exactly what we want:


On runtime, when form is opened in Create mode, we can use LOV component now:


Provide values for other not associated fields contained in the form:


And save entered record to the database:

Sunday, May 4, 2008

ADF Faces Rich Client - Complex Validation

Hey, my first application with JDeveloper 11g TP4 ! :-)

During this week I was working on business rules implementation design in my project. I got one really not usual business rule for UI, the thing is that client is Oracle Forms customer. So, in general this business rule was defined like - "When validation for particular field is failed, user must be not allowed to move to other fields". If you have noticed, in ADF Faces RC by default users are allowed to move focus to other fields and enter data, even if validation for some field is failed.

I was trying to use direct DOM manipulation to implement this rule, but without success. I have discussed this with Frank Nimphius (Principal Product Manager in Oracle) and he suggested working solution based on ADF Faces client framework. Actually I will document it in this blog post. Also you can read ADF Faces Rich Client - JavaScript Programming Nuggets page from Frank Nimphius blog.

I have implemented described business rule in ComplexValidation.zip sample application. Mandatory validation rules are applied for 3 fields - Last Name, Email and Job. Field - Job, contains LOV component and is associated with description text field - Job Title. And finally, application contains one optional Number type field. Sample is based on HR schema.

As you have noticed, there are 3 cases for validation in developed application - Mandatory, Mandatory LOV and Number type. You can easily implement your own rules, if will follow described techniques. Let's describe complex validation implementation steps for all 3 cases.

JavaScript code in all three cases will be written in af:group section created in af:document metaContainer facet:


1. Mandatory field

Rule description: When value is set to NULL and Tab button is pressed or mouse cursor is moved, focus must be returned back to Mandatory field where validation fails. To lock focus, JavaScript function is used, where ADF Faces client framework method is invoked:


Logically thinking, this function must be invoked when user is trying to move focus from current field with failed validation. With ADF Faces RC you can use af:clientListener operation component.


This component allows to invoke JavaScript function based on event. In our case, JavaScript function will be invoked when component loses focus - on blur:


At runtime, if value for mandatory Last Name field is removed:


Focus will be locked for Last Name field:


User will not be able to change values in other fields or press any buttons available on the page. The same applies for Email field.

2. Mandatory LOV field

Rule description: When value is set to NULL and Tab button is pressed or mouse cursor is moved, focus must be returned back to Mandatory LOV field where validation fails. Description text field associated with LOV field must be cleared, when validation in LOV field fails. In this case, I have used af:serverListener operation component additionally:


af:clientListener is defined similar like in previous case:


For af:serverListener I have provided its name in Type field and have specified method name from Backing bean. handlerMethod() is a Java method and this method will be invoked from JavaScript function in order to set empty value for description text field:


JavaScript function code:


Java method code:


Value of description text field in this sample application is binded to a method in backing bean:


Method in Backing bean provides value for description text field according to a value set from handlerMethod():


At runtime, when user clears value in mandatory LOV field:


Focus will be locked for this mandatory LOV field and associated description text field will be cleared. And of course, validation error message is displayed:


If you don't know already, nice feature of LOV component is that LOV window is opening automatically when wrong value is entered and Tab button is pressed (when AutoSubmit=True):


Tab button is pressed and LOV window is opened, since non existing value was entered originally:


When correct value is selected, associated description text field is refreshed again and user can move focus to other fields:


3. Number type field

Rule description: Focus is locked, when invalid value is entered. This rule is implemented in similar way as a rule in first case. JavaScript function is different:


When wrong value is entered, focus is locked again and validation error message is shown:

Friday, May 2, 2008

Oracle Rocks Again - JDeveloper TP4

Just about hour ago I have downloaded and extracted JDeveloper TP4. My first impression is very positive. I have noticed those changes so far:
  • Tool UI (functional and graphical) is improved, this will allow to develop even more quickly.
  • Tool performance is improved. Dialogs and Design windows are working faster and embedded OC4J start time is reduced.
  • Oracle ADF Faces Rich Client components behavior is improved. When running developed application, components are opening and closing in more nice way.
  • And of course, bug fixes and one more time bug fixes.
In my notebook (Apple MacBook Pro, 2.5 GHz Core Duo, 4 GB, Win XP through Boot Camp), JDeveloper TP4 runs as quickly as common Windows application.