1
votes

FLEXBuilder 3 standalone, SDK 3.5

Hello, I have a List control with an item renderer. Through data binding, selection of an item in the list displays the corresponding data set in a form for editing. Changes are updated by clicking a SAVE button.

If changes have been made in the form but not saved, I need to prompt the user if they attempt to move to another List item. If they confirm the prompt, move to the item they clicked on, discarding their changes, if not, stay where they are so they have the opportunity to click "save".

I've tried with a Listener on the List's click event, also with preventDefault() but nothing seems to intercept the default function of changing the selected item.

Any help would be greatly appreciated.

2
Can you listen to the click event in the capture phase and perform a preventDefault() there? When you add the event listener (in ActionScript) there should be an argument for 'useCapture'. It is set to false by default [such as when you add the event listener in MXML]JeffryHouser

2 Answers

0
votes

You can try the following approach:

  • prevent mouse down event in capture phase
  • Itemclick event occures anyway, so just remember clicked item index and display confirmation dialog
  • In alet's close handler do the actual change if neccessary.

Here's an example:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" minWidth="955" minHeight="600"
            creationComplete="application1_creationCompleteHandler(event)"
            >
<mx:Script>
    <![CDATA[
        import mx.controls.Alert;
        import mx.events.CloseEvent;
        import mx.events.FlexEvent;
        import mx.events.ListEvent;

        [Bindable]
        private var formDirty:Boolean = false;              

        protected function application1_creationCompleteHandler(event:FlexEvent):void
        {
            myList.addEventListener(MouseEvent.MOUSE_DOWN, myList_mouseDownHandler, true);  
        }           


        protected function myList_mouseDownHandler(event:MouseEvent):void
        {
            if (formDirty)
            {
                event.preventDefault();
                event.stopImmediatePropagation();
            }
        }

        protected function myList_itemClickHandler(event:ListEvent):void
        {
            if (formDirty)
            {
                var alert:Alert  = Alert.show("Save changes?", "Confirm save", Alert.YES | Alert.NO | Alert.CANCEL, null, alertCloseHandler);
                alert.data = event.rowIndex;
            }
        }

        private function alertCloseHandler(evt:CloseEvent):void
        {
            var alert:Alert = evt.target as Alert;
            switch (evt.detail)
            {
                case Alert.YES:
                    //Save changes
                    //
                    // Whatever....
                    //
                case Alert.NO: 
                    //manually change list index cahnge
                    // we also fall here from Alert.Yes case
                    formDirty = false;
                    myList.selectedIndex = alert.data as int;
                    break;
                case Alert.CANCEL:
                    //Do notthing:
                    break;
            }                   
        }           


        protected function invalidateButton_clickHandler(event:MouseEvent):void
        {
            formDirty = true;   
        }

    ]]>
</mx:Script>
<mx:VBox>
    <mx:List id="myList" itemClick="myList_itemClickHandler(event)">
        <mx:dataProvider>
            <mx:ArrayCollection>
                <mx:String>Item 0</mx:String>
                <mx:String>Item 1</mx:String>
                <mx:String>Item 2</mx:String>
                <mx:String>Item 3</mx:String>
                <mx:String>Item 4</mx:String>
            </mx:ArrayCollection>
        </mx:dataProvider>
    </mx:List>
    <mx:Button id="invalidateButton" click="invalidateButton_clickHandler(event)"  label="{formDirty?'Invalidated':'Invalidate form'}" enabled="{formDirty?false:true}"/>
</mx:VBox>

0
votes

You can try extend the List and override the protected function mouseDownHandler(event:MouseEvent):void. There you can decide by some logic whether to call the super.mouseDownHandler(event) or just do nothing :)

Probably there is a better function to override and a better place for that but I'm leaving that thinking up to you.

Good luck!