17 Mar 2010

Creating an Enterprise Flex Grid – Dynamic Columns (Part 1)

Posted by TomeK

Dynamic DataGrid Columns (Part 1)

In this multi-part we will create a powerful Flex enterprise Excel like grid. It will by dynamic in every way possible. We will support an arbitrary number of columns hooked in to a strongly typed data provider that is capable of a arbitrary number of properties. Later we will even learn how to perform on the fly calculations between cells. We will start simple but get to advanced by end of Part 2.

Part 1 Goal

Create a dynamic column DataGrid/AdvancedDataGrid. In this example we need dynamic column because we are displaying prices across an arbitrary time range. The Product column is fixed but time columns horizontally scroll.

Here is our starting MXML/ActionScript code

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
				verticalAlign="middle" horizontalAlign="center" backgroundColor="white"
				layout="vertical" width="100%" height="100%">
<mx:Script>
	<![CDATA[

import mx.collections.ArrayCollection;
[Bindable] private var rows:ArrayCollection =
	new ArrayCollection([
		{product: 'Ski', price0: 10, price1: 20,
			price2: 30, price3: 40, price4: 50, price5: 60},
		{product: 'Sword', price0: 0, price1: 0,
			price2: 3, price3: 4, price4: 0, price5: 0},
		{product: 'Beer', price0: 5, price1: 5,
			price2: 6, price3: 4, price4: 4, price5: 5}]);

	]]>
</mx:Script>
<mx:DataGrid width="400" height="150" lockedColumnCount="1"
			 horizontalScrollPolicy="on" dataProvider="{rows}">
	<mx:columns>
		<mx:DataGridColumn headerText="Product" dataField="product" width="100" />
		<mx:DataGridColumn headerText="Jan 2010" dataField="price0" width="75"/>
		<mx:DataGridColumn headerText="Feb 2010" dataField="price1" width="75" />
		<mx:DataGridColumn headerText="Mar 2010" dataField="price2" width="75" />
		<mx:DataGridColumn headerText="Apr 2010" dataField="price3" width="75" />
		<mx:DataGridColumn headerText="May 2010" dataField="price4" width="75" />
		<mx:DataGridColumn headerText="June 2010" dataField="price5" width="75" />
	</mx:columns>
</mx:DataGrid>
</mx:Application>

Obvious problems

  1. Hard coded columns representing months of the year. This obviously doesn’t cut it if we wanted to display an arbitrary time range
  2. Our data provider is not yet strongly typed and has fixed properties for data in columns (price0, price1, price2 etc).

Notes: please note that the exact problem applies to standard DataGrid as well as AdvancedDataGrid.

Solution – Hard coded columns to dynamic columns.

Before we attempt to fix hard coded column definitions lets fix 1 tiny thing first. Since we are displaying an arbitrary number of columns we might not even have the labels for those headers, let’s create the grid dynamically in ActionScript instead.

Add event to Application

<mx:Application creationComplete="creationCompleteHandler(event)"
private function creationCompleteHandler(event:FlexEvent) : void
{
	var columns:Array = new Array();

	columns.push(getColumn("product", "Product"));
	columns.push(getColumn("price0", "Jan 2010"));
	columns.push(getColumn("price1", "Feb 2010"));
	columns.push(getColumn("price2", "Mar 2010"));
	columns.push(getColumn("price3", "Apr 2010"));
	columns.push(getColumn("price4", "June 2010"));

	var grid:DataGrid = new DataGrid();
	grid.columns = columns;
	grid.width = 400;
	grid.lockedColumnCount = 1;
	grid.horizontalScrollPolicy = ScrollPolicy.ON;

	grid.dataProvider = rows;

	//add grid to application, this can be wherever you want,
	// maybe some Box or Canvas placeholder
	this.addChild(grid);
}

/**
 * Helper method to get column
 */
private function getColumn(dataField:String, headerText:String) : DataGridColumn
{
	var column:DataGridColumn = new DataGridColumn(dataField);
	column.headerText = headerText;
	return column;
}

Now that we have this grid in ActionScript code we should be able to see something obvious: why not just put the column creation in a loop? Exactly.

In this example the Product column is something concrete so we’ll keep it fixed (lockedColumnCount=”1″) and focus on dynamic time periods.

var columns:Array = new Array();

columns.push(getColumn("product", "Product"));

// Add as many time periods as we want here (we will make this dynamic later)
var timePeriods:Array = ["Jan 2010", "Feb 2010", "Mar 2010",
							"Apr 2010", "June 2010"];

for(var i:int = 0; i < timePeriods.length; i++)
{
	columns.push(getColumn("price" + i, timePeriods[i]));
}

We have now essentially separated the column creation to be driven by some Array of time periods, everything else should take care of itself provided that our data provider has the necessary data, i.e. that it has enough “priceX” properties, price0 to priceN where N is number of columns.


View complete code

In part 2 we will discuss what is perhaps the hard part of this solution, dynamic strongly typed object properties

Part 2 Dynamic dataProvider properties

Subscribe to Comments

2 Responses to “Creating an Enterprise Flex Grid – Dynamic Columns (Part 1)”

  1. [...] Part 1 – Dynamic DataGrid Columns of this Creating an enterprise Flex Grid series we quickly set up a ActionScript based grid that [...]

     
  2. Terrific work! This is the type of information that should be shared around the web. Shame on the search engines for not positioning this post higher!

     

    cna training

Leave a Reply

Message: