tags:

views:

2617

answers:

2

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?
}
A: 

Great question, DataGrid supports selection of objects in the DataGrid's dataProvider. But it does not allow easy selection/mouseOver of rows which do not have items in them (null rows).

1) I would either put a dummy row at the end of the DataGrid, so that way it can be easily selected by the DataGrid.
2) Otherwise, I would check to see if mouseX/mouseY are within the parameters of the null-row you just clicked on (using the null-row's global X,Y,width,height properties).

Let me know what works.

Luis B
+1  A: 

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>
Amarghosh
works well. Thanx buddy
crazy horse
I just found that when one of the columns of the grid contains a custom combobox, and you click on a 'non-empty' grid row on the combobox area, e.target is still of type ListBaseContentHolder (and not of type itemrenderer). So the below check for target type alone is not sufficient:if(!(e.target is ListBaseContentHolder)) return;The way I worked around it is to track using Boolean if the grid has data or not.If there is a better way of doing it, let us all know!
crazy horse