Item editor examples

来源:互联网 发布:制作艺术相册软件 编辑:程序博客网 时间:2024/05/20 21:23

Adobe Flex 3 Help > User Interfaces > Working with Item Editors

Adobe Flex 3 Help

User Interfaces / Working with Item Editors

Item editor examples

Example: Preventing a cell from being edited

From within an event listener for the itemEditBeginning event, you can inspect the cell being edited, and prevent the edit from occurring. This technique is useful when you want to prevent editing of a specific cell or cells, but allow editing of other cells.

For example, the DataGrid control uses the editable property to make all cells in the DataGrid control editable. You can override that for a specific column, using the editable property of a DataGridColumn, but you cannot enable or disable editing for specific cells.

To prevent cell editing, call the preventDefault() method from within your event listener for the itemEditBeginning event, as the following example shows:

<?xml version="1.0"?>

<!-- itemRenderers/events/EndEditEventPreventEdit.mxml -->

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

   

    <mx:Script>

        <![CDATA[

       

            import mx.events.DataGridEvent;

            import mx.collections.ArrayCollection;

       

            [Bindable]

            private var initDG:ArrayCollection = new ArrayCollection([

                {Artist:'Pavement', Album:'Slanted and Enchanted',

                    Price:11.99},

                {Artist:'Pavement', Album:'Brighten the Corners',

                    Price:11.99}

            ]);

           

            // Define event listener for the cellEdit event

            // to prohibit editing of the Album column.

            private function disableEditing(event:DataGridEvent):void {

                if(event.columnIndex==1)

                { 

                    event.preventDefault();

                }

            }  

                           

        ]]>

    </mx:Script>

   

    <mx:DataGrid id="myGrid"

        dataProvider="{initDG}"

        editable="true"

        itemEditBeginning="disableEditing(event);" >  

        <mx:columns>

            <mx:DataGridColumn dataField="Artist"/>

            <mx:DataGridColumn dataField="Album"/>

            <mx:DataGridColumn dataField="Price"/>

        </mx:columns>      

    </mx:DataGrid> 

</mx:Application>

 

Although the preceding example uses the column index, you could inspect any property of the DataGrid, or of the cell being edited, to make your decision about allowing the user to edit the cell.

Example: Modifying data passed to or received from an item editor

You can use the itemEditBegin and itemEditEnd events to examine the data passed to and from the item editor, and modify it if necessary. For example, you could reformat the data, extract a part of the data for editing, or examine the data to validate it.

In the next example, you use a NumericStepper control to edit the Price column of a DataGrid control. The itemEditBegin event modifies the data passed to the NumericStepper to automatically add 20% to the price when you edit it. Use the NumericStepper control to modify the updated price as necessary.

<?xml version="1.0"?>

<!-- itemRenderers/events/BeginEditEventAccessEditor.mxml -->

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

 

    <mx:Script>

      <![CDATA[

        import mx.events.DataGridEvent;

        import mx.controls.NumericStepper;

        import mx.collections.ArrayCollection;

        import mx.controls.listClasses.IDropInListItemRenderer;

   

        [Bindable]               

        private var myDP:ArrayCollection = new ArrayCollection([

            {Artist:'Pavement', Album:'Slanted and Enchanted', Price:11.99},

            {Artist:'Pavement', Album:'Crooked Rain, Crooked Rain', Price:10.99},

            {Artist:'Pavement', Album:'Wowee Zowee', Price:12.99},

            {Artist:'Pavement', Album:'Brighten the Corners', Price:11.99},

            {Artist:'Pavement', Album:'Terror Twilight', Price:11.99}

        ]);              

           

        // Handle the itemEditBegin event.

        private function modifyEditedData(event:DataGridEvent):void

        {

            // Get the name of the column being editted.

            var colName:String = myDataGrid.columns[event.columnIndex].dataField;

   

            if(colName=="Price")

            {

                // Handle the event here.

                event.preventDefault();

       

                // Creates an item editor.               

                myDataGrid.createItemEditor(event.columnIndex,event.rowIndex);

               

                // All item editors must implement the IDropInListItemRenderer interface

                // and the listData property.

                // Initialize the listData property of the editor.

                IDropInListItemRenderer(myDataGrid.itemEditorInstance).listData =

                    IDropInListItemRenderer(myDataGrid.editedItemRenderer).listData;

               

                // Copy the cell value to the NumericStepper control.

                myDataGrid.itemEditorInstance.data = myDataGrid.editedItemRenderer.data;

 

                // Add 20 percent to the current price.

                NumericStepper(myDataGrid.itemEditorInstance).value +=

                    0.2 * NumericStepper(myDataGrid.itemEditorInstance).value;   

           }

        }

      ]]>

    </mx:Script>

 

    <mx:DataGrid id="myDataGrid" dataProvider="{myDP}"

        editable="true"

        itemEditBegin="modifyEditedData(event);"

        rowHeight="60">

        <mx:columns>

            <mx:DataGridColumn dataField="Artist" />

            <mx:DataGridColumn dataField="Album" width="130" />

            <mx:DataGridColumn dataField="Price" editorDataField="value">

                <mx:itemEditor>

                    <mx:Component>

                        <mx:NumericStepper stepSize="0.01" maximum="500"/>

                    </mx:Component>

                </mx:itemEditor>

            </mx:DataGridColumn>

        </mx:columns>

    </mx:DataGrid>

</mx:Application>

 

You could use one of the Flex formatter classes to format data returned from an item editor. In the following example, you let the user edit the Price column of a DataGrid control. You then define an event listener for the itemEditEnd event that uses the NumberFormatter class to format the new cell value so that it contains only two digits after the decimal point, as the following code shows:

<?xml version="1.0"?>

<!-- itemRenderers/events/EndEditEventFormatter.mxml -->

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" >

   

    <mx:Script>

        <![CDATA[

       

            import mx.controls.TextInput;

            import mx.events.DataGridEvent;

            import mx.events.DataGridEventReason;

            import mx.formatters.NumberFormatter;

            import mx.collections.ArrayCollection;

       

            [Bindable]

            private var initDG:ArrayCollection = new ArrayCollection([

                {Artist:'Pavement', Album:'Slanted and Enchanted',

                    Price:11.99},

                {Artist:'Pavement', Album:'Brighten the Corners',

                    Price:11.99 }

            ]);

           

            // Define the number formatter.

            private var myFormatter:NumberFormatter=new NumberFormatter();

           

            // Define the eventlistner for the itemEditEnd event.

            public function formatData(event:DataGridEvent):void {  

                // Check the reason for the event.

                if (event.reason == DataGridEventReason.CANCELLED)

                {

                    // Do not update cell.

                    return;

                }           

 

                // Get the new data value from the editor.

                var newData:String=

                    TextInput(event.currentTarget.itemEditorInstance).text;

 

                // Determine if the new value is an empty String.

                if(newData == "") {

                    // Prevent the user from removing focus,

                    // and leave the cell editor open.

                    event.preventDefault();

                    // Write a message to the errorString property.

                    // This message appears when the user

                    // mouses over the editor.

                    TextInput(myGrid.itemEditorInstance).errorString=

                        "Enter a valid string.";

                    return;

                }

 

                // For the Price column, return a value

                // with a precision of 2.

                if(event.dataField == "Price") {

                    myFormatter.precision=2;

                    TextInput(myGrid.itemEditorInstance).text=

                        myFormatter.format(newData);

                }

            }          

        ]]>

    </mx:Script>

   

    <mx:DataGrid id="myGrid"

        dataProvider="{initDG}"

        editable="true"

        itemEditEnd="formatData(event);" >

        <mx:columns>

            <mx:DataGridColumn dataField="Artist"/>

            <mx:DataGridColumn dataField="Album"/>

            <mx:DataGridColumn dataField="Price"/>

        </mx:columns>      

    </mx:DataGrid> 

</mx:Application>

 

Example: Passing multiple values back from an item editor

The cell editing mechanism is optimized to work with item editors that return a single value to the list-based control. In the definition of the list-based control, you use the editorDataField property to specify the property of the item editor that contains the new cell data.

However, you might create an item editor that returns data in a format other than a single value. You could return multiple values, either multiple scalar values or an object containing the values.

To return data other than a single value, you write an event listener for the cellEndEvent that takes data from the item editor and writes it directly to the editedItemRenderer property of the list-based control. Writing it to the editedItemRenderer property also updates the corresponding data provider for the list-based control with the new data.

The following example shows an item editor implemented as a component that uses a TextInput control and a ComboBox control to let the user set the city and state portions of an address:

<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" 

    backgroundColor="yellow">

<!-- itemRenderers/events/myComponents/CityStateEditor.mxml -->

 

    <mx:TextInput id="setCity"  width="130" text="{data.City}"/>

                           

    <mx:ComboBox id="pickState" selectedItem="{data.State}">

        <mx:dataProvider>

            <mx:String>AL</mx:String>

            <mx:String>AK</mx:String>

            <mx:String>AR</mx:String>

            <mx:String>CA</mx:String>

            <mx:String>MA</mx:String>

        </mx:dataProvider>

    </mx:ComboBox>

</mx:VBox>

 

In the event listener for the cellEndEvent event, you access the new data in the TextInput and ComboBox controls by using the itemEditorInstance property of the list-based control. Then, you can write those new values directly to the editedItemRenderer property to update the list-based control, as the following example shows:

<?xml version="1.0"?>

<!-- itemRenderers/events/ComplexDGEditorReturnObject.mxml -->

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 

    width="700">

   

    <mx:Script>

        <![CDATA[

 

            import mx.events.DataGridEvent;

            import mx.events.DataGridEventReason;

            import mx.collections.ArrayCollection;

            import myComponents.CityStateEditor;

                       

            [Bindable]

            public var initDG:ArrayCollection = new ArrayCollection([

                {Company: 'Acme', Contact: 'Bob Jones',

                    Phone: '413-555-1212', City: 'Boston', State: 'MA'},

                {Company: 'Allied', Contact: 'Jane Smith',

                    Phone: '617-555-3434', City: 'SanFrancisco', State: 'CA'}

             ]);

               

            // Define the event listener.

            public function processData(event:DataGridEvent):void {

                // Check the reason for the event.

                if (event.reason == DataGridEventReason.CANCELLED){

                    // Do not update cell.

                    return;

                }          

 

                if(event.dataField == "City and State")

                {

                    // Disable copying data back to the control.

                    event.preventDefault();

 

                    // Get new city from editor.

                    myGrid.editedItemRenderer.data.City = CityStateEditor(DataGrid(event.target).itemEditorInstance).setCity.text;

 

                    // Get new state from editor.

                    myGrid.editedItemRenderer.data.State = CityStateEditor(DataGrid(event.target).itemEditorInstance).pickState.selectedItem;

 

                    // Close the cell editor.

                    myGrid.destroyItemEditor();

 

                    // Notify the list control to update its display.

                    myGrid.dataProvider.itemUpdated(event.itemRenderer.data);

                }

            }          

        ]]>

    </mx:Script>

   

    <mx:DataGrid id="myGrid"

        rowHeight="75"

        dataProvider="{initDG}"

        editable="true"

        itemEditEnd="processData(event);"> 

        <mx:columns>

            <mx:DataGridColumn dataField="Company" editable="false"/>

            <mx:DataGridColumn dataField="Contact"/>

            <mx:DataGridColumn dataField="Phone"/>

            <mx:DataGridColumn dataField="City and State" width="150"

                    itemEditor="myComponents.CityStateEditor">

                <mx:itemRenderer>

                    <mx:Component>

                        <mx:Text selectable="false" width="100%"

                            text="{data.City}, {data.State}"/>

                    </mx:Component>

                </mx:itemRenderer>

            </mx:DataGridColumn>

        </mx:columns>       

    </mx:DataGrid>     

</mx:Application>

 

Notice that the preceding example uses an inline item renderer to display the city and state in a single column of the DataGrid control.

The event listener for the itemEditEnd event determines if the column being edited is the city and state column. If so, the event listener performs the following actions:

1.           Calls the preventDefault() method to prevent Flex from returning a String value.

2.           Obtains the new city and state values from the item editor using the itemEditorInstance property of the list-based control.

3.           Calls the destroyItemEditor() method to close the item editor.

4.           Calls the itemUpdated() method to cause the list-based control to update its display based on the new data passed to it. If you do not call this method, the new data does not appear until the next time the list-based control updates its appearance.

For examples of using the List and Tree controls, see Using Item Renderers and Item Editors.

The following example performs the same action, but uses an inline item editor, rather than a component:

<?xml version="1.0"?>

<!-- itemRenderers/events/InlineDGEditorReturnObject.mxml -->

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 

    width="700">

   

    <mx:Script>

        <![CDATA[

 

            import mx.events.DataGridEvent;

            import mx.collections.ArrayCollection;

            import mx.controls.TextInput;

           

            public var newCity:String;

            public var newState:String;

           

            [Bindable]

            public var initDG:ArrayCollection = new ArrayCollection([

                {Company: 'Acme', Contact: 'Bob Jones',

                    Phone: '413-555-1212', City: 'Boston', State: 'MA'},

                {Company: 'Allied', Contact: 'Jane Smith',

                    Phone: '617-555-3434', City: 'SanFrancisco', State: 'CA'}

             ]);

               

            public function processData(event:DataGridEvent):void {                

                if(event.dataField=='City/State')

                {

                    // Disable copying data back to the control.

                    event.preventDefault();

                  

                    myGrid.editedItemRenderer.data.City=

                        myEditor(myGrid.itemEditorInstance).setCity.text;

                    myGrid.editedItemRenderer.data.State=

                        myEditor(myGrid.itemEditorInstance).pickState.selectedItem;

 

                    myGrid.destroyItemEditor();

                   

                    // Notify the list control to update its display.

                    myGrid.dataProvider.itemUpdated(myGrid.editedItemRenderer);

                }

            }          

        ]]>

    </mx:Script>

   

    <mx:DataGrid id="myGrid"

        rowHeight="75"

        dataProvider="{initDG}"

        editable="true"

        itemEditEnd="processData(event);"> 

        <mx:columns>

            <mx:DataGridColumn dataField="Company" editable="false"/>

            <mx:DataGridColumn dataField="Contact"/>

            <mx:DataGridColumn dataField="Phone"/>

            <mx:DataGridColumn dataField="City/State" width="150">

                <mx:itemRenderer>

                    <mx:Component>

                        <mx:Text selectable="false" width="100%"

                            text="{data.City}, {data.State}"/>

                    </mx:Component>

                </mx:itemRenderer>

 

                <mx:itemEditor>

                    <mx:Component className="myEditor">

                        <mx:VBox backgroundColor="yellow">

 

                            <mx:TextInput id="setCity" width="130"

                                text="{data.City}"/>

                           

                            <mx:ComboBox id="pickState"

                                selectedItem="{data.State}">

                                    <mx:dataProvider>

                                        <mx:String>AL</mx:String>

                                        <mx:String>AK</mx:String>

                                        <mx:String>AR</mx:String>

                                        <mx:String>CA</mx:String>

                                        <mx:String>MA</mx:String>

                                    </mx:dataProvider>

                            </mx:ComboBox>

                        </mx:VBox>

                    </mx:Component>                

                </mx:itemEditor>

            </mx:DataGridColumn>

        </mx:columns>      

    </mx:DataGrid> 

</mx:Application>

 

The <mx:Component> tag includes a className property with a value of "myEditor". The className property defines the name of the class that Flex creates to represent the inline item editor, just as the name of the MXML file in the previous example defines the name of the class for the component item editor. In the event listener for the itemEditEnd event, you can access the TextInput and ComboBox controls as properties of the myEditor class.

Example: Using an item renderer as an item editor

If you set the rendererIsEditor property of the DataGrid, List, or Tree control to true, the control uses the default TextInput control as the item editor, or the item renderer that specifies the itemRenderer property. If you specify an item renderer, you must ensure that you include editable controls in it so that the user can edit values.

For example, the following item renderer displays information in the cell by using the TextInput control, and lets the user edit the cell's contents:

<?xml version="1.0"?>

<!-- itemRenderers/dataGrid/myComponents/MyContactEditable.mxml -->

<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" >

 

   <mx:Script>

        <![CDATA[

            // Define a property for returning the new value to the cell.

            [Bindable]

            public var newContact:String;

        ]]>

    </mx:Script>

 

    <mx:Label id="title" text="{data.label1}"/>

    <mx:Label id="contactLabel" text="Last Contacted By:"/>

    <mx:TextInput id="contactTI"

        editable="true"

        text="{data.Contact}"

        change="newContact=contactTI.text;"/>

</mx:VBox>

 

You can use this item renderer with a DataGrid control, as the following example shows:

<?xml version="1.0"?>

<!-- itemRenderers/dataGrid/MainAppEditable.mxml -->

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"

    height="700" width="700">

   

    <mx:Script>

        <![CDATA[

            import mx.collections.ArrayCollection;

       

            [Bindable]

            private var initDG:ArrayCollection = new ArrayCollection([

                {label1: "Order #2314", Contact: "John Doe",

                    Confirmed: false, Photo: "john_doe.jpg", Sent: false},

                {label1: "Order #2315", Contact: "Jane Doe",

                    Confirmed: true, Photo: "jane_doe.jpg", Sent: false}

            ]);

        ]]>

    </mx:Script>

 

    <mx:DataGrid id="myDG"

        width="500" height="250"

        dataProvider="{initDG}"

        variableRowHeight="true" 

        editable="true">

        <mx:columns>

            <mx:DataGridColumn dataField="Photo"

                editable="false"/>

            <mx:DataGridColumn dataField="Contact"

                width="200"

                editable="true"

                rendererIsEditor="true"

                itemRenderer="myComponents.MyContactEditable"

                editorDataField="newContact"/>

            <mx:DataGridColumn dataField="Confirmed"

                editable="true"

                rendererIsEditor="true"

                itemRenderer="mx.controls.CheckBox"

                editorDataField="selected"/>

            <mx:DataGridColumn dataField="Sent"

                editable="true"

                rendererIsEditor="false"

                itemEditor="mx.controls.CheckBox"

                editorDataField="selected"/>

        </mx:columns>

    </mx:DataGrid>

</mx:Application>

 

In the previous example, you use the item renderer as the item editor by setting the rendererIsEditor property to true in the second and third columns of the DataGrid control.

Example: Using a data validator in a custom item editor

Just as you can validate data in other types of controls, you can validate data in the cells of list-based controls. To do so, you can create an item renderer or item editor that incorporates a data validator. For more information about data validators, see Validating Data.

The following example shows the code for the validating item editor component. It uses a TextInput control to edit the field. In this example, you assign a PhoneNumberValidator validator to the text property of the TextInput control to validate the user input:

<?xml version="1.0"?>

<!-- itemRenderers/validator/myComponents/EditorPhoneValidator.mxml -->

<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" >

   

    <mx:Script>

        <![CDATA[          

            // Define a property for returning the new value to the cell.

            [Bindable]

            public var returnPN:String;

        ]]>

    </mx:Script>

   

    <mx:PhoneNumberValidator id="pnV"

        source="{newPN}"

        property="text"

        trigger="{newPN}"

        triggerEvent="change"

        required="true"/>

    <mx:TextInput id="newPN"

        text="{data.phone}"

        updateComplete="returnPN=newPN.text;"

        change="returnPN=newPN.text;"/>           

</mx:VBox>

 

If the user enters an incorrect phone number, the PhoneNumberValidator draws a red box around the editor and shows a validation error message when the user moves the mouse over it.

The following example shows the code for the application that uses this item editor:

<?xml version="1.0" ?>

<!-- itemRenderers/validator/MainDGValidatorEditor.mxml -->

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

 

    <mx:Script>

        <![CDATA[

            import mx.collections.ArrayCollection;

       

            [Bindable]

            private var initDG:ArrayCollection = new ArrayCollection([

                {name: 'Bob Jones', phone: '413-555-1212',

                    email: 'bjones@acme.com'},

                {name: 'Sally Smith', phone: '617-555-5833',

                    email: 'ssmith@acme.com'},

            ]);

        ]]>

    </mx:Script>

   

    <mx:DataGrid id="dg"

        width="500" height="200"

        editable="true"

        dataProvider="{initDG}">

        <mx:columns>

            <mx:DataGridColumn dataField="name"

                headerText="Name" />

            <mx:DataGridColumn dataField="phone"

                headerText="Phone"

                itemEditor="myComponents.EditorPhoneValidator"

                editorDataField="returnPN"/>

            <mx:DataGridColumn dataField="email" headerText="Email" />

        </mx:columns>

    </mx:DataGrid>

</mx:Application>

 

 

Related Information

Help Resource Center

·                            Submit Feedback on LiveDocs

 

 

原创粉丝点击