views:

3081

answers:

8

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:

  • Dragging/Dropping a row onto the trash icon.
  • If the user clicks the "OK" button, the record is deleted.
  • If the user clicks the "Cancel" button, the operation is canceled.

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.

A: 

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)

Simon
A: 

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.

Simon
A: 

Simon, you are correct about the web service call. I have not tried a simpler dialog for canceling; however, that is a good idea and I'll try that before making the call to the web service.

Sean Staats
A: 

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.

Sean Staats
A: 

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);
mrm
A: 

@mrm - I did as you suggested but still no success.

Sean Staats
+1  A: 

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...

defmeta
A: 

DragManager.showFeedback(DragManager.NONE);