Sunday, November 24, 2013

Controlling ADF BC Mandatory Attribute Validation Conditionally

I was looking for a solution to control ADF BC attribute mandatory validation conditionally, and there is one - we can implement dynamic switch for attribute mandatory validation. Thanks to Steve Muench, who was helping to implement this requirement - I'm able to provide working sample. The main idea is - based on master attribute value, set dependent attribute to become mandatory/non-mandatory automatically. This will be implemented by controlling dynamic mandatory attribute rule in ADF BC level.

Make sure to download sample application, to test this use case - DynamicMandatoryAttrApp.zip. Test is fairly simple, there is special column displaying true/false values - meaning if CommissionPct attribute is set to be required or no in the current row. CommissionPct attribute is set to be mandatory, if Salary attribute value is greater than 10000:


You should see for Employee ID = 108, CommissionPct attribute is set to be mandatory. Try to set Salary attribute value for this employee to be less than 10000, CommissionPct attribute becomes non-mandatory instantly:


We are going to check now, how such functionality is implemented in ADF BC. There is custom Entity Attributes Hints class registered in EO implementation class:


Through this custom class we can intercept all calls to ADF BC to retrieve hints for given attribute. Mandatory property is one of the hints, this is how we can return true or false conditionally.

If you are running ADF version starting from 11g R2 or 12c, there is internal issue - it requires to set attribute index explicitly through getAttributeHints(name) method. Otherwise, custom class for Entity Attribute Hints - will be ignored:


In the custom class for Entity Attribute Hints, we can override standard method - getHint(locale, name). In this method we could evaluate conditionally or mandatory checks, as in this example CommissionPct attribute is marked to be mandatory, only if Salary value is greater than 10000:


Initially, CommissionPct attribute is set to be non-mandatory:


There are several changes required on ADF UI level, to make it work correctly. I would recommend to set contentDelivery=immediate and immediate=true for the ADF table component, this allows to reduce number of validation error popups:


When Salary attribute changes, we need to refresh dependent CommissionPct attribute, however it would not work to use regular PartialTrigger dependency and bypass validation error. We need to create binding reference and call partial target refresh programmatically. Read more here - Conditionally Required Fields in Oracle ADF Faces Rich Client. Similar binding is created for Panel Collection:


Salary attribute is set with AutoSubmit=true and Value Change Listener (we refresh table component):


Refresh is done from table component:


Make sure to change ADF UI mandatory expression, to use row.bindings.CommissionPct.hints.mandatory. Otherwise, with default expression generated for ADF table column attribute by JDeveloper, ADF UI fails to trigger getHint method in ADF BC for mandatory check:

2 comments:

Ahmad Al-Zamer said...

Hello,
I am wondering if it's possible to use this method to enforce ADF to use my custom formatter?

what is want is to format input and output of salary fields to be like:
123 456 789.781
but I can't use space as a grouping separator,I can use DecimalFormat class to achieve what I want, but how can I tell ADF to use it?

Andrejus Baranovskis said...

Yes, you can override format method in the same class.

Andrejus