Sean Staats
Sean Staats

Reputation: 297

How does one cancel/unaccept a drag-and-drop operation in Flex 3?

Goal: Allow the user to delete a record by dragging a row from an AdvancedDataGrid, dropping it onto a trash-can icon and verify the user meant to do that via a popup alert with "OK" and "Cancel" buttons.

What is working:

Problem: After the user clicks the "Cancel" button and the popup alert closes, no rows in the ADG can be dragged. I've discovered that after sorting the ADG, by clicking on a column header, the user can begin dragging rows again.

Code: (changed from original post)

<mx:Image source="{trashImage}" buttonMode="true" 
toolTip="drag a participant here to delete them from the project"
dragDrop="deleteParticipantDrop(event)" dragEnter="deleteParticipantEnter(event)" 
dragExit="deleteParticipantDragExit(event)" top="4" right="122" id="image2" />  

// trashImage Event Handlers:
private function deleteParticipantEnter(event:DragEvent):void
{
    var component:IUIComponent = IUIComponent(event.currentTarget);
    dragComponent = component;
    DragManager.acceptDragDrop(component);
    DragManager.showFeedback(DragManager.MOVE);
    deleteParticipantDragEvent = event;
}

private function deleteParticipantDrop(event:DragEvent):void
{
    var selectedKitNum:String = memberRpt.selectedItem.KitNum;
    var selectedName:String = memberRpt.selectedItem.ParticipantName;
    var component:IUIComponent = IUIComponent(event.currentTarget);
    dragComponent = component;
    DragManager.acceptDragDrop(component);
    isEditingParticipantInfo = false;
    isDeletingParticipant = true;
    deleteParticipantDropEvent = event;
    event.stopImmediatePropagation(); // Added as per mrm
    alert.confirm("Are you sure you want to delete this participant, Kit #" + memberRpt.selectedItem.KitNum + " ("  + 
        memberRpt.selectedItem.ParticipantName + ") from the project?  This cannot be reversed!!  An email will be " +
        "sent to notify this participant and you will receive a copy of it for your records.", confirmRemoveParticipant);
}

private function deleteParticipantDragExit(event:DragEvent):void
{
    var component:IUIComponent = IUIComponent(event.currentTarget);
    dragComponent = component;
    DragManager.acceptDragDrop(component);
    DragManager.showFeedback(DragManager.NONE);
}

private function confirmRemoveParticipant(event:CloseEvent):void
{
    if (event.detail == Alert.YES)
    {
        deleteReason = DeleteParticipantTitleWindow(PopUpManager.createPopUp( this, DeleteParticipantTitleWindow , true));
        dispatchEvent(deleteParticipantDropEvent); // Added as per mrm
        PopUpManager.centerPopUp(deleteReason);
        deleteReason.showCloseButton = true;
        deleteReason.title = "Reason for removal from project";
        deleteReason.addEventListener("close", cleanupRemoveParticipant);
        deleteReason["cancelButton"].addEventListener("click", cleanupRemoveParticipant);
        deleteReason["okButton"].addEventListener("click", finalizeDeleteParticipant);
        isDeletingParticipant = false; 
    }
    else
    {
        cleanupRemoveParticipant();
    }
}

private function cleanupRemoveParticipant(event:Event = null):void
{
    memberRpt.invalidateDisplayList();
    memberRpt.executeBindings();
    if (deleteReason != null)
    {
        PopUpManager.removePopUp(deleteReason);
        deleteReason = null;
    }
}

public function finalizeDeleteParticipant(event:Event):void
{
    if (deleteReason.reason.text != null)
    {
        selectedReportItem = memberRpt.selectedItem;
        selectedReportItemIndex = memberRpt.selectedIndex;
        memberReportData.removeItemAt(selectedReportItemIndex);
    }
    else
    {
        alert.info("You must provide a reason for removing a participant from your project!!");
    }

    cleanupRemoveParticipant();
}

Thanks in advance for all helpful suggestions.

Upvotes: 2

Views: 5385

Answers (6)

Reputation:

DragManager.showFeedback(DragManager.NONE);

Upvotes: 0

defmeta
defmeta

Reputation: 1322

Have you tried running the validateNow() method on the ADG after the cancel event?

Here is some more information on the validateNow() method.

Why you need to know about validateNow...

I really do think this is what you're looking for! Please let us know if that is the case...

Upvotes: 1

mrm
mrm

Reputation: 219

Here's an idea: - Just before you create the alert window, stop the DragEvent

event.stopImmediatePropagation();
  • store the event so we can resume if the user clicks the Yes button
queuedEvent = event as DragEvent;
  • show the alert window
  • if the user clicks the yes button, resume the queued event
dispatchEvent(queuedEvent);

Upvotes: 0

Sean Staats
Sean Staats

Reputation: 297

I didn't have any success with refreshing the data bindings on the datagrid via the executeBindings and invalidateDisplayList methods. I also didn't have any luck by showing the confirmation alert before making the webservice call. In fact, I discovered that making the webservice call was completely unnecessary and removed it. So now the code flows like this:

  1. Drag/drop ADG row onto trash icon.
  2. Display confirmation Alert box.
  3. If user clicked "Cancel" button, redisplay the ADG.

But the same problem persists. I'll update the Code section with the latest code.

Upvotes: 0

Simon
Simon

Reputation: 80789

Hang on... just spotted that between the drop event and the cancel button of the popup there is an asynchronous web service call which appears to be handled by GetParticipantOrderInformation. Is that correct?

If yes, then have you tried offering a simpler dialog for Cancel before you do that? I wonder whether the combination of layers of events is causing a problem.

Upvotes: 0

Simon
Simon

Reputation: 80789

Try refreshing the data bindings on the datagrid using executeBindings and/or invalidateDisplayList in the enclosing control.

To be honest this sounds a bit like a bug. Have you posted this on flexcoders? The Adobe guys hang out on there (probably here too, but definitely there)

Upvotes: 0

Related Questions