ADF Drag and Drop Hints
April 28th, 2011 | Posted by Bogdan Petridean in Oracle ADF | 2 Comments
In this post we will use keyboard hints together with drag-and-drop behavior in order to let the user choose the action (copy or move) to be executed for the dragged adf component when the drop event occurs.
Scenario
PanelBox1 – we’ll refer to it as ‘Man in black‘ and PanelBox2 – we’ll refer to it as ‘Lady in red’ are draggable components and their parents are drop targets.
In the page header we present the steps needed in order to execute a copy or a move action.
Press ctrl key (keep it pressed), drag ‘Man in black‘ component and drop it as below:
A message telling us that a copy was executed will be displayed:
Now, press shift key (keep it pressed), drag ‘Lady in red‘ and drop it as below:
A message telling us that a move was successfully executed will be displayed:
If no hint is provided than neither copy nor move is executed.
Implementation
‘Man in black‘ and ‘Lady in red‘ are represented using af:panelBox components.
af:componentDragSource is nested inside both of the above components in order to make them draggable.
The drop targets are represented by ‘Man in black‘ and ‘Lady in red‘ parents – which are represented here using af:panelGroupLayout components.
The af:dropTarget component - which is the main actor – is configured as below:
<af:dropTarget dropListener="#{businessMB.handleDnDEvent}"
clientDropListener="handleClientDropEvent"
actions="MOVE COPY">
<af:dataFlavor flavorClass="javax.faces.component.UIComponent"/>
</af:dropTarget>
The actions attribute is used to set the actions allowed by the drop target to: MOVE and COPY.
The clientDropListener attribute references the handleClientDropEvent JavaScript function which is invoked before the drop event is propagated to the server.
The proposedAction is set with respect to the logic below:
1. if ctrl key is down than the proposedAction will be set to ACTION_COPY;
2. else if shift key is down than the proposedAction will be set to ACTION_MOVE;
3. else the proposedAction will be set to ACTION_NONE.
handleClientDropEvent JavaScript function is defined as follows:
function handleClientDropEvent(evt) {
var proposedAction = AdfDnDContext.ACTION_NONE;
if (op == "copy") {
proposedAction = AdfDnDContext.ACTION_COPY;
}
else if (op == "move") {
proposedAction = AdfDnDContext.ACTION_MOVE;
}
op = "none";
return proposedAction;
}
To detect if one of shift or ctrl keys is down when the drop event occurs we use the function below:
document.onkeydown = function (evt) {
var keyCode = (window.event) ? event.keyCode:evt.which;
//if CTRL key down -> perform COPY operation
if (keyCode == 17) {
op = "copy";
}
//if SHIFT key down -> perform MOVE operation
else if (keyCode == 16) {
op = "move";
}
evt.cancel();
}
When a key is released the below function gets called and sets the op var to its default value:
document.onkeyup = function (evt) {
//set operation to default value -> NONE
op = "none";
evt.cancel();
}
Hint: Thanks to the above method if ctrl or shift are released before the drop event occurs than neither COPY nor MOVE will be executed.
Hint: We declared our JavaScript functions directly in the jspx page, but the best practice is to use a .js file and set the source attribute of af:resource component to point to that file.
The dropListener attribute references the handleDnDEvent method from Business request bean:
public DnDAction handleDnDEvent(DropEvent dropEvent) {
DnDAction proposedAction = dropEvent.getProposedAction();
Transferable transferable = dropEvent.getTransferable();
UIComponent dragComponent =
transferable.getData(DataFlavor.UICOMPONENT_FLAVOR);
if (dragComponent != null) {
UIComponent dropTarget = dropEvent.getDropComponent();
UIComponent dragComponentParent = dragComponent.getParent();
if (dropTarget.equals(dragComponentParent)) {
return DnDAction.NONE;
} else {
if (proposedAction.equals(DnDAction.COPY)) {
return handleDnDCopyEvent(dropEvent);
}
else if (proposedAction.equals(DnDAction.MOVE)) {
return handleDnDMoveEvent(dropEvent);
} else {
return DnDAction.NONE;
}
}
}
handleDnDMoveEvent and handleDnDCopyEvent methods contain only a dummy FacesMessage telling the user the action that was executed:
public DnDAction handleDnDCopyEvent(DropEvent dropEvent) {
//write your COPY code here...
//dummy code
showFacesMessage("COPY action!", FacesMessage.SEVERITY_INFO);
return DnDAction.COPY;
}
public DnDAction handleDnDMoveEvent(DropEvent dropEvent) {
//write your MOVE code here...
//dummy code
showFacesMessage("MOVE action!", FacesMessage.SEVERITY_INFO);
return DnDAction.MOVE;
}
How to COPY an ADF Component with Drag-and-Drop is implemented and explained in this post:
How to MOVE an ADF Component with Drag-and-Drop is implemented in the ADFComponentDnD fusion web application which can be downloaded from HERE or from the Extra section at the bottom of this page.
ADFDnDHints fusion web sample application implemented using JDeveloper 11.1.1.4.0 can be downloaded from HERE.
Extra
ADFComponentDnD fusion web sample application providing an implementation for Component Drag-and-Drop Behavior and implemented using JDeveloper 11.1.1.4.0 can be downloaded from HERE.
Cheers!








What about Calendar drop target
Hi Ahmed,
What about it?
Regards,
Bogdan.