Search Flex Components Free

Custom Search
Showing posts with label Flex with DataGrid. Show all posts
Showing posts with label Flex with DataGrid. Show all posts

July 6, 2009

Using a Web Service to populate a DataGrid with XML data

In this example I will be using XML data that is returned from a remote site. This example retrieves data about web sites (Name and URL). The XML data will be consumed and displayed in a FlexDataGrid control. Make sure you see the next blog about customizing a DataGrid. Here is a sample of the data returned by the program:



Google
http://google.com


Yahoo
http://yahoo.com



In this example, the data returned will be parsed and stored in an ArrayCollection object. Using an ArrayCollection is a good idea because it used in a lot of Flex tags as a data provider. It also include many methods that will allow you to manipulate the data. The following are the steps taken in Flex to retrieve the data and populate the DataGrid.
  1. Create the HttpService tag in Flex and link it to the XML source:
  2. url="http://some.examplewebsite.com/getSitesInXML.php"
    result="handleSiteData(event)" />

    id -- The name assigned to the service
    url -- is the source of the XML
    result -- Specify the name of the function that will handle the results. This function is called automatically. Incidentally, you can also add a method that will be invoked on errors (fault="someMethod()").
    resultFormat -- self explanatory.
  3. Send service request
  4. getSitesService.send();
    This is usually done upon application loading. For example, in the application tag you can add the code:
    applicationComplete="getSitesService.send();"
    Remember the method "handleSiteData()" will be called automatically upon successful return of the web service. Now, let's look at the method that will handle the returned result.

  5. Handle Site Data (Parse XML data)
    
    
    [Bindable]
    private var siteList:ArrayCollection;
    public function handleSiteData(event:ResultEvent):void {
    xmlData = XMLList(event.result);
    var siteArray:Array = new Array();
    for (var i:int = 0; i < xmlData.site.length(); i++) {
    //Create an object of type Site.
    //Site is a simple ActionScript class
    //that incldes a URL and a Name
    var s:Site = new Site(xmlData.site[i].URL,
    xmlData.site[i].Name);
    //Add the object to the array
    siteArray.push(s);
    }
    //Convert the array to an ArrayCollection
    siteList = new ArrayCollection(siteArray);
    }

    Now we have an 
    ArrayCollection of sites. This collection will be used as the "dataProvider" for the DataGrid control.

  6. Define the DataGrid Control to use the ArrayCollection "siteList" defined above.

Customizing Flex DataGrid with ItemRenderer

In this example I will be using an ArrayCollection as the data provider for the DataGrid. The ArrayCollection is of objects that represent web sites. Each object contains a Name and a URL. The data will be displayed with some customization. The customization include color, decoration, and action. Each of the items displayed will be linkable to the appropriate web site.
  • Define the DataGrid Control
    
    




    rollOver="setStyle('textDecoration','underline')"
    rollOut="setStyle('textDecoration','none')"
    useHandCursor="true" buttonMode="true"
    mouseChildren="false"
    click='navigateToURL(new URLRequest(data.URL),"_mine")'







    data refers the object being rendered. So, data.Name refers the the instance data Name within the object. Here the item renderer defines each item from the site list as a label. The label is then styled as follows:

    • The text is assigned the color #009ad4

    • Text is underlined when the cursor is placed on it and removed when rolled out.

    • It uses the hand cursor for the mouse

    • When text is clicked it calls navigateToURL method to launch the web site. If click event is calling a method defined in your file, you need to qualify the call withouterDocument to bring the functions within scope. For example, 
      click='outerDocument.myFunction(data.URL)'

March 24, 2008

Setting alternating item colors on a Flex PopUpButton control





<?xml version="1.0"?>


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

layout="horizontal"

verticalAlign="top"

backgroundColor="white">



<mx:Script>

<![CDATA[

import mx.controls.Menu;



[Bindable]

private var menu:Menu;



private function initMenu():void {

menu = new Menu();

menu.dataProvider = arr;

}

]]>

</mx:Script>



<mx:Array id="arr">

<mx:Object label="Button" />

<mx:Object label="ButtonBar" />

<mx:Object label="ColorPicker" />

<mx:Object label="ComboBox" />

</mx:Array>



<mx:Style>

PopUpButton {

popUpStyleName: myCustomPopUpStyleName;

}



.myCustomPopUpStyleName {

fontWeight: normal;

textAlign: left;

alternatingItemColors: white, #EEEEEE;

}

</mx:Style>



<mx:PopUpButton id="popUpButton"

label="Select a control..."

popUp="{menu}"

preinitialize="initMenu();"

creationComplete="popUpButton.open();" />



</mx:Application>


March 16, 2008

Determining if a Flex application has focus using the activate and deactivate events





The following example shows how you can determine if a Flex application has focus or not by listening for the activate and deactivate events on the <mx:Application /> container.


Full code after the jump.


View MXML


<?xml version="1.0" encoding="utf-8"?>

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

layout="vertical"

verticalAlign="middle"

backgroundColor="white"

activate="application_activate(event);"

deactivate="application_activate(event);">



<mx:Script>

<![CDATA[

import mx.controls.dataGridClasses.DataGridColumn;



private function application_activate(evt:Event):void {

arrColl.addItemAt({type:evt.type, time:getTimer()}, 0);

}



private function time_labelFunc(item:Object, col:DataGridColumn):String {

return numberFormatter.format(item[col.dataField]);

}

]]>

</mx:Script>



<mx:ArrayCollection id="arrColl" />



<mx:NumberFormatter id="numberFormatter"

useThousandsSeparator="true" />



<mx:DataGrid id="dataGrid"

dataProvider="{arrColl}"

width="320"

rowCount="8"

verticalScrollPolicy="on">

<mx:columns>

<mx:DataGridColumn dataField="type" />

<mx:DataGridColumn dataField="time"

headerText="time (ms)"

labelFunction="time_labelFunc" />

</mx:columns>

</mx:DataGrid>



</mx:Application>

February 6, 2008

FebDisabling item roll over highlighting in the Flex DataGrid control





<?xml version="1.0" encoding="utf-8"?>

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

layout="vertical"

verticalAlign="middle"

backgroundColor="white">



<mx:Script>

<![CDATA[

import mx.events.ListEvent;

import mx.controls.Alert;



private function dataGrid_change(evt:ListEvent):void {

Alert.show(evt.itemRenderer.data.label, evt.type);

}

]]>

</mx:Script>



<mx:Array id="arr">

<mx:Object label="Alert" />

<mx:Object label="Button" />

<mx:Object label="ButtonBar" />

<mx:Object label="CheckBox" />

<mx:Object label="ColorPicker" />

<mx:Object label="ComboBox" />

</mx:Array>



<mx:ApplicationControlBar dock="true">

<mx:CheckBox id="checkBox"

label="useRollOver:"

labelPlacement="left"

selected="true" />

</mx:ApplicationControlBar>



<mx:DataGrid id="dataGrid"

dataProvider="{arr}"

useRollOver="{checkBox.selected}"

rowCount="4"

width="200"

change="dataGrid_change(event);">

<mx:columns>

<mx:DataGridColumn dataField="label" />

</mx:columns>

</mx:DataGrid>



</mx:Application>

As you can see, when the useRollOver style is set to false , the item row highlight is not drawn when moving your mouse over an item in the DataGrid, but the background color is drawn if you select an item. If the useRollOver style is set to true , the item row highlight is drawn when hovering over a list item.


Since useRollOver is a style, you can also set it in an external .CSS file, or in an <mx:Style /> block, as shown in the following snippet:


<mx:Style>

DataGrid {

useRollOver: false;

}

</mx:Style>

Or, you can set the useRollOver style in ActionScript, as seen in the following snippet:


<mx:Script>

<![CDATA[

private function init():void {

dataGrid.setStyle("useRollOver", false);

}

]]>

</mx:Script>

January 5, 2008

Advanced DataGrid Code

We are publishing a set of three articles (excerpts from our book) in ColdFusion magazine (October, November and December) on advanced DataGrid techniques. Let the name of the magazine not mislead you - thes articles are written for all Flex developers, regardless of what has server-side technology they use.

Here is the url to all code samples from these articles:


http://samples.faratasystems.com/AdvancedDataGrid/index.html


Please note that source is available on the first page only. Also, was deploying in the rush - with debugging player you might see message boxes asking for debugger - just cancel them.

Advanced DataGrid Code


We are publishing a set of three articles (excerpts from our book) in ColdFusion magazine (October, November and December) on advanced DataGrid techniques. Let the name of the magazine not mislead you - thes articles are written for all Flex developers, regardless of what has server-side technology they use. Here is the url to all code samples from these articles:
http://samples.faratasystems.com/AdvancedDataGrid/index.html
Please note that source is available on the first page only. Also, was deploying in the rush - with debugging player you might see message boxes asking for debugger - just cancel them.

How to color Datagrid cells/rows in flex 2



















I have been looking for a easy and neat way to color a single cell or a complete row in flex 2.

<strong>Google brought me two interesting links:</strong>


<strong>1. How opaqueBackground can be used to color the background of a label itemRenderer</strong>

The comment posted by Dallas at 11/10/06 8:01, shows a way of highlighting a cell. Very simple implementation - the only problem is that the background color won't react on mouseover after the opaqueBackground is set.


<strong>2. How do you change the background cell color in a DataGrid?</strong>

Shows how to implement a colored background that react upon mouseover and selection. The implementation extends a label and overrides the 'updateDisplayList' method to draw some graphics as the background.


The last solution seems to be the one I preferred - because of the ability to see mouse effects applied to the cell. But still I liked the cleen implementation of the first one.


I couldn't resist of bringing combined solution, where I extends a Label, but listens for a Event.RENDER events instead of overriding the updateDisplayList method.


Sourcecode

Demonstrates how to use the renderer as a drop-in and inline itemRenderer.
<? xml version = "1.0" encoding = "utf-8" ?>

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

layout = "vertical" verticalAlign = "middle" xmlns : tmp = "component.dashboard.*"

creationComplete = "init()" >



< mx : Script >

private function init() : void {

myGrid.setFocus();

}

</ mx : Script >

< mx : XML id = "itemsXML" >

< items >

< item name = "Item 1" state = "1" />

< item name = "Item 2" state = "0" />

< item name = "Item 3" state = "0" />

< item name = "Item 4" state = "1" />

< item name = "Item 5" state = "0" />

</ items >

</ mx : XML >



< mx : Style >

.centered {

text-align: center;

}

</ mx : Style >



< mx : DataGrid id = "myGrid" dataProvider = "{itemsXML.item}" editable = "true" >

< mx : columns >

< mx : DataGridColumn dataField = "@name" headerText = "Name"

headerStyleName = "centered"

itemRenderer = "component.dashboard.TestItemRenderer" />



< mx : DataGridColumn dataField = "@state" headerText = "Price"

textAlign = "right" headerStyleName = "centered" >

< mx : itemRenderer >

< mx : Component >

< tmp : TestItemRenderer />

</ mx : Component >

</ mx : itemRenderer >

</ mx : DataGridColumn >

</ mx : columns >

</ mx : DataGrid >



</ mx : Application >
CustomItemRenderer.as

Following is a CustomItemRenderer that can be extended to apply logic to decide if a cell is to be styled.

package dk . jacobve {



import mx . controls . Label ;

import mx . controls . DataGrid ;

import mx . controls . dataGridClasses .*;

import mx . events . FlexEvent ;

import flash . events . Event ;



public class CustomItemRenderer extends Label {



public function CustomItemRenderer {

//listen for render events

addEventListener ( Event . RENDER , renderListener );

}



public function styleIt () : Boolean {

return false ;

}



public function styleTrue () : void {

}



public function styleFalse () : void {

}



protected function renderListener ( event : Event ) : void {

if ( listData != null ) {

var grid : DataGrid = DataGrid ( DataGridListData ( listData ). owner );

if (! grid . isItemHighlighted ( data ) && grid . selectedItem != data ) {

if ( styleIt ()) {

styleTrue ();

} else {

styleFalse ();

}

} else {

styleFalse ();

}

}

}

}

}
CustomItemRenderer extension

Shows an implementation using E4X on a xml data element to deside if the cell is to be colored red.
package dk . jacobve {



import mx . controls . Label ;

import mx . controls . DataGrid ;

import mx . controls . dataGridClasses .*;

import mx . events . FlexEvent ;

import flash . events . Event ;



public class TestItemRenderer extends CustomItemRenderer {

public override function styleIt () : Boolean {

return data . @state == "0" ;

}



public override function styleTrue () : void {

this . opaqueBackground = 0x33CC33 ;

}



public override function styleFalse () : void {

this . opaqueBackground = null ;

}

}

}

December 19, 2007

Displaying XML data in a DataGrid

Today’s handy tip comes in the form of loading and embedding an XML file in our Flex application at compile-time (as opposed to dynamically loading at run-time, which we’ll save for a future example), and displaying that information in a DataGrid control.
The following example loads an XML file at compile-time using the mx:XML and displays the information in a DataGrid:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?><FLVCoreCuePoints version="1">
<CuePoint> <Time>0</Time> <Type>event</Type> <Name>slide1</Name> <Parameters> <Parameter> <Name>id</Name> <Value>value</Value> </Parameter> </Parameters> </CuePoint>
<CuePoint> <Time>5000</Time> <Type>event</Type> <Name>slide2</Name> <Parameters> <Parameter> <Name>param1</Name> <Value>value1</Value> </Parameter> <Parameter> <Name>param2</Name> <Value>value2</Value> </Parameter> </Parameters> </CuePoint>
<CuePoint> <Time>20000</Time> <Type>event</Type> <Name>slide3</Name> </CuePoint>
</FLVCoreCuePoints><?xml version="1.0" encoding="utf-8"?><mx:Application xmlns:mx="
http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="top" backgroundColor="white">
<mx:XML id="tempXML" source="assets/cuePoints.xml" /> <mx:XMLListCollection id="cuePointXMLList" source="{tempXML.CuePoint}" /> <mx:XMLListCollection id="parametersXMLList" source="{dataGrid.selectedItem.Parameters.Parameter}" />
<mx:Script> <![CDATA[ private function parametersLabelFunction(item:Object, column:DataGridColumn):String { return item.Parameters.Parameter.length(); }
private function numericSortCompareFunction(objA:Object, objB:Object):int { var itemA:Number = parseInt(objA.Time.text()) as Number; var itemB:Number = parseInt(objB.Time.text()) as Number;
if (itemA > itemB) { return 1; } else if (itemA < itemB) { return -1; } else { return 0; } } ]]> </mx:Script>
<mx:VBox>
<mx:DataGrid id="dataGrid" dataProvider="{cuePointXMLList}" width="100%" rowCount="{cuePointXMLList.length + 1}"> <mx:columns> <mx:DataGridColumn id="timeCol" dataField="Time" headerText="Time (ms):" sortCompareFunction="numericSortCompareFunction" /> <mx:DataGridColumn id="typeCol" dataField="Type" headerText="Type:" /> <mx:DataGridColumn id="nameCol" dataField="Name" headerText="Name:" /> <mx:DataGridColumn id="parametersCol" dataField="Parameters" headerText="Parameters:" labelFunction="parametersLabelFunction" /> </mx:columns> </mx:DataGrid>
<mx:DataGrid id="parametersDataGrid" dataProvider="{parametersXMLList}" width="100%" visible="{parametersXMLList.length > 0}" rowCount="{parametersXMLList.length + 1}"> <mx:columns> <mx:DataGridColumn id="parameterNameCol" dataField="Name" headerText="Parameter Name:" /> <mx:DataGridColumn id="parameterValueCol" dataField="Value" headerText="Parameter Value:" /> </mx:columns> </mx:DataGrid>
</mx:VBox>
</mx:Application>

December 18, 2007

Converting between dates and strings using the DateField class in Flex 3 . 0

The following example shows how you can convert Date objects to String objects using the static DateField.dateToString() method in Flex. As an added bonus, the example also shows how you can convert String objects to Date Objects using the static DateField.stringToDate() method.
Full code after the jump.


<?xml version="1.0" encoding="utf-8"?><mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle" backgroundColor="white" creationComplete="init();">
<mx:Script> <![CDATA[ import mx.controls.DateField;
private const MASK:String = "DD/MM/YYYY";
private function init():void { var today:Date = new Date(); var halloween:String = "31/10/2007";
var todayString:String = DateField.dateToString(today, "DD/MM/YYYY"); todayLabel.text = todayString;
var halloweenDate:Date = DateField.stringToDate(halloween, "DD/MM/YYYY"); halloweenLabel.text = halloweenDate.toDateString(); } ]]> </mx:Script>
<mx:Form> <mx:FormItem label="today ({MASK}):"> <mx:Label id="todayLabel" /> </mx:FormItem> <mx:FormItem label="Halloween:"> <mx:Label id="halloweenLabel" /> </mx:FormItem> </mx:Form>
</mx:Application>

December 17, 2007

Autosizing Datagrid with Horizontal Scrolling

Today I was tasked with creating a spreadsheet like datagrid, one with more columns than what the available real estate would be able to show. The datagrid was to always use the maximum screen space available so that for those users with huge budgets and subsequently huge monitors would not need to scroll. For all other, more mortal users, the datagrid should simply scroll off to the right, with a nice horizontal scroll bar.

I figured this would be easy. Turns out it's a bit tricky. If I set the maxWidth of my datagrid to something smaller than the sum of my column widths, the desired behaviour would occur. I'd get a nice horizontal scroll bar and the columns would span out to the right. The problem with maxWidth is that it does not accept percentage values. So if I want the datagrid to use up 100% of the width of the parent container, I can't use maxWidth.

I tried sticking the datagrid in a canvas, thinking i'd be able to use the scrolling of the canvas to quasi hover/move over the datagrid rendered in its entirety underneath, but the vertical scrolling didn't really work out well. Perhaps someone else might have more luck with this approach. I kinda wanted to get back to using the scrollbars in the datagrid, as it seemed that this HAD to be possible!

I figured the solution had to lie in maxWidth. I put the datagrid inside a canvas and made the canvas size percentage based. I then, in a resize() function triggered by creationComplete of the app, assigned the value of the width of the canvas to the maxWidth property of my datagrid. This seemed to work. I also tried to have the resize event of the app call this function instead but I'd get null errors. Turned out I needed to assign the event listener on creationComplete.

Everything looked good, the datagrid was resizing with the canvas. At certain times however the datagrid seemed to lag behind and not fill the canvas properly. Using callLater fixed this. Here's the Demo. Right click on the demo to get the source.

Related Flex Tutorials