In Flex one of the most used and useful components is the DataGrid, and it happens to be the component we get the most questions on. This tutorial's sole purpose is to show off some of the cool things that can be done with the Flex Datagrid and to answer a few of the questions that we have outstanding. Some of the topics covered in this tutorial include changing the row color, header colors, header renderers, using dynamic xml data and others.
You can check out the example below to see some of the things that are handled in this tutorial. As you can see we have a simple datagrid with 3 columns. The columns can be sorted, resized, and moved like normal. The first column Title has a header that starts off red and flips to blue when clicked, and the contents of the first column have external link buttons to send you off to the site relevant to that row. The second column has a header that changes color when hovered. And one of the most noticeable attributes is the row color for some of the pieces of data, the row color for these is determined by whether the item has been read - a property in the data. Now take a second and mess around with the example or grab the source code.
The XML Data
First things first let's take a look at the data that we will be using for this application. The data is held in a small xml file that is on our server. It holds a list of books and data about them. Our Flex application will pull this data every time the application loads so we could update this data on the server and the next time our application would load new data would be there.
Shown below are the contents of the xml file. As you can see each book has a title, author, url, isbn 10, and read variable. The isbn 10 number is an attribute and will have to be pulled from the data slightly different from the rest of the variables. The read variable is what we are going to use to color the rows and signifies whether I have read the book or not.
<books>
<book isbn_10="1594482918">
<title>The Adventures of Johnny Bunko</title>
<author>Daniel H. Pink</author>
<url><![CDATA[http://www.amazon.com/Adventures-Johnny-Bunko-Career-Guide/dp/1594482918/ref=pd_bbs_1?ie=UTF8&s=books&qid=1216932295&sr=8-1]]></url>
<read>true</read>
</book>
<book isbn_10="0930289234">
<title>Watchmen</title>
<author>Alan Moore, Dave Gibbons</author>
<url><![CDATA[http://www.amazon.com/Watchmen-Alan-Moore/dp/0930289234/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1216932775&sr=1-1]]></url>
<read>false</read>
</book>
<book isbn_10="159184021X">
<title>Purple Cow: Transform Your Business by Being Remarkable</title>
<author>Seth Godin</author>
<url><![CDATA[http://www.amazon.com/Purple-Cow-Transform-Business-Remarkable/dp/159184021X/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1216932833&sr=1-1]]></url>
<read>true</read>
</book>
<book isbn_10="1847194443">
<title>Learning Drupal 6 Module Development</title>
<author>Matt Butcher</author>
<url><![CDATA[http://www.amazon.com/Learning-Drupal-6-Module-Development/dp/1847194443/ref=pd_bbs_sr_3?ie=UTF8&s=books&qid=1216933022&sr=1-3]]></url>
<read>true</read>
</book>
<book isbn_10="0672328917">
<title>Windows Presentation Foundation Unleashed</title>
<author>Adam Nathan</author>
<url><![CDATA[http://www.amazon.com/Windows-Presentation-Foundation-Unleashed-WPF/dp/0672328917/ref=pd_bbs_sr_2?ie=UTF8&s=books&qid=1216933086&sr=1-2]]></url>
<read>false</read>
</book>
</books>
Custom Row Colors
The first item for building the demo application is creating the user interface for it. This is going to be as simple as it gets. We are going to add a DataGrid and a few columns to our application. The columns are for the Title, Author, and ISBN number of the book. The start of our demo application follows.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:local="*" layout="absolute" width="500" height="200">
<mx:DataGrid id="booksGrid" width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn dataField="title" headerText="Title"/>
<mx:DataGridColumn dataField="author" headerText="Author"/>
<mx:DataGridColumn headerText="ISBN 10"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
To get things moving we are going to create a custom component that extends DataGrid to handle changing the row color. I am going to be using a modified method created by (or at least that is where I saw it) Peter Ent. The method uses the protected function, drawRowBackground, in the DataGrid class. Which is the function that handles drawing the row backgrounds, of course. To start with we create the component, in my case named RowColorDataGrid.
{
import flash.display.Sprite;
import mx.collections.ArrayCollection;
import mx.controls.DataGrid;
public class RowColorDataGrid extends DataGrid
{
public var rowColorFunction:Function;
override protected function drawRowBackground(s:Sprite,
rowIndex:int, y:Number, height:Number, color:uint, dataIndex:int):void
{
super.drawRowBackground(s, rowIndex, y, height, color, dataIndex);
}
}
}
In order to make changing the row color easy we are going to use a pattern that is used throughout the Flex framework, a callback function to determine the row color - similar to a labelFunction. You can see the public variable, of type Function, in the class declaration above called rowColorFunction. The function will have a few parameters passed and returns the color of the background. We need to add a little more code to our overridden function to use the rowColorFunction to determine the wanted color. Here is the function and I will explain the additions right after.
rowIndex:int, y:Number, height:Number, color:uint, dataIndex:int):void
{
if(rowColorFunction != null && dataProvider != null)
{
var item:Object;
if(dataIndex < dataProvider.length)
{
item = dataProvider[dataIndex];
}
if(item)
{
color = rowColorFunction(item, rowIndex, dataIndex, color);
}
}
super.drawRowBackground(s, rowIndex, y, height, color, dataIndex);
}
First thing in the function we check to make sure the rowColorFunction is set, otherwise we default to the original implementation by the DataGrid class. If one is set we grab the item for the row that is being drawn from the dataProvider. I modified this from Peter Ent's method to handle all the types the dataProvider can be. After grabbing the item I check to make sure it isn't null and call the row color function. The rest is handled by the drawRowBackground call.
Now we need to update the application to use our custom component. Below we have the updated grid code.
width="100%" height="100%" rowColorFunction="calcRowColor">
<local:columns>
<mx:DataGridColumn dataField="title" headerText="Title"/>
<mx:DataGridColumn dataField="author" headerText="Author" width="125" />
<mx:DataGridColumn headerText="ISBN 10" width="90"/>
</local:columns>
</local:RowColorDataGrid>
You can notice I have the rowColorFunction property set and also have set the dataProvider property. A Script tag is added and we add the function and an XMLListCollection for the holding our data.
<![CDATA[
import mx.collections.XMLListCollection;
[Bindable]
private var books:XMLListCollection;
private function calcRowColor(item:Object, rowIndex:int,
dataIndex:int, color:uint):uint
{
if(item.read == true)
return 0x49FFAD;
else
return color;
}
]]>
</mx:Script>
Our function, calcRowColor, simply checks if the item passed in has the read property set equal to true. If the read property is not true, the function simply returns the default background color. There are endless possibilities of what can be done with this so go and have fun.
Getting XML Data with HTTPService
This is going to be one of the easiest features we are going to add to the application today. Foremost, we are going to add a HTTPService to our application. We are going to set a few attributes on the tag. These include the id, url, result, and resultFormat. The url is pointed the books xml file from earlier in the post. The resultFormat is set to e4x to make handling the xml data all nice and easy. Following we have the added tag.
resultFormat="e4x" url="/files/Tutorials/Flex/DatagridOptionsOne/books.xml" />
Now we have something to use to get our data we actually need to handle the result and send for it. To do this we are going to hook into the creationComplete event on the main tag in our application. You can also see above we have already hooked into the result event of the HTTPService tag. This means we just need to implement the function. But first we have our updated Application tag.
layout="absolute" width="500" height="200" creationComplete="init()">
Furthermore, we have the two function for sending to get the xml data and the handleData function to process the result.
{
booksService.send();
}
private function handleData(event:ResultEvent):void
{
books = new XMLListCollection();
books.source = event.result.book;
}
Both of those functions above are pretty self-explanatory but I will give a quick rundown. First the send function on the http service object will send the request. The processing done is simple, we create a new collection to hold our books then pull out the book list from the result.
DataGrid Item Presentation
Up to this point you should be able to run the application and see the datagrid showing some data with a couple rows that have a greenish background marking they have been read. To add to the mix we have one column that needs a label function to display the data correctly. This is the ISBN column because the ISBN 10 number is passed as an xml attribute which can pulled out using the e4x "@" syntax. We update our column definition to set the labelFunction property and then add the label function to our actionscript.
The label function.
{
return item.@isbn_10;
}
That should make the ISBN 10 number show up in the grid correctly. The next task is to build a item renderer for the title so we can add a link to the actual amazon page of the book. It will use the url property passed through with the book data in the xml. Before starting on the actual renderer I am going to show a helper component that I built to link to external sites. The component extends the LinkButton class. So without further ado.
{
import flash.events.MouseEvent;
import flash.net.URLRequest;
import flash.net.navigateToURL;
import mx.controls.LinkButton;
public class ExternalLinkButton extends LinkButton
{
public var url:String = "";
public function ExternalLinkButton()
{
super();
addEventListener(MouseEvent.CLICK, followLink);
}
private function followLink(event:MouseEvent):void
{
if(url == "")
return;
var urlReq:URLRequest = new URLRequest(url);
navigateToURL(urlReq);
}
}
}
It is very understandable code so I am not going to go over it - feel free to ask any questions on it in the comments though. Next we are going to build the title item renderer, which is almost as easy so I am going to throw it out there and then go over the code.
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*" width="100%"
height="100%" horizontalScrollPolicy="off" horizontalGap="0">
<mx:Label text="{data.title}"/>
<local:ExternalLinkButton icon="@Embed('/assets/link.gif')"
url="{data.url}" width="22" height="100%" textAlign="left"/>
</mx:HBox>
As you can see in the code above we have a label which has the text set to the title of the book and a ExternalLinkButton. The button has an icon set and the url set to the Amazon page, along with a couple other properties. All this is put in a HBox to make layout easy. I would like to note that you could have easy set the label on the link button to the title and simply had a big link. I choose the icon route to make it easy to select a row of the data which being sent to Amazon. This pretty much takes care of showing the data in the grid.
Customizing the DataGridColumn Headers
The final couple pieces of this tutorial are going to deal with the column headers and how we can customize them a little. First we are going to hook into one of the events, headerRelease, of the DataGrid class and in our case the custom component we built. This event is fired after the one of the headers is clicked on. We are going to use this to update the style of the header clicked on. This gives the final iteration of our RowColorDataGrid tag.
height="100%" headerRelease="{headerColor(event)}" rowColorFunction="calcRowColor">
We now add the headerColor function to our script which will look like the following.
{
if(event.columnIndex != 0)
return;
var col:DataGridColumn = booksGrid.columns[event.columnIndex];
var headerStyle:String = col.getStyle("headerStyleName");
if(headerStyle != "headerBlue")
col.setStyle("headerStyleName", "headerBlue");
else
col.setStyle("headerStyleName", "headerRed");
}
In the above function we start off by checking to see if the column we are in is the title column (index 0) and if not we return out of the function. Then we declare a local variable, col, for the column that we clicked on. We use this to get the current style name (headerStyleName) for the column header. Then we check to see if it is set to "headerBlue" and if it isn't we set it and otherwise set it to "headerRed". Both "headerBlue" and "headerRed" are style classes that we declare in a Style tag of our application. This style tag is below.
RowColorDataGrid { use-roll-over: false; }
ExternalLinkButton { roll-over-color: #FF5BBA ; }
.headerRed { color: #FF0000; }
.headerBlue { color: #0000FF; }
</mx:Style>
The final thing we are going to do to our data grid is use a custom header renderer for the author column. The single purpose of this header renderer is going to be update the text color when we hover over the header, as opposed to updating on click like the previous method. For the renderer we are going to build yet another component. This component named LabelHeader is based off of the Box component and has a single label in it with the text set to normal headerText property of the column. Check out the code below for the entire component definition.
<mx:Box xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%"
mouseOver="mouseOverHandler(event)" mouseOut="mouseOutHandler(event)">
<mx:Script>
<![CDATA[
private function mouseOverHandler(event:MouseEvent):void
{
headerLabel.setStyle("color", 0xFF0000);
}
private function mouseOutHandler(event:MouseEvent):void
{
headerLabel.setStyle("color", 0x000000);
}
]]>
</mx:Script>
<mx:Label id="headerLabel" width="100%" height="100%" text="{data.headerText}" />
</mx:Box>
We hook into two events, mouseOver and mouseOut. The handlers for these are simple as pi - they simply update the text color of the label. On the DataGridColumn tag we set the headerRenderer property to LabelHeader and voilà.
width="125" headerRenderer="LabelHeader" />
Just to satisfy the curious here is the entire main application file contents.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*"
layout="absolute" width="500" height="200" creationComplete="init()">
<mx:Style>
RowColorDataGrid { use-roll-over: false; }
ExternalLinkButton { roll-over-color: #FF5BBA ; }
.headerRed { color: #FF0000; }
.headerBlue { color: #0000FF; }
</mx:Style>
<mx:Script>
<![CDATA[
import mx.utils.ColorUtil;
import mx.controls.dataGridClasses.DataGridColumn;
import mx.rpc.events.ResultEvent;
import mx.collections.XMLListCollection;
import mx.events.DataGridEvent;
[Bindable]
private var books:XMLListCollection;
private function init():void
{
booksService.send();
}
private function handleData(event:ResultEvent):void
{
books = new XMLListCollection();
books.source = event.result.book;
}
private function headerColor(event:DataGridEvent):void
{
if(event.columnIndex != 0)
return;
var col:DataGridColumn = booksGrid.columns[event.columnIndex];
var headerStyle:String = col.getStyle("headerStyleName");
if(headerStyle != "headerBlue")
col.setStyle("headerStyleName", "headerBlue");
else
col.setStyle("headerStyleName", "headerRed");
}
private function getISBN(item:Object, col:DataGridColumn):String
{
return item.@isbn_10;
}
private function calcRowColor(item:Object, rowIndex:int,
dataIndex:int, color:uint):uint
{
if(item.read == true)
return 0x49FFAD;
else
return color;
}
]]>
</mx:Script>
<mx:HTTPService id="booksService" result="handleData(event)"
resultFormat="e4x" url="DatagridOptionsOne/books.xml" />
<local:RowColorDataGrid id="booksGrid" dataProvider="{books}" width="100%"
height="100%" headerRelease="{headerColor(event)}"
rowColorFunction="calcRowColor">
<local:columns>
<mx:DataGridColumn dataField="title" headerText="Title"
headerStyleName="headerRed" itemRenderer="BookTitleRenderer"/>
<mx:DataGridColumn dataField="author" headerText="Author"
width="125" headerRenderer="LabelHeader" />
<mx:DataGridColumn labelFunction="getISBN" headerText="ISBN 10" width="90"/>
</local:columns>
</local:RowColorDataGrid>
</mx:Application>
Well I think I answered a few questions people had about the datagrid. If anyone has any other questions feel free to email us or drop a comment. Hope everyone was able to take away something from this tutorial.
08/03/2008 - 04:00
Thankyou Fattest
For doing this work AND for sharing it afterwards.
You sertanly got my respect.
I have been loking for this solution almost one year.
Is it possible to do like a blue link in the datagrid?
Thankyou and Regards
John Nielsen
08/03/2008 - 05:24
Sorry about my ignorence.
Is there any easy way to use your sourcecode directly in flex3.
Thank you
08/03/2008 - 10:39
Doesnt work
Only half of the Sourcecode.
08/03/2008 - 11:03
The source code works and is complete.
To get a working project from the source code download it and extract it to somewhere. Start a new Flex Project in Flex Builder copy all the source code and assets folder into the source folder of the project (usually src folder). Then you need to update main.mxml to get the books.xml file from the correct place. This means updating the url in the HTTPService, you update this to where ever the xml file is being held (on a webserver). To make things simple and instantly work thought simply put http://www.switchonthecode.com/sites/default/files/226/source/books.xml in the url. Now this will only work on your local computer running from Flex Builder because of cross domain access issues.
Let me know if you have any other issues.
08/04/2008 - 08:28
I have a question about "books.source = event.result.book;"
Could I make this dynamic ? So that I can use for example "book1" and "book2" for different lists which I choose from a tree.
08/04/2008 - 13:38
sT, Yeah this can be dynamic. When you set the source for the just use the selected item from your tree as the list to pull out. So something like this.
myTree would then be the id of your tree object and the objects in the dataprovider for it would be strings. So if the selected item in the tree was "book1" the code above would equal out to be the following.
08/04/2008 - 14:19
Thank you, very very much. I tried to solve this problem for hours.
08/04/2008 - 13:03
Holy butt nuts, this is INCREDIBLY helpful.
Thank you soooo much for this. I hope to expand on this and push this furthur.
Alan
08/05/2008 - 07:40
Wooorking!
Very helpful and very nicely explained.
Thanks for your your patience. :)
Regards
John Nielsen
08/05/2008 - 08:14
Possible to change grid into a advanced datagrid?
08/06/2008 - 09:50
John, I would have to look at the AdvancedDataGrid source to give you an answer I haven't really played with the AdvancedDataGrid really.
08/08/2008 - 23:02
Fattest
Ok
Thankyou. :)
08/05/2008 - 08:15
thankyou :)
08/06/2008 - 04:51
Hi!
I need to set different color of row depending on data. I have made everything like in this example but the dataProvider variable don't exist. Can you please help me ?
08/06/2008 - 09:50
bash3r, what are you using to show your data? If it is a datagrid or any list the dataProvider will certainly exist.
08/15/2008 - 10:26
I could not find "BookTitleRenderer".
Is it possible to download the source code for this application.
08/15/2008 - 11:17
yeah BookTitleRenderer is a custom item renderer you have to create it. You can download the source by clicking on the source button at the bottom of the demo application or in the paragraph preceding it.
08/25/2008 - 10:44
is there any way to make the row font bold.
I am trying to do this for 2 days!
08/25/2008 - 11:17
are you talking about the selected row or just any row?
08/25/2008 - 16:48
the selected row.
09/08/2008 - 00:37
hello,
thanks for the post!
i have the same question that scuty: is there any way to make the row font bold?? ...when mouse is over?
thanks a lot
09/11/2008 - 10:24
Well pepe and scuty here you go, a tutorial just for you.
09/14/2008 - 09:13
First of all thank you very much all of this tutors that makes me feel like a flexer =)
I'm trying to make this ExternalLinkButton's face dynamic.
My target is; in a list of different types of files can be downloaded via clicking a button inside the datagrid which button 'face' shows the target file's type by embed xls_icon.gif, doc_icon.gif, pdf_icon.gif etc.
My xml source's tag like this;
http://.../file_name.ext
i guess with a substring function I can get the extension then use it into 's icon attribute.
But my methods not working.
1.
main.mxml:
{
return url.substr(url.length - 3 , 3);
}
renderer.mxlm:
I know it's a syntax problem but how can i use a function into a element attribute?
confused. sorry =)
09/14/2008 - 09:35
eggman, you can't dynamically embed assets. Embedding assets is all done at compile time. So in order to do what you want you have two options. You can embed all the assets you want to use into the application and then swap between them. Or you can dynamically produce the icon name/path and load them at runtime. Let me know if you would like to see an example of what I am talking about. This tutorial might give you some insight into what I am talking about.
09/14/2008 - 09:47
thanks for the answer! i will tell what i can =)
10/12/2008 - 16:55
I'm trying to implement the bit of the DataGridColumn.headerRenderer. However, I'm creating the datagrid and its columns dynamically in Actionscript. Whilst it is not problem to implement a header renderer by assigning the headerRenderer property in MXML, in Actionscript it just won't work, because the GridColumn.headerRenderer property is of type mx.core:IFactory. I probably just miss something simple here.
10/13/2008 - 13:56
Matthias you are very close there you are right about the IFactory you need to do something like.
Let me know if that doesn't take care of it.
10/13/2008 - 18:05
I arrived at this point and succeeded to add a renderer based on the mx.TextArea...
advCol.headerRenderer = new ClassFactory(GridHdrRenderer);
As such it works fine. For example I can control the text alignment. However, some style attributes I set are simply ignored: font weight, font size, color, etc.
Looks like as if some sort of style inheritence overwrites my settings.
Any idea?
10/17/2008 - 00:03
Hi very nice application..i have small doubt regarding HeaderRenderer,can we use HeaderRenderer to do headerWordwrap...if yes how can we?
Thanks in Advance!.
10/21/2008 - 00:14
Noo Idea!!
10/21/2008 - 07:17
Yugan, you might be able to do this but I would have to investigate on to what extent. I mean you can try to put a renderer that has a textarea in it with wrap enabled. You might have to work a little bit to get the header to be a large enough to show the wrapped header.
12/09/2008 - 02:56
Thank you for the sample, it made my work faster.
12/13/2008 - 12:39
Can you throw more light on style properties:
RowColorDataGrid { use-roll-over: false; }and
ExternalLinkButton { roll-over-color: #FF5BBA ; }?
Thanks,
Steve
03/10/2009 - 16:43
This is great but it has a flaw. What if I wanted the rows for all books that I read to green, books that I'm currently reading to be yellow, and books that I haven't read to red. For example sake, let's say the XML values for "" were:
<read>no</read>
<read>reading</read>
any insights?
04/03/2009 - 20:25
Thank you for taking the time to explain this so comprehensively. I'm basically a Flex 3 novice, and I'm teaching myself as much as possible. Your examples have helped tremendously. I did encounter a fascinating phenomenon, and I'm curious to get your input. Just for kicks, I removed the title from one of the records in my source (xml) file. I thought this might be a "challenge" for the datagrid, particularly since the TITLE field is the one being filtered by the FIRST column in the datagrid. I can't say it was entirely expected, but the app did "crash" as a direct result of passing the empty TITLE field from a record in the source file. When I re-entered a title between the tags in the source record, the issue was resolved. Interestingly, the issue did NOT arise when I removed the contents of either of the other two fields. Does this behavior seem reasonable? Have you ever heard of something like that?
Thanks and Regards,
Daniel Toma
04/06/2009 - 04:39
Hi,
When i compile the code it there is an error 'Definition BookTitleRenderer cant be found'.
Any idea what causes the error?
Thanks in advance :)
04/06/2009 - 12:41
Well it sounds like your didn't download or create the BookTitleRenderer component. It can be downloaded with the source.
04/19/2009 - 09:28
If you do not set dataProvider in RowColorDataGrid tag but in ActionScript code, then it can cause trouble because Flex tries to initialize and view grid and runs overrided drawRowBackground method which does not check for dataProvider being null and raises exception.
Solution:
if(rowColorFunction != null && dataProvider != null)
That is: add check for dataProvider not being null into RowColorDataGrid.as method drawRowBackground, if it is null just let normal (super) version of drawRowBackground be run.
Otherwise really great and helpful tutorial.
04/19/2009 - 21:29
I have updated the code in the post, and will update the source files within the next day or two.
04/21/2009 - 03:06
Thanks, took me some time to actually figure what was happening but after comparison with normal DataGrid component (which behaved ok with no dataProvider) I concluded it was not wanted behaviour and wanted to give back to those helping other developers.
Anyway I wonder how often it is that someone runs into this issue. I used to put some empty placeholder dataProvider into DataGrid tag, but I was told I should not do that and simply init it in ActionScript (as per MVC separation of roles) - since I often use complex dataProviders generated by calls to java backend.
04/21/2009 - 20:05
How would you get this to work dynamically? IE I want to set row 2's "read" property to false and have the datagrid row respond accordingly (background color change back to normal).
I've tried a few things to no avail, including validating/invalidating the data grid and call drawRowBackgrounds (via a public accessor I created) after the data is updated.
Thanks for the great post.
04/29/2009 - 23:37
Any idea on this one?
04/30/2009 - 02:19
actually, it looks like the issue was all on my side! no worries, thanks for the great tutorial :)
05/05/2009 - 14:18
Thanks for this really good tutorial. I needed to set the color(s) on selected grid rows and this works great! The only thing I need now is a way to override the blue color when a row is selected. The blue hides my carefully crafted color coding on the selected row. What I'd like is a way to set a darker shade of my chosen color on hover and select. Looking through the flex source I haven't found the right place to do this yet, any suggestions?
05/05/2009 - 14:51
The blue selected color is also an override function, we have tutorial on this.
05/05/2009 - 15:57
Thanks, I tried catching the change event and doing a setStyle for selectedColor. That works but overriding drawSelectionIndicator, which I hadn't found yet, is a cleaner approach.
05/05/2009 - 19:14
One more thing. I also did an override of drawHighlightIndicator so that I can dynamically control custom colors of the rollOver color as it moves from item to item. This way it doesn't clash with the selected color and conveys additional information.
Add Comment
[language] [/language]
Examples:
[javascript] [/javascript]
[actionscript] [/actionscript]
[csharp] [/csharp]
See here for supported languages.
Javascript must be enabled to submit anonymous comments - or you can login.