20070530

Enabling both HTTP and HTTPS access to your Flex Application

To enable both HTTP and HTTPS access to you Flex app, you need to do the following:


1. Open remoting-config.xml (can be located at /WEB-INF/flex)

2. Look for <default-channels>

3. Add reference to the secure channel
<default-channels>
<channel ref="my-amf"/>
<channel ref="my-secure-amf"/>
</default-channels
>


4. Define "my-secure-amf" in "services-config.xml" if not aleady defined.
<channel-definition id="my-secure-amf" class="mx.messaging.channels.SecureAMFChannel">
<endpoint uri="https://{server.name}:{server.port}/{context.root}/messagebroker/amfsecure" class="flex.messaging.endpoints.SecureAMFEndpoint"/>
</channel-definition>





20070524

Single ItemRenderer for Multiple Columns in a DataGrid

Many a times we have similar columns in a datagrid and are required to be rendered in a similar manner with only little variations like formatting of the column. It is redundant in such a case to write a separate ItemRenderer per column. A better approach would be to write single ItemRenderer and pass properties to the ItemRenderer to identify a particular column.


This can be achieved by settings the ItemRenderer to column using Actionscript.
The catch is to pass properties to ItemRenderer using ClassFactory.properties method.

http://livedocs.adobe.com/flex/2/langref/mx/core/ClassFactory.html

Here's the sample code:



var colRendererFactory:ClassFactory = new ClassFactory(columnRendererClass);
colRendererFactory.properties = {columnName:"mycol1"};
column1.itemRenderer = colRendererFactory

var colRendererFactory2:ClassFactory = new ClassFactory(columnRendererClass);
colRendererFactory2.properties = {columnName:"mycol2"};
column2.itemRenderer = colRendererFactory2;


This way you can have the same itemrenderer for multiple columns and can do different styling for each column based on the properties passed.

20070523

Adding Total Row at the end of DataGrid

Algo: Add to Technorati Favorites
====

1. Create two datagrids and put both in a VBox. Set the 'verticalGap' of the VBox to zero.
2. First datagrid contains all the rows while the second one contains only the total row.
3. Second datagrid has
a) showHeaders = false
b) rowCount = 1
4. Dataprovider of the First datagrid is the arraycollection containing the Objects/data representing various rows
5. Dataprovider of the Second datagrid is the arraycollection containing ONLY one item which contains the total dataobject.

e.g.
The code would be something like :


Click here for demo
Click here for the source code

Approach 2
Another approach has been mentioned at:
http://blogs.adobe.com/aharui/2007/04/datagrid_footers.html

But the above implementation doesn't take care of resizing columns. In order to add that support:
1. add following function to FooterDataGrid
public function recreateBorder() : void
{
removeChild(DisplayObject(border));
border = null;
createBorder();
}


2. call this function on the "columnStretch" event i.e.

columnStretch="{dg1.recreateBorder()}" >


Click here to see the demo.

20070515

Exporting Datagrid data to excel

Add to Technorati Favorites
This is a updated version of http://www.cflex.net/showFileDetails.cfm?ObjectID=298&Object=File&ChannelID=1

Algo:
===
1. Convert the datagrid data to csv string
2. Post data to a servlet
3. Servlet returns the same csv string back with content -type of the HTTPResponse set to "application/ms-excel"


1. Convert the datagrid data to csv string
This is a generic version and should work with any datagrid.

public class DataGridCSVTransformer
{
private static var csvSeparator : String = "\t";
private static var lineSeparator = "\n";

public static function toCSV(dg : DataGrid) : String
{
var str : String = "";
for(var i : int = 0; i <>
{
var dgc : DataGridColumn = dg.columns[i];
if(!dgc.visible)
continue;
str += "\""+dgc.headerText+"\"";
if(i < (dg.columnCount -1))
str += csvSeparator;
}
str += "\r\n";
var rowCount : int = dg.dataProvider.length;

for(var j:int = 0; j <>
{
for(var k : int = 0; k <>
{
var dgc : DataGridColumn = dg.columns[k];
if(!dgc.visible)
continue;
var obj : Object = null;
if(dg.dataProvider is ArrayCollection)
obj = (dg.dataProvider as ArrayCollection).getItemAt(j);
else
obj = (dg.dataProvider as Array)[j];

str += "\""+dgc.itemToLabel(obj)+"\"";
if(k < (dg.columnCount -1))
str += csvSeparator;
}
if(j < (rowCount - 1))
str += lineSeparator;
}

Alert.show("String :: "+str);
return str;
}
}

2. Post the CSV data to servlet
private function doPost(event:Event) : void
{
var csvConverter :
DataGridCSVTransformer = new DataGridCSVTransformer();
var dgCSV : String =
csvConverter.toCSV(dg);
var url : String = "http://localhost:8080/flextest/reports/genreport";
var urlr : URLRequest = new URLRequest(url);
urlr.method = "POST";
var urlv : URLVariables = new URLVariables();
urlv.reportdata =
dgCSV;
urlr.data = urlv;
navigateToURL(urlr,"_blank");
}

3. Servlet returns the same csv string back with content -type of the HTTPResponse set to "application/ms-excel"

public void generateReport(HTTPServletRequest req, HTTPServletResponse res)
throws ServletException, IOException
{
String csvData = req.getParameter("reportData");
res.setContentType("application/ms-excel");
res.getOutputStream().print(csvData);
}