Editable column's value not getting 'persisted' in AdvancedDataGrid - actionscript-3

I have an AdvancedDataGrid (whose dataProvider is a variable being bound from my main mxml file, not sure if this is relevant to my problem ). I'm setting one of the AdvancedDataGridColumn's editable property as true, and when I click on the cell in the UI, it is infact editable. But when I press enter/move to a different cell, the old value returns and the newly entered value is lost. Would anyone have any ideas why that's happening? Do I have to manually change the variable provided in the dataProvider?...I would think that would happen automatically right? I'd appreciate any help!
Thanks.

This traces out correct when I edit a field and press enter then click on the button to see trace output:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" applicationComplete="init()">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.HierarchicalData;
[Bindable]
private var companyHierarchy:HierarchicalData;
private var companyData:XML = <data>
<company name="Employees">
<department name="Unit 1">
<employee name="Dave" func="C# Developer"/>
<employee name="Bob" func="AS3 Developer"/>
<employee name="Clair" func="AS3 Architect"/>
</department>
<department name="Unit 2">
<employee name="John" func="ORACLE Developer"/>
<employee name="Sandra" func="HTML Developer"/>
</department>
</company>
</data>;
private function init():void
{
companyHierarchy = new HierarchicalData(companyData.company);
}
private function checkSetData():void
{
trace(companyData);
}
]]>
</fx:Script>
<mx:AdvancedDataGrid id="test" width="500" height="500" dataProvider="{companyHierarchy}"
displayItemsExpanded="true" editable="true" enabled="true">
<mx:columns>
<mx:AdvancedDataGridColumn dataField="#name"
headerText="Companies"/>
<mx:AdvancedDataGridColumn dataField="#func"
headerText="Function"/>
</mx:columns>
</mx:AdvancedDataGrid>
<s:Button x="205" y="508" label="Button" click="checkSetData()"/>
</s:Application>

Related

Binding is not happening on Object Property and text Input

I am trying bind an Object property value to a text field. (Well I have taken this as an example ... I have no.of form fields and to be bound by other values)
But when change its value on button click the text field is not getting updated?
Below is the example code,
<?xml version="1.0" encoding="utf-8"?>
<s:Application
minHeight="600"
minWidth="955"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Declarations>
</fx:Declarations>
<fx:Script>
<![CDATA[
[Bindable]
var currentFormItem:Object = new Object();
public function changeName():void
{
currentFormItem.name = "hello";
}
]]>
</fx:Script>
<s:HGroup>
<s:TextInput id="test"
text="{currentFormItem.name}"/>
<s:Button click="changeName()"/>
</s:HGroup>
Thanks
I got the solution for this. I can just wrap this object in ObjectProxy.

FLEX DataGrid Column Modification

I am new in Flex. I want to display data in attached grid format. I found best way to display in DataGrid. But the CIs column has multiple entries so because of that other columns will duplicate. I want to avoid duplicate data in other columns. Attached screenshot is of excel, i want to achieve same format in Flex. I am using Flex 4.5
Best way I see to do what you want is to create a custom item renderer for the CLS column and have it render as a list control. That way, the CLS item in each row will only take up one row instead of multiple rows.
You can get some idea by following code... you can build logic using below concept for your implementation. Below example is sample not complete according to your requirement: -
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.core.UIComponent;
import mx.events.AdvancedDataGridEvent;
import mx.events.ListEvent;
[Bindable]
private var dpHierarchy:ArrayCollection= new ArrayCollection
([
{name:"Barbara Jennings", address: "Arizona", contact:999970, orders:["1"]},
{name:"Dana Binn", address: "Arizona", contact:9999130, orders:["2"]},
{name:"Joe Smith", address: "California", contact:9992929, orders:["3"]},
{name:"Alice Treu", address: "California", contact:9999230, orders:["4"]}
]);
private function addOrder():void
{
for(var i:int = 0 ; i < dpHierarchy.length; i++)
{
if(dropDownID.selectedItem.name == dpHierarchy[i].name)
{
var itemUpdated:Array = dpHierarchy[i].orders;
itemUpdated.push(orderNumber.text);
dpHierarchy[i].orders = itemUpdated;
dpHierarchy.itemUpdated(dpHierarchy[i]);
break;
}
}
}
]]>
</fx:Script>
<mx:VBox x="30" y="30" width="450" height="400">
<s:HGroup>
<s:Button label="Add Order" click="addOrder()"/>
<s:DropDownList id="dropDownID" dataProvider="{dpHierarchy}" labelField="name" selectedIndex="0"/>
<s:TextInput id="orderNumber" width="100"/>
</s:HGroup>
<mx:AdvancedDataGrid id="myADG"
dataProvider="{dpHierarchy}"
variableRowHeight="true" wordWrap="true">
<mx:columns>
<mx:AdvancedDataGridColumn dataField="name" headerText="Name"/>
<mx:AdvancedDataGridColumn dataField="address" headerText="Address"/>
<mx:AdvancedDataGridColumn dataField="contact" headerText="Contact"/>
<mx:AdvancedDataGridColumn dataField="orders" headerText="Orders" itemRenderer="OrderItemRenderer"/>
</mx:columns>
</mx:AdvancedDataGrid>
</mx:VBox>
</s:Application>
Item Reenderer Name: - OrderItemRenderer
<?xml version="1.0" encoding="utf-8"?>
<s:MXAdvancedDataGridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
focusEnabled="true" width="90%" height="90%">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var initDG:ArrayCollection = new ArrayCollection();
override public function set data(value:Object):void
{
super.data = value;
initDG = new ArrayCollection(value.orders)
}
]]>
</fx:Script>
<mx:DataGrid id="dataGrid" dataProvider="{initDG}" headerHeight="0" rowCount="{initDG.length}"/>
</s:MXAdvancedDataGridItemRenderer>

Disable alternatingItemColor property for AdvancedDataGrid if the rows are empty

I have a custom AdvancedDataGrid and we use alternatingItemColors property which shows two different colors for rows of the AdvancedDataGrid. Now sometimes the datagrid has 15 rows but only 5 would have data and we want only first 5 rows to display alternating colors and rest of the rows should only display one color. Has anyone done this in past and if someone can please explain how to do this would be really appreciated.
Thanks in advance.
You have to override the Datagrid and override drawRowBackground method, if the rowInd is more than the number of rows then set the default color. See the code snippet mentioned given below -
public class CustomDataGrid extends AdvancedDataGrid
{
protected override function drawRowBackground(s:Sprite, rowIndex:int, y:Number, height:Number, color:uint, dataIndex:int):void{
var XMLdata:XML=rowNumberToData(dataIndex) as XML;
if(XMLdata!=null){
if(XMLdata.attribute(Constants.col) != undefined && XMLdata.attribute(Constants.col) != ""){
color=XMLdata.attribute(Constants.col);
}else{
color=0xFFFFFF;
}
}
super.drawRowBackground(s,rowIndex,y,height,color,dataIndex);
}
}
Either set rowCount to the actual row count when you have fewer rows than the height allows for, or override drawRowBackground.
Try by using Item renderer for your ADG: -
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
[Bindable]
private var dpHierarchy:ArrayCollection= new ArrayCollection([
{name:"A", region: "Arizona"},
{name:"B", region: "Arizona"},
{name:"C", region: "California"},
{name:"D", region: "California"}
]);
]]>
</fx:Script>
<mx:AdvancedDataGrid id="myADG"
width="500" height="500"
paddingBottom="0" paddingLeft="0" paddingRight="0" paddingTop="0"
dataProvider="{dpHierarchy}"
itemRenderer="DrawAlternateRowColor">
<mx:columns>
<mx:AdvancedDataGridColumn dataField="name" headerText="Name" />
<mx:AdvancedDataGridColumn dataField="region" headerText="Region" />
</mx:columns>
</mx:AdvancedDataGrid>
</s:Application>
//ItemRenderer name: - DrawAlternateRowColor -- you can use the same concept with you CADG.
<?xml version="1.0" encoding="utf-8"?>
<s:MXAdvancedDataGridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
focusEnabled="true" alternatingItemColors="[#0000FF, #FF0000]"
width="100%" height="100%">
<s:Label id="lblData" verticalAlign="middle" text="{listData.label}" />
</s:MXAdvancedDataGridItemRenderer>

How to add items to a datagrid at runtime in flex4?

My UserInfromation form contains two input fields username,location(city) and one radio button as gender and two buttons add and reset.when I click on add button that data will be added in datagrid at runtime.
I am unable to reproduce how will i do this.
can anyone help me on this with example?
Here is a sample app (with code):
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
private var ac:ArrayCollection = new ArrayCollection();
protected function addBtn_clickHandler(event:MouseEvent):void
{
var obj:Object = new Object();
obj.userName = userNameTI.text;
obj.location = locationTI.text;
ac.addItem(obj);
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<mx:Form width="100%">
<mx:FormItem label="UserName:">
<s:TextInput id="userNameTI"/>
</mx:FormItem>
<mx:FormItem label="Location:">
<s:TextInput id="locationTI"/>
</mx:FormItem>
</mx:Form>
<s:Button id="addBtn" label="Add" click="addBtn_clickHandler(event)"/>
<mx:DataGrid id="dg" width="100%" dataProvider="{ac}"/>
</s:WindowedApplication>
Couple of things are left for you as an exercise :)

pass data from popup to parent

I have a parent w/ a popup child. When parent loads, I have to call a function within the popup without showing the popup (thus, I load "pupLove" but don't include it in layout)....I then pass this data to the parent. When the user manually clicks another button to open the popup, the same function is called & data passed to the parent. However, I am not able to pass dg.length to the parent. I believe the root problem is that I am loading "pupLove" & thus the parents are getting confused.....I'm guessing if I get rid of "pupLove" I can pass the data correctly but will need to call the child's function at creationComplete of the parent....how do I do that?
Here's my parent:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
backgroundColor="green" width="50%" height="100%"
xmlns:local="*"
>
<fx:Script>
<![CDATA[
import pup;
import mx.managers.PopUpManager;
public function showPup(evt:MouseEvent):void {
var ttlWndw:pup = PopUpManager.createPopUp(this, pup, true) as pup;
PopUpManager.centerPopUp(ttlWndw);
}
]]>
</fx:Script>
<mx:VBox>
<local:pup id="pupLove" visible="false" includeInLayout="false" />
<s:Button click="showPup(event);" label="launch Pup" />
<mx:Text id="Ptest" color="black" text="from Parent:{pupLove.dg.length}" />
</mx:VBox>
</s:Application>
And a popup child called 'pup.mxml':
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300">
<fx:Script>
<![CDATA[
public function init():void{
// send php call
}
import mx.events.CloseEvent;
import mx.managers.PopUpManager;
private function removePup(evt:Event):void {
PopUpManager.removePopUp(this);
}
]]>
</fx:Script>
<fx:Declarations>
<s:ArrayCollection id="dg">
</s:ArrayCollection>
</fx:Declarations>
<s:TitleWindow width="100%" height="100%" close="removePup(event)">
<mx:VBox>
<mx:Text id="test" color="red" text="from Child:{dg.length}" />
<s:Button label="add Items" click="dg.addItem({id:'cat'})" />
</mx:VBox>
</s:TitleWindow>
</s:Group>
UPDATE: I guess my question can be more easily stated as: "is there a way to call a child's function from the parent without actually loading the child?"
Well, if in your child's function, you don't need to access any of its UI component, then you could instanciate the child in the parent view and call the method.
When you need to display the popup afterwhile, use the PopupManager addPopup method with this existing instance instead of using createPopup