In ADF often We apply LOV on a ID attribute to show it's Description to user, This works good in case of choice list (selectOneChoice) but if we use Input Text with List of Values (<af:inputListOfValues>) or Combo Box with List of Values (<af:inputComboboxListOfValues>) then after selection ID appears on page instead of Description like this
So to avoid this we apply LOV on a transient attribute that shows Description and sets ID value DB attribute, See how to implement this
Here I am using Departments and Employees table of HR Schema to prepare Model
Create a transient attribute of String type (to show Description) in Employes viewObject to apply LOV on that,
Set updatable Always for transient attribute
Now apply LOV on this attribute using Departments viewObject and pass DepartmentId to ID DB attribute of Employees ViewObject using List Return Values
On UI Hints select DepartmentName as we want to show this to user
Now drop Employees viewObject as form on page and see that LOV is working properly except DepartmentName is not appearing though it's Id is saved in DB
To populate DepartmentName of respectived DepartmentId in transient attribute we can use these two methods
1. Using findByKey() in Groovy Expression
We can use Groovy Expression to populate transient attribute value based of Key attribute of Lov ViewObject. Here Department Id is primary key of Departments ViewObject so we can use Lov Accessor to find DepartmentName using findByKey method
I have used this expression, here I made a JBO Key using key attribute DepartmentId (Departments ViewObject) , DepartmentsVO1 is the name Lov ViewAccessor
if(DepartmentId!=null){ oracle.jbo.Key keyVal=new oracle.jbo.Key(DepartmentId); return DepartmentsVO1.findByKey(keyVal,1)[0].getAttribute("DepartmentName"); } else{ return null; }
Now go to viewObject source and change expression trust mode to trusted
All Done :) Run and check application, LOV Description is appearing
2. Using Java Code in ViewObject RowImpl Class
We can write logic to get LOV Desciption in transient's getter method in RowImpl Class of Employees viewObject
First step is to create RowImpl class for Employees ViewObject
Go to RowImpl class and write this code in getter method of transient attribute, this code filters Lov accessor using repective DepartmentId and retrieves DepartmentName
/** * Gets the attribute value for the calculated attribute DeptNameTrans. * @return the DeptNameTrans */ public String getDeptNameTrans() { Integer departmentId = null; String departmentName = null; //Check if DepartmentId is not null then get DepartmentName for that Id if (getDepartmentId() != null) { departmentId = getDepartmentId(); //getDepartmentsVO1 is ViewAccessor of LOV ViewObject Row[] deptRows; deptRows = getDepartmentsVO1().getFilteredRows("DepartmentId", departmentId); if (deptRows.length > 0) { departmentName = deptRows[0].getAttribute("DepartmentName").toString(); } return departmentName; } else { return (String) getAttributeInternal(DEPTNAMETRANS); } }
All Done :)
Sample ADF Application (Jdev 12.1.3)- Download
Cheers :) Happy Learning
Excuse me i get this error The variable [DepartmentsVO1] is Undeclared. My version is 12.2.1. Can you help me resolve this ?
ReplyDeleteHuy
DeleteCheck that DepartmentsVo1 is added as viewAccessor in Employees VO or not ?
Use Lov Accessor name in expression and use findByKey on that
Ashish
thank you
DeleteHi Huy do quang. Did you fix that issue of undeclared error?
Deleteyou have to check the dependency of departmentID in the transient Attribute
ReplyDeleteHello
ReplyDeleteI just went through your blog. This works when the value has been selected .
I have a scenario when i want input box to be populated at run when user selects a value
Can you help
Thanks
Pritee
Hi Pritee
DeleteThis will work in your case too, just put proper partial triggers on input text
Ashish
This comment has been removed by the author.
ReplyDeleteHi,
ReplyDeleteIs there any performance impact by using this approach ? Suppose if i am showing this as a table and it have large number of rows. Will this execute the query of view Accessor for each row ? or it just find the row from cache ?
What is your opinion about creating an association And selecting those two EOs in the View Object by using that association? So that you can show the name from second EO?
Which will be performance wise better?
Thanks,
Gijith
Hi Gijith
DeleteI don't think that it'll affect performance because view accessor doesn't execute VO query everytime , It filters data from it's own rowset that is fetched on first execution of viewObject
I am not sure about the association part , never tried that
Ashish
Hi, I tried this approach today and having a problem. Could any one please help me?
ReplyDeleteMy scenario is exactly same as the above and I used the LOVVO to get the description. the Description is correctly populating when I load the screen and when user select a different ID from the List of value it get reset to old ID and Descrption value, it never set to what I select in the LOV.
I removed the Groovy expression, then the Load screen load blank description but when I select a value that change properly only when I use the groovy expression it reset to the initial value. I tried the java approach also but its the same behavior. Any clue what might be happening? I am jusing JDev 12.2.1.2.
Figured.....changing the default List Type in the LOV UI-Hint tab to Input Text with List of Values made the tric for me. I was thinking since it was a default type and when I drag and drop if I change the type logically it will work....but apparently not.....:)
DeleteGlad you got it working
Delete