Flex DataGrid Add New row via single click event

apache-flexdatagrid

I am trying to implement the following functionality:

Flex data grid has 1 default row created. When user clicks on the second row, a new row needs to be created and made editable.

Here is what works already – user tabs over the columns and when the user tabs while in the last column, a new row is created with default values.

Here is also what already works – user click a button outside the grid, which adds a new row.

(itemEditBegin and itemEditEnd have been implemented)

Here is what does NOT work: When I "single click" on the second row (no data yet – row is null), how do I detect that the currently clicked row is the second row and make it editable? Can I figure out the rowIndex from MouseEvent and use this to add a new row?

Find code below:

<mx:DataGrid id="myGrid" editable="true" click="clickEvent(event)"
     itemEditEnd="endEdit(event)" itemEditBegin="beginEdit(event)" variableRowHeight="true" >

private function clickEvent(ev:Event):void
{
    var i:Object = MouseEvent(ev).currentTarget;
        // is this the right event?
}

Best Answer

If there is no data, there won't be any row or itemRenderer and hence technically there is no row index. The e.target would contain the ListBaseContentHolder and e.currentTarget would contain the DataGrid itself. However you can use the mouse-y position to calculate what row would have been present at the clicked location. Here is a dirty little trick to do it - it's not thoroughly tested and hence might fail for edge cases.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
    xmlns:local="*" creationComplete="create();">
    <mx:DataGrid id="myGrid" editable="true" click="clickEvent(event)"
     variableRowHeight="true" >
    <mx:columns>
        <mx:DataGridColumn dataField="d"/>
        <mx:DataGridColumn/>
    </mx:columns>
    </mx:DataGrid>
    <mx:Script>
        <![CDATA[
            import mx.controls.listClasses.ListRowInfo;
            import mx.controls.listClasses.ListBaseContentHolder;
            private function clickEvent(e:MouseEvent):void
            {
                if(!(e.target is ListBaseContentHolder))
                    return;
                var holder:ListBaseContentHolder = 
                    ListBaseContentHolder(e.target);
                var rowIndex:Number = -1;
                var length:Number = holder.rowInfo.length;
                var rowInfo:ListRowInfo;
                for(var i:Number = 0; i < length; i++)
                {
                    rowInfo = holder.rowInfo[i];
                    if(e.localY > rowInfo.y && 
                        e.localY < rowInfo.y + rowInfo.height)
                    {
                        rowIndex = i;
                        break; 
                    }
                }
                trace("Clicked on " + rowIndex);
            }
            private function create():void
            {
                myGrid.dataProvider = [{d:"A"},{d:"B"}];
            }
        ]]>
    </mx:Script>
</mx:Application>
Related Topic