Problem:
Imagine you have 2 regions, Department and Employee region and want to refresh/requery Employee region after dragging a Department row from the Department region to the Employee region.
This is where ADF's Drag and Drop Framework comes into picture.
The following images shows what I wanted to accomplish:
Constraint:
Emp and Dept tables are not related to each other so the data model is independent of one another.
Solution:
<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
<af:table value="#{bindings.DeptVO1.collectionModel}" var="row"
rows="#{bindings.DeptVO1.rangeSize}"
emptyText="#{bindings.DeptVO1.viewable ? 'No data to display.' : 'Access Denied.'}"
fetchSize="#{bindings.DeptVO1.rangeSize}" rowBandingInterval="0"
selectedRowKeys="#{bindings.DeptVO1.collectionModel.selectedRow}"
selectionListener="#{bindings.DeptVO1.collectionModel.makeCurrent}"
rowSelection="single"
binding="#{backingBeanScope.backing_Department.t1}" id="t1">
<af:column sortProperty="DeptId" sortable="false"
headerText="#{bindings.DeptVO1.hints.DeptId.label}" id="c2">
<af:outputText value="#{row.DeptId}" id="ot2">
<af:convertNumber groupingUsed="false"
pattern="#{bindings.DeptVO1.hints.DeptId.format}"/>
</af:outputText>
</af:column>
<af:column sortProperty="DeptName" sortable="false"
headerText="#{bindings.DeptVO1.hints.DeptName.label}" id="c1">
<af:outputText value="#{row.DeptName}" id="ot1"/>
</af:column>
<af:dragSource actions="COPY" defaultAction="COPY" discriminant="Dept"/>
</af:table>
<!--oracle-jdev-comment:auto-binding-backing-bean-name:backing_Department-->
</jsp:root>
And here is the code snippet of Employee.jsff
<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
<af:table value="#{bindings.EmpVO1.collectionModel}" var="row"
rows="#{bindings.EmpVO1.rangeSize}"
emptyText="#{bindings.EmpVO1.viewable ? 'No data to display.' : 'Access Denied.'}"
fetchSize="#{bindings.EmpVO1.rangeSize}" rowBandingInterval="0"
selectedRowKeys="#{bindings.EmpVO1.collectionModel.selectedRow}"
selectionListener="#{bindings.EmpVO1.collectionModel.makeCurrent}"
rowSelection="single"
binding="#{backingBeanScope.backing_Employee.t2}" id="t2">
<af:column sortProperty="EmpId" sortable="false"
headerText="#{bindings.EmpVO1.hints.EmpId.label}" id="c3">
<af:outputText value="#{row.EmpId}" id="ot3">
<af:convertNumber groupingUsed="false"
pattern="#{bindings.EmpVO1.hints.EmpId.format}"/>
</af:outputText>
</af:column>
<af:column sortProperty="EmpName" sortable="false"
headerText="#{bindings.EmpVO1.hints.EmpName.label}" id="c2">
<af:outputText value="#{row.EmpName}" id="ot2"/>
</af:column>
<af:column sortProperty="DeptId" sortable="false"
headerText="#{bindings.EmpVO1.hints.DeptId.label}" id="c1">
<af:outputText value="#{row.DeptId}" id="ot1">
<af:convertNumber groupingUsed="false"
pattern="#{bindings.EmpVO1.hints.DeptId.format}"/>
</af:outputText>
</af:column>
<af:dropTarget dropListener="#{backingBeanScope.backing_Employee.handleDrop}"
actions="COPY">
<af:dataFlavor flavorClass="java.lang.Object"/>
</af:dropTarget>
</af:table>
<!--oracle-jdev-comment:auto-binding-backing-bean-name:backing_Employee-->
</jsp:root>
And here is the code for the Managed Bean that contains the handleDrop drop listener method:
package view.backing;
import java.util.Iterator;
import java.util.List;
import javax.faces.component.UIComponent;
import oracle.adf.model.BindingContext;
import oracle.adf.model.binding.DCIteratorBinding;
import oracle.adf.view.rich.component.rich.data.RichTable;
import oracle.adf.view.rich.datatransfer.DataFlavor;
import oracle.adf.view.rich.datatransfer.Transferable;
import oracle.adf.view.rich.dnd.DnDAction;
import oracle.adf.view.rich.event.DropEvent;
import oracle.binding.BindingContainer;
import oracle.jbo.Row;
import oracle.jbo.ViewObject;
import oracle.jbo.uicli.binding.JUCtrlHierBinding;
import oracle.jbo.uicli.binding.JUCtrlHierNodeBinding;
import org.apache.myfaces.trinidad.model.CollectionModel;
import org.apache.myfaces.trinidad.model.RowKeySet;
public class Employee {
private RichTable t2;
public void setT2(RichTable t1) {
this.t2 = t1;
}
public RichTable getT2() {
return t2;
}
public DnDAction handleDrop(DropEvent dropEvent){
Transferable transferable = dropEvent.getTransferable();
DataFlavor<RowKeySet> rowKeySetFlavor = DataFlavor.getDataFlavor(RowKeySet.class, "Dept");
RowKeySet rowKeySet = transferable.getData(rowKeySetFlavor);
if (rowKeySet != null){
CollectionModel dragModel = null;
dragModel = transferable.getData(CollectionModel.class);
if (dragModel!=null) {
JUCtrlHierBinding binding = null;
binding = (JUCtrlHierBinding) dragModel.getWrappedData();
Iterator rowKeySetIterator = rowKeySet.iterator();
if (binding != null) {
if (rowKeySetIterator.hasNext()) {
List rowKey = (List) rowKeySetIterator.next();
JUCtrlHierNodeBinding nodeBinding = null;
nodeBinding = binding.findNodeByKeyPath(rowKey);
Row rw = nodeBinding.getRow();
queryEmployees( ((oracle.jbo.domain.Number)rw.getAttribute("DeptId")).toString(), dropEvent.getDropComponent());
}
return DnDAction.MOVE;
}
}
}
return DnDAction.MOVE;
}
private void queryEmployees(String departmentId, UIComponent dropComponent){
BindingContext bctx = BindingContext.getCurrent();
BindingContainer bindings = bctx.getCurrentBindingsEntry();
DCIteratorBinding employeesIter = (DCIteratorBinding)bindings.get("EmpVO1Iterator");
ViewObject vo = employeesIter.getViewObject();
vo.setWhereClause("dept_id = :TheDeptId");
vo.defineNamedWhereClauseParam("TheDeptId", null, null);
vo.setNamedWhereClauseParam("TheDeptId", departmentId);
vo.executeQuery();
}
}
Thats it.
JDev Release 11.1.1.4
Imagine you have 2 regions, Department and Employee region and want to refresh/requery Employee region after dragging a Department row from the Department region to the Employee region.
This is where ADF's Drag and Drop Framework comes into picture.
The following images shows what I wanted to accomplish:
Constraint:
Emp and Dept tables are not related to each other so the data model is independent of one another.
Solution:
- Created two fragments, containing Dept and Emp tables.
- On the Dept table, dropped the 'Drag Source' tag from the Operations Component Pallette and specify the operation as COPY and descriminator and Dept.
- On the Emp table, drop the 'Drop Target' tag from the Operations Component Pallette and specify a bean method as the drop event listener ( code snippet is shown below ).
- For the 'Drop Target' tag, do specify java.lang.Object as the Flavor Class for the child dataFlavor tag, otherwise it will not work.
- Include them in their respectative task flows and drop them as regions on the final page.
Here is the code snippet of Department.jsff
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
<af:table value="#{bindings.DeptVO1.collectionModel}" var="row"
rows="#{bindings.DeptVO1.rangeSize}"
emptyText="#{bindings.DeptVO1.viewable ? 'No data to display.' : 'Access Denied.'}"
fetchSize="#{bindings.DeptVO1.rangeSize}" rowBandingInterval="0"
selectedRowKeys="#{bindings.DeptVO1.collectionModel.selectedRow}"
selectionListener="#{bindings.DeptVO1.collectionModel.makeCurrent}"
rowSelection="single"
binding="#{backingBeanScope.backing_Department.t1}" id="t1">
<af:column sortProperty="DeptId" sortable="false"
headerText="#{bindings.DeptVO1.hints.DeptId.label}" id="c2">
<af:outputText value="#{row.DeptId}" id="ot2">
<af:convertNumber groupingUsed="false"
pattern="#{bindings.DeptVO1.hints.DeptId.format}"/>
</af:outputText>
</af:column>
<af:column sortProperty="DeptName" sortable="false"
headerText="#{bindings.DeptVO1.hints.DeptName.label}" id="c1">
<af:outputText value="#{row.DeptName}" id="ot1"/>
</af:column>
<af:dragSource actions="COPY" defaultAction="COPY" discriminant="Dept"/>
</af:table>
<!--oracle-jdev-comment:auto-binding-backing-bean-name:backing_Department-->
</jsp:root>
And here is the code snippet of Employee.jsff
<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
<af:table value="#{bindings.EmpVO1.collectionModel}" var="row"
rows="#{bindings.EmpVO1.rangeSize}"
emptyText="#{bindings.EmpVO1.viewable ? 'No data to display.' : 'Access Denied.'}"
fetchSize="#{bindings.EmpVO1.rangeSize}" rowBandingInterval="0"
selectedRowKeys="#{bindings.EmpVO1.collectionModel.selectedRow}"
selectionListener="#{bindings.EmpVO1.collectionModel.makeCurrent}"
rowSelection="single"
binding="#{backingBeanScope.backing_Employee.t2}" id="t2">
<af:column sortProperty="EmpId" sortable="false"
headerText="#{bindings.EmpVO1.hints.EmpId.label}" id="c3">
<af:outputText value="#{row.EmpId}" id="ot3">
<af:convertNumber groupingUsed="false"
pattern="#{bindings.EmpVO1.hints.EmpId.format}"/>
</af:outputText>
</af:column>
<af:column sortProperty="EmpName" sortable="false"
headerText="#{bindings.EmpVO1.hints.EmpName.label}" id="c2">
<af:outputText value="#{row.EmpName}" id="ot2"/>
</af:column>
<af:column sortProperty="DeptId" sortable="false"
headerText="#{bindings.EmpVO1.hints.DeptId.label}" id="c1">
<af:outputText value="#{row.DeptId}" id="ot1">
<af:convertNumber groupingUsed="false"
pattern="#{bindings.EmpVO1.hints.DeptId.format}"/>
</af:outputText>
</af:column>
<af:dropTarget dropListener="#{backingBeanScope.backing_Employee.handleDrop}"
actions="COPY">
<af:dataFlavor flavorClass="java.lang.Object"/>
</af:dropTarget>
</af:table>
<!--oracle-jdev-comment:auto-binding-backing-bean-name:backing_Employee-->
</jsp:root>
And here is the code for the Managed Bean that contains the handleDrop drop listener method:
package view.backing;
import java.util.Iterator;
import java.util.List;
import javax.faces.component.UIComponent;
import oracle.adf.model.BindingContext;
import oracle.adf.model.binding.DCIteratorBinding;
import oracle.adf.view.rich.component.rich.data.RichTable;
import oracle.adf.view.rich.datatransfer.DataFlavor;
import oracle.adf.view.rich.datatransfer.Transferable;
import oracle.adf.view.rich.dnd.DnDAction;
import oracle.adf.view.rich.event.DropEvent;
import oracle.binding.BindingContainer;
import oracle.jbo.Row;
import oracle.jbo.ViewObject;
import oracle.jbo.uicli.binding.JUCtrlHierBinding;
import oracle.jbo.uicli.binding.JUCtrlHierNodeBinding;
import org.apache.myfaces.trinidad.model.CollectionModel;
import org.apache.myfaces.trinidad.model.RowKeySet;
public class Employee {
private RichTable t2;
public void setT2(RichTable t1) {
this.t2 = t1;
}
public RichTable getT2() {
return t2;
}
public DnDAction handleDrop(DropEvent dropEvent){
Transferable transferable = dropEvent.getTransferable();
DataFlavor<RowKeySet> rowKeySetFlavor = DataFlavor.getDataFlavor(RowKeySet.class, "Dept");
RowKeySet rowKeySet = transferable.getData(rowKeySetFlavor);
if (rowKeySet != null){
CollectionModel dragModel = null;
dragModel = transferable.getData(CollectionModel.class);
if (dragModel!=null) {
JUCtrlHierBinding binding = null;
binding = (JUCtrlHierBinding) dragModel.getWrappedData();
Iterator rowKeySetIterator = rowKeySet.iterator();
if (binding != null) {
if (rowKeySetIterator.hasNext()) {
List rowKey = (List) rowKeySetIterator.next();
JUCtrlHierNodeBinding nodeBinding = null;
nodeBinding = binding.findNodeByKeyPath(rowKey);
Row rw = nodeBinding.getRow();
queryEmployees( ((oracle.jbo.domain.Number)rw.getAttribute("DeptId")).toString(), dropEvent.getDropComponent());
}
return DnDAction.MOVE;
}
}
}
return DnDAction.MOVE;
}
private void queryEmployees(String departmentId, UIComponent dropComponent){
BindingContext bctx = BindingContext.getCurrent();
BindingContainer bindings = bctx.getCurrentBindingsEntry();
DCIteratorBinding employeesIter = (DCIteratorBinding)bindings.get("EmpVO1Iterator");
ViewObject vo = employeesIter.getViewObject();
vo.setWhereClause("dept_id = :TheDeptId");
vo.defineNamedWhereClauseParam("TheDeptId", null, null);
vo.setNamedWhereClauseParam("TheDeptId", departmentId);
vo.executeQuery();
}
}
Thats it.
JDev Release 11.1.1.4
No comments:
Post a Comment