Home > flex, tips & tricks > DataGrid – Confirm a Grid change event using an Alert popup

DataGrid – Confirm a Grid change event using an Alert popup

Today I saw an interesting post on FlexCoders. Suppose you have an editable DataGrid and you want to confirm through an Alert if the change should be made or not. Preventing the change is easy, you just need hook onto the itemEditEnd and call event.preventDefault(). The problem arises when you want to confirm this with the user using an Alert. This is because the Alert.show call is asynchronous. This means that the grid event will complete before the user can choose Yes or No.

public function editEnd(event :D ataGridEvent):void {

  Alert.show("Do you want to save changes?","Save changes",Alert.YES | Alert.NO,null,function(ev:CloseEvent):void {
      if (ev.detail == Alert.YES) {
        //LABEL2: This will be reached long after the LABEL1 has been reached. 
        //So at this point the grid has been executed the default behavior for the change event
      }
    });
    //LABEL1: Because of the asynchronous nature this will be reached right after the Alert.show call    

}

So my idea of solving this was to save the new value, prevent the default grid behavior of updating the dataProvider and update the data provider manually on the Alert.show closeHandler.

Here is some code that illustrates this:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
        initialize="initData()" layout="absolute">
  <mx:Script>
   <![CDATA[
       import mx.controls.TextInput;
       import mx.controls.Alert;
    import mx.collections.*;
    import mx.events.*;

      private var DGArray:Array = [
         {Artist:'Pavement', Album:'Slanted and Enchanted', Price:11.99},
         {Artist:'Pavement', Album:'Brighten the Corners', Price:11.99}];

      [Bindable]
      public var initDG:ArrayCollection;
      public function initData():void {
         initDG=new ArrayCollection(DGArray);
      }

      public function editEnd(event:DataGridEvent):void {

          //Save the data before calling Alert
        var myEditor:TextInput =
                    TextInput(event.currentTarget.itemEditorInstance);

        // Get the new value from the editor.
        var newVal:String = myEditor.text;
        var dataObject:Object = event.itemRenderer.data;
        var property:String = event.dataField;

        Alert.show("Do you want to save changes?","Save changes",Alert.YES | Alert.NO,null,function(ev:CloseEvent):void {
            //If we have clicked YES then update the data collection manually
            if (ev.detail == Alert.YES) {
                  dataObject[property] = newVal.toString();
                  initDG.itemUpdated(dataObject,property);
            }
          });

          //prevent data grid to update his dataProvider collection
          event.preventDefault();
      }
   ]]>
   </mx:Script>

   <mx:DataGrid id="myGrid" width="350" height="200"
      dataProvider="{initDG}" editable="true" itemEditEnd="editEnd(event)" >
      <mx:columns>
         <mx:DataGridColumn dataField="Album" />
         <mx:DataGridColumn dataField="Price" />
      </mx:columns>
   </mx:DataGrid>
   <mx:DataGrid id="readOnlyGrid" width="350" height="200"
      dataProvider="{initDG}" x="0" y="208">
      <mx:columns>
         <mx:DataGridColumn dataField="Album" />
         <mx:DataGridColumn dataField="Price" />
      </mx:columns>
   </mx:DataGrid>
</mx:WindowedApplication>
Categories: flex, tips & tricks Tags:
  1. No comments yet.
  1. No trackbacks yet.