April 8th, 2008 by Kyle
Tags: , , ,
Posted in: Flex


The flex docs show how to use a DateField component as a Datagrid itemEditor. But what if your date data is actually a string instead of a date object? The sample below shows how to code a custom itemEditor extending the DateField component that allows you to do this. (I have also show how to use the drop in DateField as an editor for Dates.)

This movie requires Flash Player 9

Download a zipfile containing the source to this sample.

Browse the source of this example.

Or continue into the blog entry to see the source:
Read the rest of this post»




14 Comments »

February 18th, 2008 by Kyle
Tags: , , , , ,
Posted in: Flex


Here is a sample that came about as usual, from working on an issue with a customer. I found I didn’t have a good example of a combobox itemEditor. This sample came about when moving from using a combobox as an inline editor to moving to a combobox within a custom component as an editor. Wrapping the combobox in a VBox within the custom component caused some errors and undesirable behavior. In order to wire up data and tabbing/focus behavior you have to remember you component should implement IDropInListItemRenderer and IFocusManagerComponent. See the following sample code and running sample:

App:

< ?xml version="1.0" encoding="utf-8"?>
<mx:application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:xml id="xml" source="weather.xml"/>
    <mx:datagrid id="myDatagrid" dataProvider="{xml.city}"
        variableRowHeight="true" editable="true" rowHeight="50"
        width="300" height="300">
        <mx:columns>
        <mx:datagridcolumn dataField="Location"/>
        <mx:datagridcolumn dataField="Climate" editable="true" editorDataField="value">
            <mx:itemeditor>
                <mx:component>
                    <mx:combobox editable="true">
                        <mx:dataprovider>
                            <mx:string>Mild</mx:string>
                            <mx:string>Hot</mx:string>
                            <mx:string>Foggy</mx:string>
                            <mx:string>Rainy</mx:string>
                            <mx:string>Snow</mx:string>
                        </mx:dataprovider>
                    </mx:combobox>
                </mx:component>
            </mx:itemeditor>
        </mx:datagridcolumn>
        <mx:datagridcolumn dataField="CloudCoverPercent" editable="true" editorDataField="value"
            itemEditor="CloudCover"/>
    </mx:columns>
    </mx:datagrid>
</mx:application>
 

Read the rest of this post»




27 Comments »

December 12th, 2007 by Kyle
Tags: , , , ,
Posted in: ActionScript, Flex


This isn’t as difficult as some may think. Basically your itemRenderer opens up a popup. When the renderer creates the popup, it sets an “opener” property on the popup pointing back to “this”, which is the itemRenderer. That way, when the editing is finished in the popup, the popup can pass data back to a function in the itemRenderer to do the update, close itself, and set focus back to the itemRenderer.

Here is the code for the app:

< ?xml version="1.0" encoding="utf-8"?>
<mx:application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*" >
    <mx:array id="arr">
        <mx:object articleName="Finding out a characters Unicode character code Downloading the latest Adobe Labs version of Flex 3 SDK/Flex Builder 3 (codename: Moxie)" data="15" />
        <mx:object articleName="Setting an icon in an Alert control" data="14" />
        <mx:object articleName="Setting an icon in a Button control" data="13" />
        <mx:object articleName="Installing the latest nightly Flex 3 SDK build into Flex Builder 3" data="10" />
        <mx:object articleName="Detecting which button a user pressed to dismiss an Alert dialog" data="9" />
        <mx:object articleName="Using the Alert control Formatting data tips in a Slide" data="8" />
    </mx:array>
    <mx:arraycollection id="AC" source="{arr}" />    

    <mx:datagrid height="250" dataProvider="{AC}" variableRowHeight="true" width="60%" editable="true">
        <mx:columns>
            <mx:datagridcolumn dataField="data" headerText="ID" editable="false" width="125"/>
            <mx:datagridcolumn editable="false" wordWrap="true"
                headerText="Article Name"              
                itemRenderer="MyRenderer" dataField="articleName"/>
        </mx:columns>
    </mx:datagrid>
</mx:application>
 

Read the rest of this post»




9 Comments »

December 11th, 2007 by Kyle
Tags: , , , , , , , ,
Posted in: Flex


I had a customer asking how to do this.
Sorting the datagrid sorts the underlying dataprovider.
Remember that things like ArrayCollections are just essentially views of the data. So adding an element to the underlying data, regardless of the position at which you add the new item, will not affect its position in the “view”. It will get added in its sorted position if the view is showing sorted data. The workaround to this is show in the simple sample below:

<mx:application xmlns:mx="http://www.adobe.com/2006/mxml" creationcomplete="init()">
    <mx:script>
        <!–[CDATA[
            import mx.collections.ArrayCollection;

            public var objs:ArrayCollection = new ArrayCollection();
            /*
             * initialize the dataprovider
             */

            private function init():void {

                var obj:Object = new Object();
                obj.name = "carry";
                objs.addItem(obj);

                obj = new Object();
                obj.name = "fred";
                objs.addItem(obj);

                obj = new Object();
                obj.name = "henry";
                objs.addItem(obj);

                obj = new Object();
                obj.name = "issac";
                objs.addItem(obj);

                obj = new Object();
                obj.name = "mary";
                objs.addItem(obj);

                obj = new Object();
                obj.name = "tom";
                objs.addItem(obj);

                obj = new Object();
                obj.name = "tom2";
                objs.addItem(obj);

                dg.dataProvider = objs;
            }

            import flash.utils.ByteArray;

            private function clone(source:Object):*
            {
                var myBA:ByteArray = new ByteArray();
                myBA.writeObject(source);
                myBA.position = 0;
                return(myBA.readObject());
            }

            private function addObj():void{

                var temp:Array = clone(objs.toArray());
                objs=new ArrayCollection(temp);
                dg.dataProvider=objs;

                var obj:Object = new Object();
                obj.name=;
                objs.addItemAt(obj, 0)

            }

        ]]–>
    </mx:script>
    <mx:button width="150" label="Add New Row" click="addObj()">
    <mx:datagrid id="dg" editable="true" width="50%" height="80%">
    <mx:columns>
        <mx:datagridcolumn headertext="Name" datafield="name">
            editable="true" />
    </mx:datagridcolumn>
</mx:columns>                                                  

</mx:datagrid>
</mx:button></mx:application>

Browse the source of this example.
Download a zipfile containing the source to this sample.

This movie requires Flash Player 9




3 Comments »

November 26th, 2007 by Kyle
Tags: , , , , , , , ,
Posted in: Flex


This is a follow on to my previous blog entry:
http://blog.739saintlouis.com/2007/11/22/flex-linebreaks-in-the-datagrid/

Here I show how to deal with line breaks in itemRenderer and itemEditors instead of in a datagrid labelFunction.
(This is also a nice example of writing simple, separate itemRenderer and itemEditors.)
Read the rest of this post»




4 Comments »

November 22nd, 2007 by Kyle
Tags: , , , , , , , ,
Posted in: Flex


This is a follow up to my previous linebreak post.

This demonstrates how to deal with parsing linebreaks when they are in the text data for a datagrid.
You can either escape them in your source text data as shown in the previous post or you can use a labelFunction and some simple regular expression parsing to handle the escaping.

Here is the application code:

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

    <mx:script>
        <!–[CDATA[
        private function format(item:Object, column:DataGridColumn):String{
            var str:String=item[column.dataField]–>            var myPattern:RegExp = /\\n/g;
            var newStr:String=str.replace(myPattern, "\n");
            return newStr;
        }
        ]]>
    </mx:script>

    <mx:array id="arr1">
        <mx:object articlename="Finding out a characters \nUnicode character \ncode" data="15">
        <mx:object articlename="Setting an icon in an Alert control" data="14">
        <mx:object articlename="Setting an icon in a Button control" data="13">
        <mx:object articlename="Installing the latest nightly \nFlex 3 SDK build into Flex Builder 3" data="10">
        <mx:object articlename="Detecting which button a user pressed to dismiss an Alert dialog" data="9">
        <mx:object articlename="Using the Alert control" data="8">
        <mx:object articlename="Formatting data tips in a Slider" data="7">
        <mx:object articlename="Downloading the latest Adobe Labs version of Flex 3 SDK/Flex Builder 3 (codename: Moxie)" data="6">
    </mx:object>
    <mx:arraycollection id="arrColl" source="{arr1}">
    <mx:array id="arr2">
        <mx:object articlename="Finding out a characters {‘\n‘}Unicode character code" data="15">
        <mx:object articlename="Setting an icon in an Alert control" data="14">
        <mx:object articlename="Setting an icon in a Button control" data="13">
        <mx:object articlename="Installing the latest nightly {‘\n‘}Flex 3 SDK build into Flex Builder 3" data="10">
        <mx:object articlename="Detecting which button a user pressed to dismiss an Alert dialog" data="9">
        <mx:object articlename="Using the Alert control" data="8">
        <mx:object articlename="Formatting data tips in a Slider" data="7">
        <mx:object articlename="Downloading the latest Adobe Labs version of Flex 3 SDK/Flex Builder 3 (codename: Moxie)" data="6">
    </mx:object>
    <mx:arraycollection id="arrColl2" source="{arr2}">    

    <mx:text text="this dg uses a labelFunction to manipulate the linebreaks">

    <mx:datagrid id="dataGrid" dataprovider="{arrColl}" variablerowheight="true" width="60%" height="35%">
        <mx:columns>
            <mx:datagridcolumn labelfunction="format" datafield="articleName" headertext="Name of the article in question">
            <mx:datagridcolumn datafield="data" headertext="ID of the article">
        </mx:datagridcolumn>
    </mx:datagridcolumn>  

    <mx:text text="this dg has the linebreaks modified in the source {‘\n‘}arraycollection using curly braces and single quotes.">

    <mx:datagrid dataprovider="{arrColl2}" variablerowheight="true" width="60%" height="35%">
        <mx:columns>
            <mx:datagridcolumn datafield="articleName" headertext="Name of the article in question">
            <mx:datagridcolumn datafield="data" headertext="ID of the article">
        </mx:datagridcolumn>
    </mx:datagridcolumn>
</mx:columns>
</mx:datagrid></mx:text></mx:columns></mx:datagrid></mx:text></mx:arraycollection></mx:object></mx:object></mx:object></mx:object></mx:object></mx:object></mx:object></mx:array></mx:arraycollection></mx:object></mx:object></mx:object></mx:object></mx:object></mx:object></mx:object></mx:array></mx:application>

Browse the source of this example.
Download a zipfile containing the source to this sample.

This movie requires Flash Player 9




1 Comment »

Here is another good datagrid itemrender that I refer to when starting on datagrid renderer issues for customers.
It demonstrates how to create an itemEditor that is based on VBox and has child components (in this case a checkbox) and demonstrates how to implement the IDropInListItemRenderer and IFocusManagerComponent interfaces.
The sample also demonstrates how to add a listener to the underlying dataprovider arraycollection to detect change events and show what data has changed when edits are committed to the collection.

Here is the code for the application:

<mx:application xmlns:mx="http://www.adobe.com/2006/mxml" creationcomplete="init()">
    <mx:script>
        <!–[CDATA[
            import mx.events.CollectionEvent;
            import mx.events.DataGridEventReason;
            import mx.collections.ArrayCollection;
            import mx.events.DataGridEvent;
            import mx.events.ListEvent;

            [Bindable]–>            private var myAC:ArrayCollection = new ArrayCollection([
                {id:89, Contact: ‘Bob Jones’, FollowUp: true },
                {id:5, Contact: ‘Jane Smith’, FollowUp: true },
                {id:7, Contact: ‘Doug Johnson’, FollowUp: false },
                {id:15, Contact: ‘John Jackson’, FollowUp: true },
                {id:21, Contact: ‘Christina Coenraets’, FollowUp: true },
                {id:4, Contact: ‘Joanne Wall’, FollowUp: false },
                {id:461, Contact: ‘Maurice Smith’, FollowUp: false },
                {id:35, Contact: ‘Lorraine Barnes’, FollowUp: true },
                {id:61, Contact: ‘The Dude’, FollowUp: true },
                {id:56, Contact: ‘Abe Rockaway’, FollowUp: true }

            ]);

            private function init():void{
                myAC.addEventListener(CollectionEvent.COLLECTION_CHANGE, onChange);
            }

            private function onChange(event:CollectionEvent):void{
                for (var i:int=0; i < event.items.length;i++){
                    var obj:Object=event.items[i].source;
                     for (var p:String in obj) {
                            if(p!="mx_internal_uid"){
                                cellInfo.text += "\n";
                                if(event.items[i].property==p){cellInfo.text +="*"}
                                 cellInfo.text += p+": " + obj[p];
                            }
                        }
                }
            }

        ]]>
    </mx:script>
    <mx:datagrid id="myGrid">
        dataProvider="{myAC}" editable="true" >
        <mx:columns>
            <mx:datagridcolumn datafield="Contact" width="150">
            </mx:datagridcolumn><mx:datagridcolumn datafield="id" width="150" editable="false">
            </mx:datagridcolumn><mx:datagridcolumn datafield="FollowUp">
                width="150"
                headerText="Follow Up?"
                itemRenderer="DGCheckBoxEditor" rendererIsEditor="true"
                editorDataField="cbSelected"/>
        </mx:datagridcolumn>
     

    <mx:textarea id="cellInfo" width="300" height="150">    

</mx:textarea>
</mx:columns></mx:datagrid></mx:application>

Read the rest of this post»




9 Comments »

November 1st, 2007 by Kyle
Tags: , , ,
Posted in: Flex


I had a customer that noticed that when you disable the datagrid, it does not “gray out” like other components. I went digging around in the code and found that the datagrid did in fact “gray out” but the opacity of the background blocked the effect out. The header also didn’t seem to “gray out”, so I took care of both issues in my extension to dataGrid as shown below.

Here is my simple app to demonstrate the issue and workaround:

<mx:application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:my="*">

    <mx:xmllist id="employees">
        <iployee>
            <name>Christina Coenraets</name>
<phone>555-219-2270</phone>
            <iail>ccoenraets@fictitious.com</iail>
            <active>true</active>
        </iployee>
        <iployee>
            <name>Joanne Wall</name>
<phone>555-219-2012</phone>
            <iail>jwall@fictitious.com</iail>
            <active>true</active>
        </iployee>
        <iployee>
            <name>Maurice Smith</name>
<phone>555-219-2012</phone>
            <iail>maurice@fictitious.com</iail>
            <active>false</active>
        </iployee>
        <iployee>
            <name>Mary Jones</name>
<phone>555-219-2000</phone>
            <iail>mjones@fictitious.com</iail>
            <active>true</active>
        </iployee>
    </mx:xmllist>

        <mx:label text="Default DataGrid">
        <mx:datagrid id="dg" width="100%" height="100%" rowcount="5" dataprovider="{employees}">
            <mx:columns>
                <mx:datagridcolumn datafield="name" headertext="Name">
                <mx:datagridcolumn datafield="phone" headertext="Phone">
                <mx:datagridcolumn datafield="email" headertext="Email">
            </mx:datagridcolumn>
        </mx:datagridcolumn>

        <mx:label text="Custom DataGrid">
        <my:mydatagrid id="mydg" width="100%" height="100%" rowcount="5" dataprovider="{employees}">
            <my:columns>
                <mx:datagridcolumn datafield="name" headertext="Name">
                <mx:datagridcolumn datafield="phone" headertext="Phone">
                <mx:datagridcolumn datafield="email" headertext="Email">
            </mx:datagridcolumn>
        </mx:datagridcolumn>

<mx:button label="enable/disable DG" click="mydg.enabled=!mydg.enabled;dg.enabled=!dg.enabled">

</mx:button>
</mx:datagridcolumn></my:columns></my:mydatagrid></mx:label></mx:datagridcolumn></mx:columns></mx:datagrid></mx:label></mx:application>

Here is my custom extension to datagrid:

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

    <mx:script>
        <!–[CDATA[

        private var original_backgroundAlpha:Number;
        private var original_headerColors:Array;       

        override public function set enabled(value:Boolean):void
        {
            if(isNaN(original_backgroundAlpha)){
                original_backgroundAlpha=1;
            }

            if(value){
                this.setStyle("backgroundAlpha",original_backgroundAlpha);
                if(original_headerColors){
                    this.setStyle("headerColors",original_headerColors);
                }
            }
            else{
                original_backgroundAlpha=this.getStyle("backgroundAlpha");
                original_headerColors=this.getStyle("headerColors");
                this.setStyle("backgroundAlpha",original_backgroundAlpha*.75)

                var bgDC:Number=this.getStyle("backgroundDisabledColor");

                this.setStyle("headerColors",[bgDC,bgDC]–>         }

            super.enabled = value;
        }
        ]]>
    </mx:script>

</mx:datagrid>

Here is the running application:

This movie requires Flash Player 9

Browse the source of this example.
Download a zipfile containing the source to this sample.




No Comments »

I have come across a few cases where it was useful to have the column and row positions within an itemRenderer and so have made this sample to demonstrate how to do that.

Here is the application code:

<mx:application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:script>
        <!–[CDATA[
            import mx.events.DataGridEvent;
            import mx.collections.ArrayCollection;

            private static var object1:Object = new Object();
                                object1.name = "Object 1";

            private static var object2:Object = new Object();
                                object2.name = "Object 2";

            private static var object3:Object = new Object();
                                object3.name = "Object 3";

            private static var object4:Object = new Object();
                                object4.name = "Object 4";

            private static var object5:Object = new Object();
                                object5.name = "Object 5";

            private static var object6:Object = new Object();
                                object6.name = "Object 6";

            private static var object7:Object = new Object();
                                object7.name = "Object 7";

            private var things:Array = [object1, object2, object3, object4, object5, object6, object7]–>
            [Bindable]
            public var thingsAC:ArrayCollection = new ArrayCollection(things);

        ]]>
    </mx:script>

    <mx:datagrid id="dg" width="510" height="100">
         draggableColumns="false" dataProvider="{thingsAC}"
         horizontalScrollPolicy="on"
         rowCount="4">

        <mx:columns>
            <mx:datagridcolumn width="200" headertext="Name" datafield="name">
            <mx:datagridcolumn width="200" headertext="Column 2" itemrenderer="MyIR">
            <mx:datagridcolumn width="200" headertext="Column 3" itemrenderer="MyIR">
            <mx:datagridcolumn width="200" headertext="Column 4" itemrenderer="MyIR">
        </mx:datagridcolumn>
    </mx:datagridcolumn>

</mx:datagridcolumn>
</mx:datagridcolumn></mx:columns></mx:datagrid></mx:application>

Here is the code for my itemRenderer:

<mx:vbox xmlns:mx="http://www.adobe.com/2006/mxml" horizontalalign="center">
    implements="mx.controls.listClasses.IDropInListItemRenderer"
    preinitialize ="init();">

    <mx:script>
    <!–[CDATA[
        import mx.controls.DataGrid;
        import mx.controls.dataGridClasses.DataGridListData;
        import mx.controls.listClasses.BaseListData;
        import flash.events.Event;
        import mx.collections.ArrayCollection;        

        [Bindable]–>       public var _lbl:String;

        private function onChange(event:Event):void{
            var myListData:DataGridListData = DataGridListData(listData);
        }

        private var _listData:BaseListData;
        private var myDG:DataGrid;

        public function get listData():BaseListData {
          return _listData;
        }
        public function set listData( value:BaseListData ):void {
            _listData = value;
            myDG = _listData.owner as DataGrid;

        }  

        public function init():void {
            addEventListener("dataChange", handleDataChanged);
        }    

        public function handleDataChanged(event:Event):void {
            // Cast listData to DataGridListData.
            var myListData:DataGridListData = DataGridListData(listData);

            var row:int=myListData.rowIndex+myDG.verticalScrollPosition;
            //to make 1 based
            var col:int=myListData.columnIndex+1;

            _lbl="row: " + String(row) +
                " column: " + String(col);

        }    

        ]]>
    </mx:script>
    <mx:label id="lbl" text="{_lbl}">
</mx:label>
</mx:vbox>

Here is the running application:

This movie requires Flash Player 9

Browse the source of this example.
Download a zipfile containing the source to this sample.




4 Comments »

October 26th, 2007 by Kyle
Tags: , , , , , ,
Posted in: Flex


I was helping a customer with a simple sample and couldn’t find one that was specifically what I needed. The docs did have a sample for filtering an arraycollection bound to a combobox (I think) and this wasn’t much of a stretch, but I thought it would be useful to post the sample for the datagrid scenario so that it was no stretch.

Here is the application code:

<mx:application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:script>
        <!–[CDATA[
            import mx.collections.*;
            import mx.events.ItemClickEvent;            

            private var selectedRegion:String;

            public function regionFilterFunc(item:Object):Boolean {
                if (selectedRegion=="all")
                    return true
                else
                    return item.region == selectedRegion;
            }

            // Function to apply the filter function the ICollectionView.
            public function filterAC(event:ItemClickEvent):void {
                selectedRegion=event.label;
                myAC.filterFunction=regionFilterFunc;
                //Refresh the collection view to apply the filter.
                myAC.refresh();
            }

        ]]–>
    </mx:script>

    <!– An ArrayCollection with an array of objects. –>
    <mx:arraycollection id="myAC">
        <mx:array id="myArray">
            <mx:object state="LA" city="Baton Rouge" region="west">
            <mx:object state="NH" city="Concord" region="east">
            <mx:object state="TX" city="Austin" region="west">
            <mx:object state="MA" city="Boston" region="east">
            <mx:object state="AZ" city="Phoenix" region="west">
            <mx:object state="OR" city="Salem" region="west">
            <mx:object state="FL" city="Tallahassee" region="east">
            <mx:object state="MN" city="Saint Paul" region="east">
            <mx:object state="NY" city="Albany" region="east">
        </mx:object>
    </mx:object>

    <mx:togglebuttonbar id="tbb" horizontalgap="5" itemclick="filterAC(event);">
            <mx:dataprovider>
                <mx:array>
                    <mx:string>all</mx:string>
                    <mx:string>east</mx:string>
                    <mx:string>west</mx:string>
                </mx:array>
            </mx:dataprovider>
        </mx:togglebuttonbar>

    <mx:datagrid id="dg" width="100%" height="100%" rowcount="5" dataprovider="{myAC}">
        <mx:columns>
            <mx:datagridcolumn datafield="state" headertext="State">
            <mx:datagridcolumn datafield="city" headertext="City">
            <mx:datagridcolumn datafield="region" headertext="region">
        </mx:datagridcolumn>
    </mx:datagridcolumn>

</mx:datagridcolumn>
</mx:columns></mx:datagrid></mx:object></mx:object></mx:object></mx:object></mx:object></mx:object></mx:object></mx:array></mx:arraycollection></mx:application>

Here is the running sample:

This movie requires Flash Player 9

Browse the source of this example.
Download a zipfile containing the source to this sample.




3 Comments »

« Previous Entries