By sharing data control, we can have master-detail scenarios working without much java coding. All we need to do is just to set the partial trigger property of the child region to refer to the parent. For example, consider the following UI:
In the above figure, the first table lists the master Departments table, and the second table lists the child Employee table. The DepartmentsView is showing the sum of all employees salaries grouped by department. The child EmployeesView lists all the employees for the above selected department. There is a master child relationship between the DepartmentsView and EmployeesView, as shown below:
Because of this master-detail relationship, we don’t have to do much of the coding to sync-up master and detail region whenever any activity happens in the master table. All we need to do is to set partial trigger for the second region to point to the first table. So, when we select any other row, the child region gets refreshed automatically, as shown below:
We don’t need to set change event policy to ppr as well for the child iterator, as shown below:
Even without setting this property, the flow works because of shared data control, and partial trigger set on the child table to point to the parent table.
Code Snippet:
DepartmentsView VO Query
SELECT Departments.DEPARTMENT_ID,
Departments.DEPARTMENT_NAME,
SUM(Employees.SALARY) SALARYSUM
FROM DEPARTMENTS Departments, EMPLOYEES Employees
WHERE Employees.DEPARTMENT_ID = Departments.DEPARTMENT_ID
GROUP BY Departments.DEPARTMENT_ID, Departments.DEPARTMENT_NAME
MasterPage.jspx
<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
<jsp:directive.page contentType="text/html;charset=UTF-8"/>
<f:view>
<af:document id="d1">
<af:messages id="m1"/>
<af:form id="f1">
<af:showDetail disclosed="true" id="sd2" disclosedText="Departments"
undisclosedText="Departments" inlineStyle="width:100%;">
<af:table value="#{bindings.DepartmentsView2.collectionModel}"
var="row" rows="#{bindings.DepartmentsView2.rangeSize}"
emptyText="#{bindings.DepartmentsView2.viewable ? 'No data to display.' : 'Access Denied.'}"
fetchSize="#{bindings.DepartmentsView2.rangeSize}"
rowBandingInterval="0"
selectedRowKeys="#{bindings.DepartmentsView2.collectionModel.selectedRow}"
selectionListener="#{bindings.DepartmentsView2.collectionModel.makeCurrent}"
rowSelection="single" id="t1" contentDelivery="immediate"
autoHeightRows="#{bindings.DepartmentsView2.rangeSize}"
width="100%">
<af:column sortProperty="DepartmentId" sortable="false"
headerText="#{bindings.DepartmentsView2.hints.DepartmentId.label}"
id="c1">
<af:outputText value="#{row.DepartmentId}" id="ot1">
<af:convertNumber groupingUsed="false"
pattern="#{bindings.DepartmentsView2.hints.DepartmentId.format}"/>
</af:outputText>
</af:column>
<af:column sortProperty="DepartmentName" sortable="false"
headerText="#{bindings.DepartmentsView2.hints.DepartmentName.label}"
id="c2">
<af:outputText value="#{row.DepartmentName}" id="ot3"/>
</af:column>
<af:column sortProperty="Salarysum" sortable="false"
headerText="#{bindings.DepartmentsView2.hints.Salarysum.label}"
id="c3">
<af:outputText value="#{row.Salarysum}" id="ot2">
<af:convertNumber groupingUsed="false"
pattern="#{bindings.DepartmentsView2.hints.Salarysum.format}"/>
</af:outputText>
</af:column>
</af:table>
</af:showDetail>
<af:spacer width="10" height="10" id="s1"/>
<af:showDetail disclosed="true" id="sd1" disclosedText="Employees"
undisclosedText="Employees" inlineStyle="width:100.0%;">
<af:table value="#{bindings.EmployeesView3.collectionModel}" var="row"
rows="#{bindings.EmployeesView3.rangeSize}"
emptyText="#{bindings.EmployeesView3.viewable ? 'No data to display.' : 'Access Denied.'}"
fetchSize="#{bindings.EmployeesView3.rangeSize}"
rowBandingInterval="0" id="t2" contentDelivery="immediate"
autoHeightRows="#{bindings.EmployeesView3.rangeSize}" width="100%"
partialTriggers="::t1"> <af:column sortProperty="EmployeeId" sortable="false"
headerText="#{bindings.EmployeesView3.hints.EmployeeId.label}"
id="c7">
<af:outputText value="#{row.EmployeeId}" id="ot9">
<af:convertNumber groupingUsed="false"
pattern="#{bindings.EmployeesView3.hints.EmployeeId.format}"/>
</af:outputText>
</af:column>
<af:column sortProperty="FirstName" sortable="false"
headerText="#{bindings.EmployeesView3.hints.FirstName.label}"
id="c12">
<af:outputText value="#{row.FirstName}" id="ot14"/>
</af:column>
<af:column sortProperty="LastName" sortable="false"
headerText="#{bindings.EmployeesView3.hints.LastName.label}"
id="c8">
<af:outputText value="#{row.LastName}" id="ot12"/>
</af:column>
<af:column sortProperty="Salary" sortable="false"
headerText="#{bindings.EmployeesView3.hints.Salary.label}"
id="c6">
<af:outputText value="#{row.Salary}" id="ot10">
<af:convertNumber groupingUsed="false"
pattern="#{bindings.EmployeesView3.hints.Salary.format}"/>
</af:outputText>
</af:column>
<af:column sortProperty="DepartmentId" sortable="false"
headerText="#{bindings.EmployeesView3.hints.DepartmentId.label}"
id="c13">
<af:outputText value="#{row.DepartmentId}" id="ot13">
<af:convertNumber groupingUsed="false"
pattern="#{bindings.EmployeesView3.hints.DepartmentId.format}"/>
</af:outputText>
</af:column>
</af:table>
</af:showDetail>
</af:form>
</af:document>
</f:view>
</jsp:root>
MasterPage.jspx Page Definition File
<?xml version="1.0" encoding="UTF-8" ?>
<pageDefinition xmlns="http://xmlns.oracle.com/adfm/uimodel"
version="11.1.1.59.23" id="MasterPage2PageDef"
Package="view.pageDefs">
<parameters/>
<executables>
<variableIterator id="variables"/>
<iterator Binds="DepartmentsView2" RangeSize="25"
DataControl="AppModuleDataControl" id="DepartmentsView2Iterator"/>
<iterator Binds="EmployeesView3" RangeSize="25"
DataControl="AppModuleDataControl" id="EmployeesView3Iterator"/>
</executables>
<bindings>
<tree IterBinding="DepartmentsView2Iterator" id="DepartmentsView2">
<nodeDefinition DefName="model.DepartmentsView">
<AttrNames>
<Item Value="DepartmentId"/>
<Item Value="DepartmentName"/>
<Item Value="Salarysum"/>
</AttrNames>
</nodeDefinition>
</tree>
<tree IterBinding="EmployeesView3Iterator" id="EmployeesView3">
<nodeDefinition DefName="model.EmployeesView">
<AttrNames>
<Item Value="EmployeeId"/>
<Item Value="FirstName"/>
<Item Value="LastName"/>
<Item Value="Email"/>
<Item Value="PhoneNumber"/>
<Item Value="HireDate"/>
<Item Value="JobId"/>
<Item Value="Salary"/>
<Item Value="CommissionPct"/>
<Item Value="ManagerId"/>
<Item Value="DepartmentId"/>
</AttrNames>
</nodeDefinition>
</tree>
</bindings>
</pageDefinition>
That's it.
JDev Release 11.1.1.4
In the above figure, the first table lists the master Departments table, and the second table lists the child Employee table. The DepartmentsView is showing the sum of all employees salaries grouped by department. The child EmployeesView lists all the employees for the above selected department. There is a master child relationship between the DepartmentsView and EmployeesView, as shown below:
Because of this master-detail relationship, we don’t have to do much of the coding to sync-up master and detail region whenever any activity happens in the master table. All we need to do is to set partial trigger for the second region to point to the first table. So, when we select any other row, the child region gets refreshed automatically, as shown below:
We don’t need to set change event policy to ppr as well for the child iterator, as shown below:
Even without setting this property, the flow works because of shared data control, and partial trigger set on the child table to point to the parent table.
Code Snippet:
DepartmentsView VO Query
SELECT Departments.DEPARTMENT_ID,
Departments.DEPARTMENT_NAME,
SUM(Employees.SALARY) SALARYSUM
FROM DEPARTMENTS Departments, EMPLOYEES Employees
WHERE Employees.DEPARTMENT_ID = Departments.DEPARTMENT_ID
GROUP BY Departments.DEPARTMENT_ID, Departments.DEPARTMENT_NAME
MasterPage.jspx
<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
<jsp:directive.page contentType="text/html;charset=UTF-8"/>
<f:view>
<af:document id="d1">
<af:messages id="m1"/>
<af:form id="f1">
<af:showDetail disclosed="true" id="sd2" disclosedText="Departments"
undisclosedText="Departments" inlineStyle="width:100%;">
<af:table value="#{bindings.DepartmentsView2.collectionModel}"
var="row" rows="#{bindings.DepartmentsView2.rangeSize}"
emptyText="#{bindings.DepartmentsView2.viewable ? 'No data to display.' : 'Access Denied.'}"
fetchSize="#{bindings.DepartmentsView2.rangeSize}"
rowBandingInterval="0"
selectedRowKeys="#{bindings.DepartmentsView2.collectionModel.selectedRow}"
selectionListener="#{bindings.DepartmentsView2.collectionModel.makeCurrent}"
rowSelection="single" id="t1" contentDelivery="immediate"
autoHeightRows="#{bindings.DepartmentsView2.rangeSize}"
width="100%">
<af:column sortProperty="DepartmentId" sortable="false"
headerText="#{bindings.DepartmentsView2.hints.DepartmentId.label}"
id="c1">
<af:outputText value="#{row.DepartmentId}" id="ot1">
<af:convertNumber groupingUsed="false"
pattern="#{bindings.DepartmentsView2.hints.DepartmentId.format}"/>
</af:outputText>
</af:column>
<af:column sortProperty="DepartmentName" sortable="false"
headerText="#{bindings.DepartmentsView2.hints.DepartmentName.label}"
id="c2">
<af:outputText value="#{row.DepartmentName}" id="ot3"/>
</af:column>
<af:column sortProperty="Salarysum" sortable="false"
headerText="#{bindings.DepartmentsView2.hints.Salarysum.label}"
id="c3">
<af:outputText value="#{row.Salarysum}" id="ot2">
<af:convertNumber groupingUsed="false"
pattern="#{bindings.DepartmentsView2.hints.Salarysum.format}"/>
</af:outputText>
</af:column>
</af:table>
</af:showDetail>
<af:spacer width="10" height="10" id="s1"/>
<af:showDetail disclosed="true" id="sd1" disclosedText="Employees"
undisclosedText="Employees" inlineStyle="width:100.0%;">
<af:table value="#{bindings.EmployeesView3.collectionModel}" var="row"
rows="#{bindings.EmployeesView3.rangeSize}"
emptyText="#{bindings.EmployeesView3.viewable ? 'No data to display.' : 'Access Denied.'}"
fetchSize="#{bindings.EmployeesView3.rangeSize}"
rowBandingInterval="0" id="t2" contentDelivery="immediate"
autoHeightRows="#{bindings.EmployeesView3.rangeSize}" width="100%"
partialTriggers="::t1"> <af:column sortProperty="EmployeeId" sortable="false"
headerText="#{bindings.EmployeesView3.hints.EmployeeId.label}"
id="c7">
<af:outputText value="#{row.EmployeeId}" id="ot9">
<af:convertNumber groupingUsed="false"
pattern="#{bindings.EmployeesView3.hints.EmployeeId.format}"/>
</af:outputText>
</af:column>
<af:column sortProperty="FirstName" sortable="false"
headerText="#{bindings.EmployeesView3.hints.FirstName.label}"
id="c12">
<af:outputText value="#{row.FirstName}" id="ot14"/>
</af:column>
<af:column sortProperty="LastName" sortable="false"
headerText="#{bindings.EmployeesView3.hints.LastName.label}"
id="c8">
<af:outputText value="#{row.LastName}" id="ot12"/>
</af:column>
<af:column sortProperty="Salary" sortable="false"
headerText="#{bindings.EmployeesView3.hints.Salary.label}"
id="c6">
<af:outputText value="#{row.Salary}" id="ot10">
<af:convertNumber groupingUsed="false"
pattern="#{bindings.EmployeesView3.hints.Salary.format}"/>
</af:outputText>
</af:column>
<af:column sortProperty="DepartmentId" sortable="false"
headerText="#{bindings.EmployeesView3.hints.DepartmentId.label}"
id="c13">
<af:outputText value="#{row.DepartmentId}" id="ot13">
<af:convertNumber groupingUsed="false"
pattern="#{bindings.EmployeesView3.hints.DepartmentId.format}"/>
</af:outputText>
</af:column>
</af:table>
</af:showDetail>
</af:form>
</af:document>
</f:view>
</jsp:root>
MasterPage.jspx Page Definition File
<?xml version="1.0" encoding="UTF-8" ?>
<pageDefinition xmlns="http://xmlns.oracle.com/adfm/uimodel"
version="11.1.1.59.23" id="MasterPage2PageDef"
Package="view.pageDefs">
<parameters/>
<executables>
<variableIterator id="variables"/>
<iterator Binds="DepartmentsView2" RangeSize="25"
DataControl="AppModuleDataControl" id="DepartmentsView2Iterator"/>
<iterator Binds="EmployeesView3" RangeSize="25"
DataControl="AppModuleDataControl" id="EmployeesView3Iterator"/>
</executables>
<bindings>
<tree IterBinding="DepartmentsView2Iterator" id="DepartmentsView2">
<nodeDefinition DefName="model.DepartmentsView">
<AttrNames>
<Item Value="DepartmentId"/>
<Item Value="DepartmentName"/>
<Item Value="Salarysum"/>
</AttrNames>
</nodeDefinition>
</tree>
<tree IterBinding="EmployeesView3Iterator" id="EmployeesView3">
<nodeDefinition DefName="model.EmployeesView">
<AttrNames>
<Item Value="EmployeeId"/>
<Item Value="FirstName"/>
<Item Value="LastName"/>
<Item Value="Email"/>
<Item Value="PhoneNumber"/>
<Item Value="HireDate"/>
<Item Value="JobId"/>
<Item Value="Salary"/>
<Item Value="CommissionPct"/>
<Item Value="ManagerId"/>
<Item Value="DepartmentId"/>
</AttrNames>
</nodeDefinition>
</tree>
</bindings>
</pageDefinition>
That's it.
JDev Release 11.1.1.4