Tuesday, June 23, 2009

Dynamic columns in datagrid in Adobe Flex

When we set the dataprovider property of the datagrid, it automatically renders the columns with the default values. For instance, the column title is set as the node name if the dataprovider is XMLListCollection. But we would like to have more control on each column so that we can set it's title, width, and other properties as per our need. For this, we need to create each column dynamically at the run time by taking a first record from the dataprovider. In my same project, as mentioned in the last post, I was using XML output from PHP module to bind with the datagrid. However, this XML is also very dynamic in nature that it has variable numbers of nodes with variable node name based on the parameters selected. Depending on the output, I would also require to set some of the columns as read only when the grid is rendered. The overall idea here is to get the first child node of the XML and generate the array of an Objects with the desired properties set. And then an array of DataGridColumn objects is created and set the property as in the Object created in the first step. Below is the code sample;

private function bindData():void
{
    myGrid.dataProvider = xmlListCollection;
    myGrid.columns = getColumns(getColumnDef(xmlListCollection));
}
        
//get the first item from the XML to define the columns
private function getColumnDef(xmlData:XMLListCollection):Array
{
    var arrColDef:Array = new Array();
    var node:XML = xmlData[0]//get the first node of the XMLListCollection
    var childNodes:XMLList = node.children()//get its child nodes as an XMLList
    var objColDef:Object;
            
    for each(var xmlColumn:XML in childNodes//loop over the XMLList
    {
        objColDef = new Object();
        objColDef.dataField = xmlColumn.localName();
                
        switch(objColDef.dataField)
        {
            case "name":
                objColDef.headerText = "Full Name";
                objColDef.width = 120;
                objColDef.editable = true;
                break;
                    
            case "address":
                objColDef.headerText = "Permanent Address";
                objColDef.width = 120;
                objColDef.editable = true;
                break;
                        
            case "hour":
                objColDef.headerText = "Hour";
                objColDef.width = 120;
                objColDef.editable = false;
                break;
                        
            case "min":
                objColDef.headerText = "Minute";
                objColDef.width = 120;
                objColDef.editable = false;
                break;
                
            default :
                objColDef.width = 120;
                objColDef.editable = true;
                break;
        }
                
        arrColDef.push(objColDef);
    }

    return arrColDef;                    
}

//Generate the actual datagrid columns
private function getColumns(colDef:Array):Array
{
    var dataGridColumn:DataGridColumn;
    var arrColumns:Array = new Array();
            
    for each (var objColDef:Object in colDef)
    {
        dataGridColumn = new DataGridColumn();
        dataGridColumn.dataField =  objColDef.dataField;
        dataGridColumn.headerText = objColDef.headerText;
        dataGridColumn.editable = objColDef.editable;
        dataGridColumn.width =  objColDef.width;
                
        arrColumns.push(dataGridColumn);                
    }
    
    return arrColumns;
}

1 comment:

Anonymous said...

Could you please make the running application with View Source available?
Thanks