ADF – warn about changes


It is a very common requirement in any application to warn about changes when a user is going away from a transaction page without applying the data.
To achieve this, uncommittedDataWarning="on" must be set on document tag.

And if the user wants to go away from the page without saving, we also need to do rollback on the data. But if the data is rolled back, uncommittedDataWarning will not work as there wont be any pending changes anymore after rollback.
So in such case, instead of doing rollback in actionlistener or action of the navigation button, rollback should be included in adfc-config after navigating away from page. (i.e after user clicks on OK button of warning popup).

Steps to do this :
1. Right click on adfc-config , Insert inside ADF Task Flow –> ADF Task Flow –> Method Call.
2. Give some unique Activity Id
3. select from expression builder, the rollback binding from ur page definition
4. Give an outcome to navigate to destination.
5. Now add a control flow between source page and this method call , and another control flow from this method call to destination page.

This way rollback is achieved before navigating to destination page and after the warning message.

http://www.oracle.com/technetwork/developer-tools/adf/unsaveddatawarning-100139.html

Posted in ADF | 1 Comment

ADF – Scope of Dynamic Region Bean


If a page has dynamic regions, and links to access those dynamic regions, we configure a backing bean to accomplish navigation to those dynamic regions. By default , when the backing bean is created from property inspector, it is created with backingBeanScope.
Now when we try to access the dynamic regions thru links, we observe that the default region which is rendered first (default value of taskFlowId in backing bean) will be working fine where as navigation to other regions will not be as expected. This is because, The scope the dynamic region backing bean should be atleast be viewScope. A dynamic region backing bean with backingBeanScope or requestScope will not work as expected.

Posted in ADF | Leave a comment

ADF – How to get Selected Row when Row Selection is disabled


I am using jdev 11.1.1.2.0 and due to some reasons, I have disabled row selection in my table. And I have given a check box for allowing the user to select a row. If Row selection is enabled, any row on which the user clicks becomes the current row and hence can be easily accessed in code. This post shows how to access a selected row when the row selection feature is disabled.

In short, when the user clicks on the checkbox, I want to get the row on which user has clicked the checkbox.
So I use the following code in my value change listener.

Method 1:

FacesCtrlHierNodeBinding changedRow = (FacesCtrlHierNodeBinding)linesTable.getRowData();

and u can get any attribute from the row using changedRow.getAttribute();

Method 2:

DCBindingContainer bindings = (DCBindingContainer)getBindings();
DCIteratorBinding iter = bindings.findIteratorBinding("LinesVO1Iterator");

List rowKey = (List)linesTable.getRowKey();
Key key = (Key)rowKey.get(0);
Row row = iter.findRowByKeyString(key.toStringFormat(true));

Method 3 :

BindingContext bc = BindingContext.getCurrent();
DCDataControl dc = bc.findDataControl("MyAMDataControl");
ApplicationModule am = (ApplicationModule)dc.getDataProvider();
ViewObject vo = am.findViewObject("LinesVO1");
Row row = vo.getRowAtRangeIndex(linesTable.getRowIndex());

Note : My table has a binding in this backing bean so that I can access it as linesTable variable.

Posted in ADF | 2 Comments

ADF – oracle.ord.im.NotConnectedException while downloading attachment


Take a File Upload scenario in ADF. The requirement is the user should be able to upload a file using browse button. once the user selects a file, the file should appear as link so that user can click on it and view. finally it can be saved to database using an apply button. In the database, this file will be stored in a field of type ORDSYS.ORDDOC.
In the above scenario, to download the file , I got the inputStream from the VO attribute which is of type OrdDocDomain and manipulated it to show it on page.
Now the code I used to get the inputStream from OrdDocDomain variable called file is:

in = file.getDataInStream();
Now the issue:
Once the data is saved to database, if I try to download the file, its working perfectly.
But before clicking Apply, if I try to download the file by clicking on the link, I am getting oracle.ord.im.NotConnectedException.

The reason for the above exception is getDataInStream() method of OrdDocDomain gets the inputStream only if the data is already committed to database. it cannot fetch it if the data is still in VO/EO cache (i.e before commit).

So the code used to solve the above issue is :

//If the file is connected to database (already existing in db) then get the data in stream
if(file.isConnected()){
in = file.getDataInStream();
}
//if the file is just uploaded and so not posted to db yet, get the temporarily stored content source
else
{ OrdByteArraySource bs = (OrdByteArraySource)file.getContentSource();
in = bs.getInputStream();
}

And now everything is working perfectly as expected.

Posted in ADF | 4 Comments

ADF – Defaulting value in poplist


Normally, we have a display value and code value for poplists. We show the display value to the user and store the code value in the database. Take a scenario where we have a model driven poplist where the values are populated from a VO. To achieve this, we have to create a transient attribute for display_value to which the list of values is attached, and return value is populated in the database attribute.
Now lets say we need to show a default value in the poplist. defaulting the database field in create method of entity will not default the value in display_value. so this post shows how to default the value in the display_value transient attribute and the database attribute from the base VORowImpl.
Ex: ClStatus is the EO based attribute in which code should be defaulted as ‘PENDING’
ClStatusMeaing is the transient display_value attribute in which corresponding meaning should be populated from the lov vo query.
Code to be written in the getter of the transient attribute:

public String getClStatusMeaning() {
String val = (String) getAttributeInternal(CLSTATUSMEANING);
String defaultStatus = "PENDING";
if(val == null){
Row[] rows = getStatusesLovVO1().getFilteredRows("LookupCode", defaultStatus);
StatusesLovVORowImpl row = (StatusesLovVORowImpl)rows[0];
if(row != null){
val = row.getMeaning();
setClStatus(defaultStatus);
}
}
return val;
}

Posted in ADF | Leave a comment

ADF – refreshing Dependent LOV in Table


Today, I faced an interesting issue in a dependent lov which, I thought, is worth blogging.
Normally, to create a column as lov which is dependent on another column, we create a bind variable in the child lov query, and in the main VO, we provide the parent attribute name as the value for bind variable, by editing the child view accessor.

In my scenario, a column of my table is dependent on a field which is part of a panel form layout which is present above my table.
I implemented this in the same way above and for the bind variable, I provided the value of the parent field using groovy expression.
And the table is refreshed using contextual event (my table is part of a dynamic region).

everything worked fine except one scenario!!

If I enter the parent field value first, and then create rows by clicking add row and then select lov, results are coming as expected.

If I Add row in the table first and then change the value of parent item in the form, and select lov, results are not correct. Its binding the old value and not the changed value. but if I click on add row once again, then thngs are working fine for all rows (including the previous row.)

After debugging for a while, I came to know that the only extra thing “Add Row” is doing is — it is refreshing the iterator of the table. So when the user changes the parent item, I am programmatically refreshing the iterator of my table using the following code and the lov worked fine ! ūüôā

DCBindingContainer bindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
DCIteratorBinding iter = (DCIteratorBinding)bindings.findIteratorBinding("");
iter.executeQuery();

Perfect!….. but wait! there is one more catch here!
Lets say I added a row in lines table, but did not enter values in any field, and then changing the value of parent item.
alas! the newly added row is disappearing.
This is because when an iterator is refreshed as above, any non dirty rows will be removed.
so, further task here is to make the created rows dirty by setting some attribute in the VO.

Posted in ADF | Leave a comment

ADF – Render or Hide components


I am currently developing a page where I have to render some fields dynamically based on the value of a poplist. Initially I was setting the rendered property to true or false based on the value of another field using EL expression and partial triggers is set to the id of the poplist. But this did not work as expected because partial triggers will not work on components that are not rendered (rendered = false). So a round about solution I used was , I gave partial triggers to the entire region in which my dynamic component is present.But this resulted in unnecessary validations because the entire region is refreshed unnecessarily.

Then through forums, I came to know that I have to use visible property instead of rendered property in my case to dynamically render or hide the field. By doing so, I can keep the partial triggers to the current field itself instead of using ppr for entire region in which it is present.

So the moral of the story is… in a scenario like this, use visible property instead of rendered property.

Posted in ADF | Leave a comment

ADF – Stop VO execution during page render


 Back again after quite some time! My ADF journey has started and so keep watching my blog to learn ADF along with me. Just as a primer, here is a small tip learnt.

In ADF when you drag and drop a VO from Data Control to your page and run your page, the VO will by default be executed and the output is shown. no extra line of code is needed to execute the VO at all like its done in OAF. but sometimes we may dont want this to happen during page render itself. Example in a search page, we dont want the vo to be executed when we open the page. It should only be executed after a click of a button. In that case to stop VO execution during page render, do the following.

Go to page definition. –> expand executables tab –> double click on your VO iterator –> in property inspector, set the refresh condition to following :

#{adfFacesContext.postback == true}

The adfFacesContext.postback boolean property evaluates to false when a page is first rendered, or rendered due to navigation from another page. It evaluates to true when the end user has interacted with some UI control on the page, causing a postback to that page to handle the event.

Posted in ADF, TechnoloZi | Leave a comment

How to fetch a bean in Advanced Search Panel


Normally, when we want to get handle of any bean in the page , we use webBean.findChildRecursive(“<id of bean>”) method. But to get handle of a criteria bean in advanced search panel, this will not work.

Example, lets say we have a advanced search panel and the first criteria Row has a message text input field with id Emp.

Now if we write webBean.findChildRecursive(“Emp”), it returns null. This is because, the framework dynamically allocates a different id of the form “Value_n” for each criteria row created in the page.

sample code :

¬†¬†¬† OAAdvancedSearchBean advBean = (OAAdvancedSearchBean)webBean.findChildRecursive(“AdvancedSearchBean”);
¬†¬†¬† OAMessageTextInputBean empNum = (OAMessageTextInputBean)advBean.findChildRecursive(“Value_x”);
¬†¬†¬† empNum.setValue(pageContext,”123″);

where x stands for xth criteria row in the advanced search panel. i.e if empNum is the first criteria row in your page, then give Value_0 as id.

Posted in OAF | Leave a comment

Displaying multiple records in single row


If you want to display values of multiple records in a single row seperated by commas, it can be done using ‘SYS_CONNECT_BY_PATH’ or also using DBMS_UTILITY.TABLE_TO_COMMA procedure.

Example: If you want to display all employee names belonging to dept 10 seperated by comma in a single row… following are the samples

Sample code using SYS_CONNECT_BY_PATH

SELECT MAX (LTRIM (SYS_CONNECT_BY_PATH (ename, ','), ',')) emp_list
FROM (SELECT empno, ename, ROWNUM AS record_num
FROM emp
WHERE deptno = 10) e
START WITH record_num = 1
CONNECT BY record_num = PRIOR record_num + 1

Sample code using TABLE_TO_COMMA

DECLARE
l_tab DBMS_UTILITY.uncl_array;
l_out VARCHAR2 (4000);
l_index NUMBER;

CURSOR c_emp
IS
SELECT ename
FROM emp
WHERE deptno = 10;
BEGIN
l_index := 0;

FOR ename_rec IN c_emp
LOOP
l_index := l_index + 1;
l_tab (l_index) := ename_rec.ename;
END LOOP;

DBMS_UTILITY.table_to_comma (l_tab, l_index, l_out);
DBMS_OUTPUT.put_line (l_out);
END;
/

Reference for more details :
http://www.oratechinfo.co.uk/delimited_lists_to_collections.html

Posted in PLSQL | Leave a comment