Sunday, January 8, 2012

Master-Detail with One Iterator

I will show slightly different approach how to implement Master-Detail relationship just with one iterator in ADF Bindings. Detail row collection will be fetched directly through View Link Accessor. I guess such approach is especially good, when you need to display Master-Detail data in the same table and want to declare just one iterator in ADF Bindings.

Sample application implements View Link between Locations and Departments, Data Model contains Master-Detail relationship based on View Link:


Drag & drop Locations table into ADF UI, Locations iterator will be defined in ADF Bindings:


Add child Departments collection to the Locations iterator and set DepartmentName attribute to be visible:



We can reference detail rows by pointing to View Link Accessor (by View Link Accessor name - DepartmentsView). Iterator will retrieve all detail rows available and display Department Name for each:


DepartmentsView is View Link Accessor name (pointing to Departments and generated in Locations), you can double check this in View Link definition wizard:


Here how it looks on UI, one Location row comes with collection of Departments rows:


Sample application - MasterDetailInlineTableApp.zip.

11 comments:

SK said...

Andrejus,

This is nice article.
Can i do the samething with JavaDataControls? Especially what is the equivalent step for the relationship step?

Thanks
Sri

Anonymous said...

How can i show a selectonechoice or other lists instead of output labels ? af:iterator cannot be used inside of these components, and af:foreach doesnt work.

Thanks

Claudio

Anonymous said...

i achieved this with varStatus in foreach:

af:selectOneChoice id="soc1"
af:forEach begin="0" end="5" varStatus="tel"
af:selectItem label="#{row.telefones[tel.index].ddd} #{row.telefones[tel.index].numero}" value="#{row.telefones[tel.index].numero}" id="si3"/
/af:forEach

/af:selectOneChoice

but now i cant get the size of the nested collection. I tried row.telefones.estimateRowCout but gives me a numberformatexception. Any ideas ?

thanks

Claudio

Anonymous said...

Andrejus,


In this situation i can access the length of the nested collection

af:outputText value="total tels: #{fn:length(row.telefones)}" id="ds2" /

but in foreach statement

af:forEach begin="0" end="#{fn:length(row.telefones)}" ....

i can't...

Using the elresolver in a managed bean such as

List l = context.getApplication().evaluateExpressionGet(context, "#{row.telefones}", List.class));

gives me a null object.

I think that issue is related to the evaluation process or not ? How we can resolve this ?

thanks,

Claudio

Andrej Baranovskij said...

You can write managed bean method, where you could convert into required type - call this method instead of accessing expression directly.

Andrejus

Anonymous said...

Andrejus,

Is it possible to use the datacontrol methods in the child iterator? i.e. "createInsert" method.

I'm using an table inside an iterator. I can retrieve data normally, but I'm not sure how I'd call the methods.

Thanks in advance!

Andrej Baranovskij said...

Yes, it should work to call createInsert for detail data.

Andrejus

Test said...

Hi Andrejus,
I've similar usecase in my current project. I've master detail scenarion at 3 levels. If I run the page normally, it shows the data at all the 3 levels. If I use af:query panel to show the page, the page displays the data for the 2 levels only.

In simple, I added Employees as the child for the Departments and used af:iterator to show the employees for each Department in the same page (assume as LocDeptEmp page). If I run the page, the page shows the employees data along with Departments.

Now created a Search page for the locations. The locationId in search results table is a command link when clicked navigates you to the above page (LocDeptEmp page). Now the LocDeptEmp.jspx page shows only the Departments page not the employees data.

I can upload the testcase.

Thanks,
Lakshman

Madhu Krishna said...

Hi
I have two read only voew objects with a view link between them.
I have the Retain View Link Accesor option enabled for the parent VO.
Created a Tree binding and able to load the page and show the tree.
fillingIterator =(DCIteratorBinding)contain.get("FillingBillCodeROVOIterator");
fillingIteratorRoSetIterator = fillingIterator.getViewObject().createRowSetIterator(null);
while(fillingIteratorRoSetIterator.hasNext()){
fillingRow = (FillingBillCodeROVORowImpl)fillingIteratorRoSetIterator.next();

RowIterator it = fillingRow.getFillingBlackBoxROVO();
Row currRow = null;
while(it.hasNext()){
currRow = it.next();
}

But when I am trying to iterate through the child view link acessor, it is not able to find the child rows.

If I remove the option it is able to find it.
Any help would be highly appreciated

Thanks and Regards
Madhu Krishna

Unknown said...

hi Andrejus,

i did it and it worked pretty well.
but now i want to select the detailed item {departmentName}
through the managed bean..
is there a way i can do that?

Thanks.

RAMESH said...

#{fn:length(item.Rewards)}

Rewards collections returning only one record, but length function returning 100. If collections return more than one record then length function returning correct value. Issue with only collection with one record.
Can you please help.

Thanks,
Ramesh