This discussion is archived
2 Replies Latest reply: Jun 13, 2012 12:08 PM by 941791 RSS

ADF drag and drop w/ Iterator

941791 Newbie
Currently Being Moderated
Hi. I am a relative ADF newbie. I must implement a UI where items are rendered using the af:iterator.
Each item created by the iterator has 2 basic parts, both made of <panelGroupLayout/> elements.
The top element has a <af:componentDragSource/> element.
The bottom element has a <af:dropTarget/>
So:
<af:iterator var="#{myBean.items}" varStatus="stat"><!-- 'items' returns an ArrayList w/ these Integer values: [1,2,3,4,5] -->
<panelGroupLayout>
<af:outputText value="Drag Object #{stat.index}"/>
<af:componentDragSource discriminant="test"/>
<f:attribute name="draggedObject" value="#{stat.index}"/>
</panelGroupLayout>

<panelGroupLayout>
<af:outputText value="Target Object #{stat.index}"/>
<af:dropTarget actions="MOVE" dropListener="#{myBean.dropMethod}">
<af:dataFlavor flavorClass="javax.faces.component.UIComponent" discriminant="test"/>
</af:dropTarget>
<f:attribute name="dropTarget" value="#{stat.index}"/>
</panelGroupLayout>
</af:iterator>

Here is my listener:
public DnDAction dropMethod(oracle.adf.view.rich.event.DropEvent event) {
Transferable dropTransferable = event.getTransferable();
UIComponent movedComponent = dropTransferable.getData(DataFlavor.UICOMPONENT_FLAVOR);
if (movedComponent != null && DnDAction.MOVE.equals(event.getProposedAction())) {
UIComponent dropComponent = event.getDropComponent();
System.out.println("In dropMethod(). Dragged component draggedObject attribute: " + event.getDragComponent().getAttributes().get("draggedObject"));
System.out.println("In dropMethod(). movedComponent dropTarget attribute: " + movedComponent.getAttributes().get("dropTarget"));
}

When I use the page and drag one item onto a target and look at the attribute values in a debugger, the draggedObject is identical to the dropTarget.

IOW, if I drag object labeled "Drag Object 1" and drop it on object labeled "Target Object 4", the output from the System.out.println()s above reads:
In dropMethod(). Dragged componet draggedObject attribute: 4
In dropMethod(). movedComponent dropTarget attribute: 4

However, if I simply hard-code identical objects in my jspx, same pairs, same names, same controls, an identical operation will produce different results. It will say:

In dropMethod(). Dragged componet draggedObject attribute: 1
In dropMethod(). movedComponent dropTarget attribute: 4

Anybody know how to get this to work properly while using the iterator? The number of objects I must render is variable.
  • 1. Re: ADF drag and drop w/ Iterator
    920236 Newbie
    Currently Being Moderated
    Hello there.

    I'm a relative ADF newbie too. Investigating your question helped me resolve a similar problem I had encountered. Bottom line: try replacing <af:iterator> with <af:forEach>. Here's my changes to your code:
    <af:forEach items="#{myBean.items}" varStatus="stat"><!-- 'items' returns an ArrayList w/ these Integer values: [1,2,3,4,5] -->
        <af:panelGroupLayout>
            <af:outputText value="Drag Object #{stat.index}">
                <af:componentDragSource discriminant="test"/>
                <f:attribute name="draggedObject" value="#{stat.index}"/>
            </af:outputText>
        </af:panelGroupLayout>
    
        <af:panelGroupLayout>
            <af:outputText value="Target Object #{stat.index}">
                <af:dropTarget actions="MOVE" dropListener="#{myBean.dropMethod}">
                    <af:dataFlavor flavorClass="javax.faces.component.UIComponent" discriminant="test"/>
                </af:dropTarget>
                <f:attribute name="dropTarget" value="#{stat.index}"/>
            </af:outputText>
        </af:panelGroupLayout>
    </af:forEach>
    In your code, the <f:attribute> wasn't nested under the <af:outputText>, was that really working?

    and the event handler:
    public DnDAction dropMethod(oracle.adf.view.rich.event.DropEvent event) { 
        logger.info("In dropMethod(). Dragged component draggedObject attribute: " + event.getDragComponent().getAttributes().get("draggedObject"));
        logger.info("In dropMethod(). movedComponent dropTarget attribute: " + event.getDropComponent().getAttributes().get("dropTarget"));
        return DnDAction.MOVE;
    }
    Notice in the event handler code it's way easier to just get the drop target from the event instead of digging through the Transferable.

    So this seems to have something to do with the difference between <af:iterator> and <af:forEach>, which is alluded to in the tag doc here: http://jdevadf.oracle.com/adf-richclient-demo/docs/tagdoc/af_forEach.html. It says:
    >
    The forEach tag should be used with intent and knowledge. The forEach tag is not used in JSF for iteration, but instead for generating multiple components. If your goal is to iterate over a collection of objects and render HTML for each item, <af:iterator> should be using instead.
    >

    I don't find that word of caution extremely helpful. After all, what's the real difference between iteration and generating multiple components? could we see an example? I've been using <af:iterator> by default and only if something doesn't work right do I try <af:forEach>. There haven't been many instances where <af:forEach> has actually worked better than <af:iterator> until this one.

    Anyway, hope this helps you.
  • 2. Re: ADF drag and drop w/ Iterator
    941791 Newbie
    Currently Being Moderated
    Thanks for the reply. But the <af:forEach> does not allow parameters to be passed to the components nested inside. The real code I am using looks like this:

    <af:iterator var="activity" first="0" rows="0"
    value="#{attrs.activityList}">

    <af:declarativeComponent viewId="/ui/editor/narrative/NVActivity.jspx">
    <f:attribute name="activity" value="#{activity}"/>
    </af:declarativeComponent>
    </af:iterator>

    where the values from 'attrs.activityList' are passed to a group of declarativeComponents. The <forEach> does not allow this.

    W/o an iterator I have much bigger problems than failing Drag and Drop.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points