pconn222
pconn222

Reputation: 11

Access to undefined property itemRenderer (Keyboard Event)

I am trying to get the following code to run when I hit enter on a row within a data grid, it works when I click on the row (ListEvent) but how would I enable this to work when the enter key is hit (KeyboardEvent). I have the enter key working although it throws this error every time

  private function onButtonClick(evt:KeyboardEvent):void
{
 var item:Object = evt.itemRenderer.data;
    openWorkflowItem(item.date.date, item.workFlowID);
    $multiEdit = false;

    if (target === currentWorkflowItems)
    {
        $histFilter['sym'] = item.sym;
        histSym.text = item.sym;
        applyHistFilters();
    }

}



<mx:AdvancedDataGrid
                    id="historicalWorkflowItems"
                    dataProvider="{$historicalWFItems}"
                    width="100%" height="100%"
                    itemClick="{onWFItemClick(event)}"
                    keyDown="if (event.keyCode==Keyboard.ENTER){ onButtonClick(event)}"
                    borderStyle="none"
                    sortExpertMode="true"
                    useHandCursor="true"
                    headerShift="{saveColumnSettings('historical', historicalWorkflowItems)}"
                    columnStretch="{saveColumnSettings('historical', historicalWorkflowItems)}"
                    horizontalScrollPolicy="auto"
                    verticalScrollPolicy="auto"
                    allowMultipleSelection="true"
                    >

Upvotes: 0

Views: 122

Answers (1)

Aaron Beall
Aaron Beall

Reputation: 52183

The problem is that you are assigning a key listener to the grid, so there's no specific item in this context. The keyDown event fires whenever a key is pressed with focus anywhere within the grid. You want something like itemKeyDown, but the grid does not seem to provide you with such an event.

This is why I asked you to check Event/target to see what value it holds. If an item renderer has focus and the user presses a key, your handler will fire and you can check if the event target is an item renderer, ex if(event.target is AdvancedDataGridItemRenderer). (The event currentTarget will always be the grid.) Now, I'm not super familiar with the implementation of AdvancedDataGrid item rendering, but it's likely that the event target will not itself be an item renderer, only a child of an item renderer (say a text field inside the item renderer). To check if the target is inside an item renderer is possible by walking the display tree and checking if a parent is an item renderer class:

function findItemRenderer(object:DisplayObject):AdvancedDataGridItemRenderer {
    var current:DisplayObject = object;
    while(current && !(current is AdvancedDataGrid)){
        if(current is AdvancedDataGridItemRenderer)
            return current as AdvancedDataGridItemRenderer;
        current = current.parent;
    }
    return null;
}

Now you can handle your event like this:

function gridKeyDown(e:KeyboardEvent):void {
    var item:AdvancedDataGridItemRenderer = findItemRenderer(e.target as DisplayObject);
    if(item){
        // do stuff with your item
    }
}

But this is getting kind of silly to search the display hierarchy like this. What you should do is just dispatch an event from inside your item renderer, so that the event target is always the item renderer itself. For example:

class MyItemRenderer extends AdvancedDataGridItemRenderer {
    public static const ITEM_ENTER:String = "itemEnter";
    public MyItemRenderer(){
        addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
    }
    private function keyDown(e:KeyboardEvent):void {
        if(e.keyCode == Keyboard.ENTER)
            dispatchEvent(new Event(ITEM_ENTER, true)); // bubbles=true
    }
}

Now you can handle this event:

myGrid.addEventListener(MyItemRenderer.ITEM_ENTER, itemEnter);

function itemEnter(e:Event):void {
    var item:MyItemRenderer = e.target as MyItemRenderer;
    // do stuff with your item
}

Upvotes: 0

Related Questions