Check out my blog entry I just posted on this topic (I already had the
code sample lying around and hadn't gotten around to posting it),

 

http://blog.739saintlouis.com/2007/12/12/datagrid-popup-as-itemeditor/

 

HTH

 

-Kyle

 

________________________________

From: flexcoders@yahoogroups.com [mailto:[EMAIL PROTECTED] On
Behalf Of Alex Harui
Sent: Tuesday, December 11, 2007 9:37 PM
To: flexcoders@yahoogroups.com
Subject: RE: [flexcoders] Re: Use a Popup as itemEditor in Datagrids

 

I might have time to look at this over the weekend.

 

________________________________

From: flexcoders@yahoogroups.com [mailto:[EMAIL PROTECTED] On
Behalf Of mcaplan_labnet
Sent: Tuesday, December 11, 2007 6:47 PM
To: flexcoders@yahoogroups.com
Subject: [flexcoders] Re: Use a Popup as itemEditor in Datagrids

 

I seem to keep on banging my head against a wall on this issue. I've
been plugging away at this issue for several days now with little
progress.

I set the popup.owner property as recommended by Alex. This seemed to
have helped, but issues still persist. 

I "cheated" and created an inPopup flag in the parent document to try
and thwart popup loops (see code snips below). I say cheated, because
I gathered from Alex's suggestion that I should not need to do that. 

Regardless, that hack worked marginally well, but I'm having
additional issue, and I know it is because I am just not getting it. 
My hunch is that these additional issues are side effects to my
improper implementation of the popup in the itemEditor.

These "side effect" issues I am seeing include:

- My itemRenderer is not being reliably updated. To be clear, the
data from the itemEditor is being properly trapped, and the
dataProvider updated. The itemRender is not being updated because it
appears that the dataChange event on the itemRenderer is not being
dispatched -- at least not reliably. It is being dispatched and the
itemRenderer updated when I edit a different column in the datagrid. 

- If I click outside of my modal popup, focus is lost on the current
itemEditor cell resulting in the first row itemEditor being executed
immediately following the close of my initial popup. I've _covered_
my popup with focusEnabled = false statements which work great in the
popup. But outside popup clicks messes the focus.

For my first flex project, I've bitten off much more than I can chew
here. :) I've gone through the Flex 3 docs, flexcoders, and google
end-to-end, and I'm just not seeing a solution.

Any kind gurus out there that can offer some guidance? I've included
code snippets for all the components below.

Thanks!

Mike

<?xml version="1.0" encoding="utf-8"?>
<!-- modules.Case -->
<comp:ModuleTitleWindow xmlns:mx="http://www.adobe.com/2006/mxml
<http://www.adobe.com/2006/mxml> "
layout="absolute" xmlns:comp="components.*" initialize="init();"
verticalScrollPolicy="off" horizontalScrollPolicy="off" title="Case
{caseNumber}" showCloseButton="true" close="closePopUp();"
borderAlpha="1" width="100%" height="100%"
implements="modules.Case.ICase">
<mx:Script>
<![CDATA[
import mx.events.DataGridEventReason;
import mx.events.DataGridEvent;

/**
* Flag for modules.Case.TeethEditor to ensure there is no
popup loop
*/
public var inPopup:Boolean = false;

/**
* procedures datagrid itemEditEnd event handler
*/
private function procedureUpdate(event:DataGridEvent):void
{
if (event.reason == DataGridEventReason.CANCELLED) {
return;
}

switch (event.dataField) {
case "macro_id" :
// Disable copying data back to the control.
event.preventDefault();

// Get new city from editor.
procedures.selectedItem.description =
MacroIdEditor(DataGrid(event.target).itemEditorInstance).selectedItem.de
scription;

// Close the cell editor.
procedures.destroyItemEditor();

// Notify the list control to update its display.

procedures.dataProvider.itemUpdated(event.itemRenderer.data);
break;

case "teeth" :
// Disable copying data back to the control.
event.preventDefault();

if (!inPopup) { // Check to see that the popup
is not active

// Get new city from editor.
procedures.selectedItem.teeth =
TeethEditor(DataGrid(event.target).itemEditorInstance).teeth;

// Notify the list control to update its
display.

procedures.dataProvider.itemUpdated(event.itemRenderer.data);

// Close the cell editor.
procedures.destroyItemEditor();
}
break;
}
}

]]>
</mx:Script>

<mx:DataGrid id="procedures" editable="true"
itemEditEnd="procedureUpdate(event);">
<mx:dataProvider>
<mx:ArrayCollection>
<mx:source>
<mx:Object macro_id="D2456" teeth="11" />
<mx:Object macro_id="D2445" teeth="12,13" />
<mx:Object macro_id="D2658" teeth="21,22" />
</mx:source>
</mx:ArrayCollection>
</mx:dataProvider>
<mx:columns>
<mx:DataGridColumn dataField="macro_id" editable="true"
itemEditor="modules.Case.MacroIdEditor" />
<mx:DataGridColumn dataField="teeth" editable="true"
itemEditor="modules.Case.TeethEditor" editorDataField="teeth"
itemRenderer="modules.Case.TeethRenderer" />
</mx:columns>
</mx:DataGrid>

</comp:ModuleTitleWindow>

<?xml version="1.0" encoding="utf-8"?>
<!-- modules.Case.TeethEditor -->
<mx:TextInput xmlns:mx="http://www.adobe.com/2006/mxml
<http://www.adobe.com/2006/mxml> "
creationComplete="_init()" text="{_converted}" editable="false">
<mx:Script>
<![CDATA[
import modules.Case;
import mx.managers.PopUpManager;
import modules.Case.TeethSelector;
import mx.events.FlexEvent;
import mx.utils.StringUtil;

/**
* Teeth selected
*/
[Bindable]
public function get teeth():String
{
return _teeth;
}
public function set teeth(value:String):void
{
_teeth = value;
data.teeth = _teeth;
}
private var _teeth:String;

/**
* text to display in textarea 
* @ private
*/
[Bindable]
private var _converted:String;

/**
* Tooth selector popup instance
*/
private var _popup:TeethSelector;

/**
* Reference to the parent document which contains the datagrid
*/
private var _c:Case;


/**
* creationComplete event handler
*/
private function _init():void
{
teeth = data.teeth;

addEventListener(FlexEvent.DATA_CHANGE, _dataChanged);

_updateText(data.teeth);

_c = parentDocument as Case;

// Only show the popup teeth selector 
// if the popup isn't already displayed
if (!_c.inPopup) {
_c.inPopup = true;
_popTeethSelector();
}
}

/**
* Display popup teeth selector
*/
private function _popTeethSelector():void
{
_popup = new TeethSelector();
_popup.teeth = teeth;

// handle popup updated event
_popup.addEventListener("updated", _updateTeeth);

// handle popup closing event
_popup.addEventListener("closing", _closePopup);

_popup.focusEnabled = false;
PopUpManager.addPopUp(_popup,
_c.procedures.editedItemRenderer as DisplayObject, true);

// popup owner is the current datagrid item renderer
_popup.owner = _c.procedures.editedItemRenderer as
DisplayObjectContainer; 
PopUpManager.centerPopUp(_popup);
}

/**
* Handle the updated event of the popup teeth 
* selector by grabbing the newly selected teeth and
* and removing the popup
*/
private function _updateTeeth(e:Event):void
{
teeth = _popup.teeth;
_c.inPopup = false;
_updateText(teeth);
PopUpManager.removePopUp(_popup);
}

/**
* Handle the closing event of the poup teeth
* selector by closing the popup
*/
private function _closePopup(e:Event):void
{
_c.inPopup = false;
PopUpManager.removePopUp(_popup);
}

/**
* Update the displayed textarea text 
*/
private function _updateText(teeth:String):void
{
// updates _converted ...
}

/**
* dataChanged event handler - this updates the displayed
* textarea text
*/
private function _dataChanged(e:Event):void
{
teeth = data.teeth;
_updateText(data.teeth);
}

]]>
</mx:Script> 
</mx:TextInput>

<?xml version="1.0" encoding="utf-8"?>
<!-- modules.Case.TeethSelector -->
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml
<http://www.adobe.com/2006/mxml> " title="Tooth
Selector" creationComplete="_init()" showCloseButton="true"
close="this.dispatchEvent( new Event('closing') );"
focusEnabled="false">

<mx:Metadata>
[Event("updated")]
</mx:Metadata>
<mx:Metadata>
[Event("closing")]
</mx:Metadata>
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import mx.controls.CheckBox;
import mx.utils.StringUtil;

public var teeth:String;

/**
* creationComplete event handler
*/
private function _init():void
{
// set selected teeth
}

/**
* Save function. Updates the teeth variable
* and dispatches the updated event 
*/
private function _done():void
{
teeth = // ....

this.dispatchEvent( new Event("updated") );
}
]]>
</mx:Script>

<mx:Canvas>
<mx:CheckBox x="28.2" y="111" id="t28" styleName="t28"
focusEnabled="false"/>
<mx:CheckBox x="152.2" y="141.3" id="t48" styleName="t48"
focusEnabled="false"/>
<!-- ... -->
</mx:Canvas>
</mx:TitleWindow>

<?xml version="1.0" encoding="utf-8"?>
<!-- modules.Case.TeethRenderer -->
<mx:Label xmlns:mx="http://www.adobe.com/2006/mxml
<http://www.adobe.com/2006/mxml> " width="100%"
creationComplete="_init()" text="{_converted}">
<mx:Script>
<![CDATA[
import mx.utils.StringUtil;
import mx.events.FlexEvent;

/**
* label text
*/
[Bindable]
private var _converted:String;

/**
* creationComplete event handler
*/
private function _init():void
{
_updateText();
addEventListener(FlexEvent.DATA_CHANGE, _dataChanged);
}

/**
* update label displayed text
*/
private function _updateText():void
{
// update _converted var here ...
}

/**
* dataChanged event handler. Updates the label text
*/
private function _dataChanged(e:Event):void
{
_updateText();
}
]]>
</mx:Script>
</mx:Label>

 

Reply via email to