Wednesday, 18 August 2010

Datagrid with image and events

At my company I'm making an application that has many datagrids to manage information that comes from external XML files. Many are related to one another, and some of them are meant to choose online documents, that will be used by chosen users (also in datagrids). One of the requests was to be able to choose a document in the dataGrid and preview the document.


The first question was, what type of visual aid would there be for the user to see that "you can click here to preview the document"?


Since this is a Flash application, there was not much sense to use text aids, like a link in HTML, so I wanted to place an icon for the user to click.


The next question is: How do you place an image in a dataGrid cell?


Not a trivial one to answer, since the Adobe documentation is not very clear in some aspects, and is incomplete in most cases, and this is one of them.


You can change the cell rendering option using the cellRenderer class. But how do you do it?


After long research over the internet, most users and cases are documented in AS2 using the mx.core.UIComponent. In AS3 is the fl.core.UIComponent, but I stumbled in poor documentation.


So searching a bit further I discovered an example from Adobe itself, and it's in this webpage:
http://www.adobe.com/devnet/flash/quickstart/datagrid_pt3/


I tried to adapt this solution to my problem, and it looked promising, since it was in AS3, and it was exactly what I wanted. Guess what? No errors, but it didn't work either. I changed all variables, made the associations right, but some new classes, new MovieClips in the library... but nothing worked.


Adobe forums... nothing!


Finnaly, I found forum entry in Kirupa.com, and the user EssencLord, presented a simple solution to overcome this problem. His solution was exactly whath I was looking for.




1. Make a separate class and give it a name that will identify it has a cell renderer class. I called it MCCellRenderer, because it will use a MovieClip with an icon inside, to be displayed in the dataGrid:

package src{

import fl.controls.listClasses.CellRenderer;
import flash.utils.getDefinitionByName;

public class MCCellRenderer extends CellRenderer {
        public function MCCellRenderer():void {


               var instance = new (getDefinitionByName("eye")); // Create Instance of "eye"
               this.addChild(instance);    // Add this instance to the CellRenderer
               instance.name = "eye";    // Name this new instance
           
               // Position Movie in Cell
               instance.x += 18;
               instance.y += 10;
        }
}





2. Then in the main class, associate this class with the cell you want in the dataGrid:

var verCol:DataGridColumn = new DataGridColumn("Ver");
verCol.cellRenderer = MCCellRenderer;

If you want to associate a MouseEvent with that particular cell, you can do it like this:

1.Add an event listener do the datagrid:
MyDataGrid.addEventListener(MouseEvent.CLICK, onClickCell);


2. And here's and function that will detect which cell was clicked, and react accordingly:


function onClickEvent (E:Event){
// if a record is selected
if (eventGrid.selectedIndex != -1)
{
// Check if user clicked on the Info Icon CellRender of the selected Row
var Row = eventGrid.selectedIndex;
// get selected row
var Col = eventGrid.getColumnIndex("Ver");
// the column of cells with MCCellRenderer
if (E.target == eventGrid.getCellRendererAt(Row, Col))
MyFunction ();

}
}


Keep it simple

Friday, 13 August 2010

Function Call Back

This is very handy feature when programming in AS3.


Imagine that you make a AlertBox class, that when called, it makes a custom Alert message. Imagine then, that you can put 1, 2 or 3 buttons, according to the message type. 


If you want to reuse this class in several projects, it's a good idea to tell the different buttons what or where to return when it's pressed.


That's were the Function Call Back enters. After a couple of hours and some search in the web, I came up with a solution, which I want to share.


It's very simple.
First declare in your class a variable that will keep the function reference later on, like this:

private var callBack:Function;

Then when you instantiate the Class, one of the arguments, of the constructor or function, will keep the function name, like this:

createAlert(..., callback){
...
}

Finally inside the constructor or function, you have to attribute the argument to the variable you defined earlier, like this:

callBack=callback;

Then place this variable as a call of some event, like this:

button1.addEventListener(MouseEvent.CLICK, callBack);

... and that's it.


If you want to call the call back function with arguments, instead of a event, just call this way:


typeOfMessage=1;


callback(typeOfMessage);