How to set advanced data grid column from a xternal xml? - actionscript-3

I have a xml file
<Column id="first name" headerLabel="first name" dataField="first name" />
<Column id="regionName" headerLabel="Region" dataField="region_name" />"
<Column id="lastname" headerLabel="last_name" dataField="last_name"/>
I want this column name to be assigned to my data grid as i am succesfull in picking up data from a back end and save in a variable now i just want to display it in my advanced data grid can any body guide me how to do that with a written example?
<mx:AdvancedDataGrid
id="list"
dataProvider="{data}"
columns = ?/>
I am using this code supoose my xml file name is in assets/config/rumpy.xml from which i want to retrieve column name using header field.

I would suggest you to convert this XML to a XMLList and add columns to the data grid while iterating through its elements.
By default you should determine an empty set of data grid columns. In my example if you don't do it, you will get two times more columns, because the grid can define columns automatically according to the data provider's structure.
<?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" creationComplete="init(event)">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.advancedDataGridClasses.AdvancedDataGridColumn;
import mx.events.FlexEvent;
private var columnList:XMLList;
[Bindable]private var data:ArrayCollection = new ArrayCollection([
{first_name:"John", last_name:"Busch", region_name:"CA"},
{first_name:"Mike", last_name:"Harris", region_name:"DC"},
{first_name:"Linda", last_name:"Brucks", region_name:"CA"}]);
protected function init(event:FlexEvent):void
{
loadXML();
}
private function loadXML():void
{
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, onXMLComplete);
loader.load(new URLRequest("assets/config/rumpy.xml"));
}
private function onXMLComplete(evt:Event):void
{
var xmlData:XML = XML((evt.currentTarget as URLLoader).data);
columnList = xmlData.Column;
var cols:Array = list.columns;
for each (var item:XML in columnList)
{
var adgc:AdvancedDataGridColumn = new AdvancedDataGridColumn(item.#dataField);
adgc.headerText = item.#headerText;
cols.push(adgc);
}
list.columns = cols;
}
]]>
</fx:Script>
<mx:AdvancedDataGrid id="list" x="10" y="10" dataProvider="{data}" width="360" height="120">
<mx:columns/>
</mx:AdvancedDataGrid>
</s:Application>
//rumpy.xml
<Columns>
<Column id="first_name" headerText="First Name" dataField="first_name"/>
<Column id="regionName" headerText="Region" dataField="region_name"/>
<Column id="lastname" headerText="Last Name" dataField="last_name"/>
</Columns>

Related

Dynamically generated MXML data doesn't get rendered

So I have a requirement to display dynamically generated data in the view.
For this, my idea was to create a mxml file and then use it as an object. Fill the data in the ibject and then use addChild to display it. But even after adding all the data. The dynamically generated mxml file doesn't gets displayed.
Code
BuyTogetherGrid.MXML
<?xml version="1.0" encoding="utf-8"?>
<mx:Box xmlns:mx="http://www.adobe.com/2006/mxml" width="80" height="60" xmlns:image="org.commodity.detail.image.*">
<mx:HBox>
<image:ImageBox id="buyTogetherImg"></image:ImageBox>
<mx:VBox id="textInfo">
<mx:Box id="commonNameBox">
<mx:Label id="commonName">
</mx:Label>
</mx:Box>
<mx:Box id="commonPriceBox">
<mx:Label id="commonPrice">
</mx:Label>
</mx:Box>
</mx:VBox>
</mx:HBox>
<mx:Script>
<![CDATA[
public function createGrid():void{
this.buyTogetherImg = new ImageBox();
this.commonName = new Label();
this.commonPrice = new Label();
}
]]>
</mx:Script>
</mx:Box>
This is my MXMl File. My idea was to create an object of this mxml object. Add data to buyTogetherImg, CommonName, CommonPrice and then use addChild
Part where I set the data
<mx:HBox id="buyTogetherBox" width="100%" borderColor="black">
</mx:HBox>
The upper HBox is the container where I will keep all my generated object
var buyTogetherBox : BuyTogetherGrid = new BuyTogetherGrid();
buyTogetherBox.createGrid();
for each(var item:cmListItem in commod.items){
if(item.dataFormat == 2){
buyTogetherBox.buyTogetherImg.imgData = item.value as ImageData;
} else if(item.dataFormat == 0){
buyTogetherBox.commonName.text = item.value.toString();
} else if(item.dataFormat == 3){
buyTogetherBox.commonPrice.text = StringUtil.numToStrPrice(item.value as Number);
}
}
this.buyTogetherBox.addChild(buyTogetherBox);
}
The code check some conditions and add the data. However the buyTogetherBox is not visible. But if I try something like
this.buyTogetherBox.addChild(buyTogetherBox.buyTogetherImg);
then i can see the image in the H:Box.
I am pretty new to Flex. so may be I would have missed something
You are leaving the statically created instances of the label and image control unused and creating new instances instead. Basically, the entire createGrid() function is unnecessary. You already have the controls created in MXML. Just use them with creating new instances.
var grid:BuyTogetherGrid = new BuyTogetherGrid();
grid.addEventListener(FlexEvent.CREATION_COMPLETE, this.grid_creationCompleteHandler);
Elsewhere in the same class...
private function grid_creationCompleteHandler(event:FlexEvent):void
{
// Set your properties here
}
As Pranav said it takes some time to create MXML components and if you try to assess them immediately you will get a null pointer exception because they don't exist yet. A quick and dirty solution is to make public variables in your BuyTogetherGrid.MXML and then bind the text properties to these variables, like
<?xml version="1.0" encoding="utf-8"?>
<mx:Box xmlns:mx="http://www.adobe.com/2006/mxml" width="80" height="60" xmlns:image="org.commodity.detail.image.*">
<fx:Script>
<![CDATA[
[Bindable] public var imageData:ImageData;
[Bindable] public var name:String;
[Bindable] public var price:String;
]]>
</fx:Script>
<mx:HBox>
<image:ImageBox id="buyTogetherImg" imgData={imageData}/>
<mx:VBox id="textInfo">
<mx:Box id="commonNameBox">
<mx:Label id="commonName" text="{name}">
</mx:Label>
</mx:Box>
<mx:Box id="commonPriceBox">
<mx:Label id="commonPrice" text="{price}">
</mx:Label>
</mx:Box>
</mx:VBox>
and then you do
buyTogetherBox.imageData = yourImageData;
buyTogetherBox.name = "Your Name";
buyTogetherBox.imageData = "Your price";
and yes, remove the unnecessary createGrid() method

arraycollection error in flex4.6

I'm having difficulty passing json to a datagrid.
I get the following error:
TypeError: Error #1034: Type Coercion failed: cannot convert mx.collections::ArrayCollection#bc292a9 to Array.
at Function/<anonymous>()[C:\Users\Birger\Dropbox\Rich Media Applications\P006_Project\src\FULLTEST.mxml:10]
at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.binding::Binding/wrapFunctionCall()[E:\dev\4.y\frameworks\projects\framework\src\mx\binding\Binding.as:395]
at mx.binding::Binding/innerExecute()[E:\dev\4.y\frameworks\projects\framework\src\mx\binding\Binding.as:469]
at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.binding::Binding/wrapFunctionCall()[E:\dev\4.y\frameworks\projects\framework\src\mx\binding\Binding.as:395]
at mx.binding::Binding/execute()[E:\dev\4.y\frameworks\projects\framework\src\mx\binding\Binding.as:333]
at mx.binding::BindingManager$/executeBindings()[E:\dev\4.y\frameworks\projects\framework\src\mx\binding\BindingManager.as:153]
at FULLTEST/_FULLTEST_ArrayCollection1_i()[C:\Users\Birger\Dropbox\Rich Media Applications\P006_Project\src\FULLTEST.mxml:4]
at FULLTEST()[C:\Users\Birger\Dropbox\Rich Media Applications\P006_Project\src\FULLTEST.mxml:4]
my code is:
<?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" xmlns:components="components.*" initialize="getData.send();">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<mx:HTTPService id="getData" url="http://localhost/P006_Project/Query.php"
useProxy="false" method="POST" resultFormat="text" result="getPHPData(event)">
</mx:HTTPService>
<s:ArrayCollection id="acItems" source="{dataArray}" />
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
import mx.rpc.events.ResultEvent;
[Bindable]private var dataArray:ArrayCollection = new ArrayCollection();
private function initDataGrid():void
{
getData.send();
}
private function getPHPData(event:ResultEvent):void
{
var rawArray:Array;
var rawData:String = String(event.result);
rawArray = JSON.parse(rawData) as Array;
dataArray = new ArrayCollection(rawArray);
}
]]>
</fx:Script>
<mx:Accordion id="accItems" creationPolicy="auto">
<s:NavigatorContent label="Frisdranken">
<components:FULLTESTCOMP acItems="{acItems}" creationComplete="{initDataGrid()}"/>
</s:NavigatorContent>
</mx:Accordion>
</s:Application>
so I'm trying to fill my datagrid with content from my database by converting it into JSON. I'm using a custom component (just an ordinary datagrid in this one).
Here is the problem:
<s:ArrayCollection id="acItems" source="{dataArray}" />
source needs to be of type "Array" but you're assigning the source to an ArrayCollection object.
You should do:
<s:ArrayCollection id="acItems" source="{dataArray.source}" />
Hope this helps.

highlighting mx:datagrid individual cell on drag event

I'm new to flex and recently assigned a project where I need to work on datagrid to make it able to highlight individual or multiple (but adjacent) cells based on the item being dragged from a list. So scenario is like this...
I'm using flex SDK 4.6. I have a mx datagrid (I can't use spark or other version due to some restrictions) with some dates as rows and time (00-23 hrs) in columns( so total 25 columns: 1st column showing dates and rest 24 for hours).
That way we have each date acting as row-header which runs through 24 columns for hours. I have a list which is getting populated from an XML file and each item in the list has a date and time elements associated with it. when we drag an item from the list into datagrid, it should highlight particular cell(s) in the datagrid based on matching dates(from list item being dragged and datagrid dates column) and matching hours (from list item being dragged and datagrid hour columns).
So far I'm able to get the row index and column index/indices on drag enter but getting them highlighted as a whole row-column. for example if it turns out to be 3rd row and 4th-5th column, it highlights whole 3rd row(all 25 columns) and all cells under 4th-5th column. what I need is to get to a specific location like someCell(rowIndex:xx, ColIndex:YY) and change that cell's style. There are some examples with item-renderer but they are using cell's data to find if its less than or greater than some value and then maipulating it, but I couldn't use it in my case.
Secondly I want to replace the scrollbars with two buttons(one at top and another at bottom) of the dates column to scroll the dates. I'll be very thankful for any advise on that too.
Hope I've made the questions/scenario clear. Thanks for having a look into it. Looking forward for a helping hand from the community. This task is on urgent list...please help.
If I have understood your problem coorectly, here is my proposal.
You should be able to give to each cell of the datagrid information about date and time. You can make it through ItemRenderer, which implements IDropInListItemRenderer interface. If user selects any element of your XML List, he defines a certain time point, which should be compared with one of the ItemRenderer.
I hope it will help you.
//CellRenderer.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="100%" height="100%"
backgroundColor="{(cellDate == parentDocument.selectedDate && cellHour == parentDocument.selectedHour) ? 0xfcb9bb : 0xfefceb}"
implements="mx.controls.listClasses.IDropInListItemRenderer">
<fx:Script>
<![CDATA[
import mx.controls.dataGridClasses.DataGridListData;
import mx.controls.listClasses.BaseListData;
private var _listData:BaseListData;
[Bindable]private var cellDate:String;
[Bindable]private var cellHour:String;
override public function set data( value:Object ) : void
{
super.data = value;
cellDate = data.date;
cellHour = (listData as DataGridListData).label;
}
[Bindable]public function get listData() : BaseListData
{
return _listData;
}
public function set listData( value:BaseListData ) : void
{
_listData = value;
}
]]>
</fx:Script>
</mx:HBox>
//Application
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
layout="absolute"
minWidth="955" minHeight="600" creationComplete="initApp()" backgroundColor="0xeeeeee">
<fx:Declarations>
<fx:Model id="cells">
<dataset>
<data>
<date>14.01.2013</date>
<h00>00:00</h00>
<h01>01:00</h01>
<h02>02:00</h02>
<h03>03:00</h03>
</data>
<data>
<date>15.01.2013</date>
<h00>00:00</h00>
<h01>01:00</h01>
<h02>02:00</h02>
<h03>03:00</h03>
</data>
<data>
<date>16.01.2013</date>
<h00>00:00</h00>
<h01>01:00</h01>
<h02>02:00</h02>
<h03>03:00</h03>
</data>
<data>
<date>17.01.2013</date>
<h00>00:00</h00>
<h01>01:00</h01>
<h02>02:00</h02>
<h03>03:00</h03>
</data>
</dataset>
</fx:Model>
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.events.DragEvent;
import mx.events.ListEvent;
[Bindable]public var selectedDate:String;
[Bindable]public var selectedHour:String;
private function initApp():void
{
srclist.dataProvider = new ArrayCollection([
{activity: 'Reading', date: '14.01.2013', hour: '01:00'},
{activity: 'Television', date: '15.01.2013', hour: '03:00'},
{activity: 'Movies', date: '16.01.2013', hour: '02:00'}
]);
}
protected function onItemRollOver(event:ListEvent):void
{
var item:Object = (srclist.dataProvider as ArrayCollection).getItemAt(event.rowIndex);
selectedDate = item.date;
selectedHour = item.hour;
}
]]>
</fx:Script>
<mx:HBox x="35" y="28" height="200">
<mx:VBox width="124" height="100%">
<mx:Label text="Available Activities"/>
<mx:List
id="srclist"
labelField="activity"
width="118" height="100%"
allowMultipleSelection="false"
dragEnabled="true"
dragMoveEnabled="true" selectionColor="0xffffff"
itemRollOver="onItemRollOver(event)" itemRollOut="selectedDate = ''; selectedHour = '';"/>
</mx:VBox>
<mx:VBox height="100%">
<mx:Label text="Scheduler"/>
<mx:DataGrid
width="386" height="100%" dataProvider="{cells.data}"
alternatingItemColors="[0xffffff]"
horizontalGridLineColor="0x999999"
horizontalGridLines="true"
verticalGridLineColor="0x999999"
sortableColumns="false"
resizableColumns="false" selectable="false">
<mx:columns>
<mx:DataGridColumn dataField="date" headerText="Data"/>
<mx:DataGridColumn dataField="h00" headerText="00:00" itemRenderer="com.CellRenderer"/>
<mx:DataGridColumn dataField="h01" headerText="01:00" itemRenderer="com.CellRenderer"/>
<mx:DataGridColumn dataField="h02" headerText="02:00" itemRenderer="com.CellRenderer"/>
<mx:DataGridColumn dataField="h03" headerText="03:00" itemRenderer="com.CellRenderer"/>
</mx:columns>
</mx:DataGrid>
</mx:VBox>
</mx:HBox>
</mx:Application>

How to hide the contents of a flex data grid?

NOTE: I'm using FLEX 4.
Hi, I want to know if there is a way to hide the data of a data grid without hiding the data grid itself? I want the screen to open with the data grids appearing empty. I only want the contents of the data grid to be visible once the user has selected an option from a combo box. Is there a way to do this? (The reasons for this are sort of involved and not pleasant to explain, but it's something I have to do.)
Thanks!
You could set dataProvider of the data grid to null or an empty collection until ready to display your data.
By default, initialize null or an empty collection to the data grid. Then, when the desired combo box option is selected set the data grid data provider to valid data:
<?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">
<fx:Script>
<![CDATA[
import mx.collections.ArrayList;
import spark.events.IndexChangeEvent;
[Bindable]
public var data:ArrayList = new ArrayList([ "one", "two", "three" ]);
protected function combobox1_changeHandler(event:IndexChangeEvent):void
{
switch (comboBox.selectedItem)
{
case "Show data":
dataGrid.dataProvider = data;
break;
default:
dataGrid.dataProvider = null;
break;
}
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout />
</s:layout>
<s:DataGrid id="dataGrid"
dataProvider="{null}" />
<s:ComboBox id="comboBox"
change="combobox1_changeHandler(event)">
<s:dataProvider>
<s:ArrayList>
<fx:String>Show data</fx:String>
<fx:String>Hide data</fx:String>
</s:ArrayList>
</s:dataProvider>
</s:ComboBox>
</s:Application>
Another approach would be to use Flex state system.
You could define two states to control visibility of data in the data grid. Then, set the data provider according to the current state:
<?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"
currentState="hideData">
<s:states>
<s:State name="showData" />
<s:State name="hideData" />
</s:states>
<fx:Script>
<![CDATA[
import mx.collections.ArrayList;
import spark.events.IndexChangeEvent;
[Bindable]
public var data:ArrayList = new ArrayList([ "one", "two", "three" ]);
protected function combobox1_changeHandler(event:IndexChangeEvent):void
{
switch (comboBox.selectedItem)
{
case "Show data":
currentState = "showData";
break;
default:
currentState = "hideData";
break;
}
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout />
</s:layout>
<s:DataGrid id="dataGrid"
dataProvider.hideData="{null}"
dataProvider.showData="{data}" />
<s:ComboBox id="comboBox"
change="combobox1_changeHandler(event)">
<s:dataProvider>
<s:ArrayList>
<fx:String>Show data</fx:String>
<fx:String>Hide data</fx:String>
</s:ArrayList>
</s:dataProvider>
</s:ComboBox>
</s:Application>

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>