Problem linking datagrid to text Input - apache-flex

What I am trying to do is have a user input his data into multiple textboxes, then once the data is entered it is displayed on the datagrid at runtime. The problem is when I run the app I click my button but no information entered is added to datagrid. My textboxes are also supposed to clear once the button is pressed but again nothing happens. Here is my code:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]private var dgItems:ArrayCollection;
[Bindable]public var temp:Object;
public function addItem(evt:Event):void {
//add item if the text input fields are not empty
if(name_input.text != ""&& location_input.text !="") {
//create a temporary Object
temp = myDG.selectedItem;
var temp:Object = new Object();
//add the text from the textfields to the object
temp = {name:name_input.text, location:location_input.text};
//this will add the object to the ArrayColldection (wich is binded with the DataGrid)
dgItems.addItem(temp);
//clear the input fields
name_input.text = "";
location_input.text ="";
}
}
]]>
</mx:Script>
<mx:DataGrid x="97" y="110" dataProvider="{dgItems}" id="myDG">
<mx:columns>
<mx:DataGridColumn headerText="Column 1" dataField="name:"/>
<mx:DataGridColumn headerText="Column 2" dataField="location:"/>
</mx:columns>
</mx:DataGrid>
<mx:Button x="97" y="51" label="add" click="addItem(event)"/>
<mx:TextInput x="117" y="300" id="location_input"/>
<mx:TextInput x="117" y="340" id="name_input"/>
</mx:Application>
Any help is greatly appreciated.

Your code has lots of errors. First, you were not initializing the dgItems array collection, so it's value was null. You would get errors when you tried to "addItem" to the null object.
Second you were trying to access the selectedItem of the dataGrid before initializing the DataGrid's ArrayCollection dataProvider. No items in the list, there can be no selectedItem.
Third, you're creating the new object twice; once with the 'new Object' line and again with
the in-line syntax for defining ojects: '{}
Fourth, the datafield properties on the DataGridColumn both had colons in them, but the object's properties did not.
I hope this helps.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
// array collection was never initialized; you can't items to a null object
[Bindable]private var dgItems:ArrayCollection = new ArrayCollection();
// not needed
// [Bindable]public var temp:Object;
public function addItem(evt:Event):void {
//add item if the text input fields are not empty
if(name_input.text != ""&& location_input.text !="") {
//create a temporary Object
// this line of code serves no purpos
// temp = myDG.selectedItem;
var temp:Object // = new Object();
//add the text from the textfields to the object
temp = {name:name_input.text, location:location_input.text};
//this will add the object to the ArrayColldection (wich is binded with the DataGrid)
dgItems.addItem(temp);
//clear the input fields
name_input.text = "";
location_input.text ="";
}
}
]]>
</mx:Script>
<mx:DataGrid x="97" y="110" dataProvider="{dgItems}" id="myDG">
<mx:columns>
<!-- need to remove the colons from the data field -->
<mx:DataGridColumn headerText="Column 1" dataField="name"/>
<mx:DataGridColumn headerText="Column 2" dataField="location"/>
</mx:columns>
</mx:DataGrid>
<mx:Button x="97" y="51" label="add" click="addItem(event)"/>
<mx:TextInput x="117" y="300" id="location_input"/>
<mx:TextInput x="117" y="340" id="name_input"/>
</mx:Application>
Many of these errors were easy to catch as soon as I launched the debugger. If you aren't already using it, I suggest doing some reading up on it.

Related

Flex datagrid and nested Array dataprovider

I have used datagrid on many projects populate the grid using the following "Usual data structure" and brought the standard o/p as shown below Image.
But now for one assignment I want to bring the same grid result using the below mentioned "Complex data structure" (nested array). I have some Idea which is process the data before pushing it to the Grid but the problem am having is I need to perform some update , edit delete operation through the grid renderers and the same should be reflected into the source collection also. Please let me know is there a way I can use the "Complex structure" and bring the expected o/p using any flex in build properties. Thanks in Advance.
Usual data structure
steps = [a,b,c];
a = {x:100,y:y1,z:z1};
b = {x:200,y:y2,z:z2};
c = {x:300,y:y3,z:z3};
Complex data structure
[] is an Array collection not Array type.
a = [100,y1,z1];
b = [200,y2,z2];
c = [300,y3,z3];
steps = [[a,some objects],[b,some objects],[c,some objects]];
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
private var a:ArrayCollection = new ArrayCollection(['x1','y1','z1']);
private var b:ArrayCollection = new ArrayCollection(['x2','y2','z2']);
private var c:ArrayCollection = new ArrayCollection(['x3','y3','z3']);
[Bindable]
private var stepsObjs:ArrayCollection = new ArrayCollection([{ items: a},{ items: b},{ items: c}]);
]]>
</mx:Script>
<mx:DataGrid dataProvider="{stepsObjs}" >
<mx:columns>
<mx:DataGridColumn dataField="items.0" headerText="x" />
<mx:DataGridColumn dataField="items.1" headerText="y" />
<mx:DataGridColumn dataField="items.2" headerText="z" />
</mx:columns>
</mx:DataGrid>
</mx:Application>
EDIT Replacing with code to solve the new question.
This one worked for me:
<?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:Script>
<![CDATA[
import mx.collections.ArrayCollection;
private var a:ArrayCollection = new ArrayCollection([100,'y1','z1']);
private var b:ArrayCollection = new ArrayCollection([200,'y2','z2']);
private var c:ArrayCollection = new ArrayCollection([300,'y3','z3']);
private var stepsObjs:ArrayCollection = new ArrayCollection([{ items: a},{ items: b},{ items: c}]);
private var stepsColl:ArrayCollection = new ArrayCollection([[a],[b],[c]]);
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout />
</s:layout>
<mx:DataGrid dataProvider="{stepsObjs}" >
<mx:columns>
<mx:DataGridColumn dataField="items.0" headerText="x" />
<mx:DataGridColumn dataField="items.1" headerText="y" />
<mx:DataGridColumn dataField="items.2" headerText="z" />
</mx:columns>
</mx:DataGrid>
<mx:DataGrid dataProvider="{stepsColl}" >
<mx:columns>
<mx:DataGridColumn dataField="0.0" headerText="x" />
<mx:DataGridColumn dataField="0.1" headerText="y" />
<mx:DataGridColumn dataField="0.2" headerText="z" />
</mx:columns>
</mx:DataGrid>
</s:Application>
The itemRenderers should dispatch an event that describes what should happen, and then it should be handled higher up.
Like this:
//inside item renderer
dispatchEvent(new ItemEvent(ItemEvent.DELETE_ITEM, true, item));//where true tells the event to bubble (you'll need to create this event)
//somewhere above the DataGrid
dataGrid.addEventListener(ItemEvent.DELETE_ITEM, deleteItemFromSource);
protected function deleteItemFromSource(e:ItemEvent):void {
var lcv:ListCollectionView = (dataGrid.dataProvider as ListCollectionView);
lcv.removeItemAt(lcv.getItemIndex(e.item));
}
Note as a FYI that you should be using some sort of ListCollectionView if you want the datagrid to automatically update when you change it, not an Array.
HTH;
Amy

Selecting a column in a flex datagrid

In a flex datagrid, by default clicking on column headers does sorting. I want it such that if a user clicks a column header the entire column is selected. I have the datagrid listening for the HEADER_RELEASE event so I know when the column header is clicked.
How can I have the column and header appear highlighted similar to how a row is highlighted when selected?
You can do this by setting backgroundColor of the selected column:
<?xml version="1.0" encoding="utf-8"?>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.events.DataGridEvent;
[Bindable]
public var mydata:ArrayCollection;
public function init():void
{
mydata = new ArrayCollection();
mydata.addItem( { a:"John", b:"Smith" } );
mydata.addItem( { a:"Jane", b:"Doe" } );
grid1.addEventListener(DataGridEvent.HEADER_RELEASE, selectColumn);
}
public function selectColumn(event:DataGridEvent):void
{
var selectedColumn:DataGridColumn = grid1.columns[event.columnIndex];
selectedColumn.setStyle("backgroundColor", "0x7FCEFF");
event.stopImmediatePropagation();
}
]]>
</mx:Script>
<mx:DataGrid id="grid1" editable="true" dataProvider="{mydata}" >
<mx:columns>
<mx:DataGridColumn dataField="a" headerText="A" />
<mx:DataGridColumn dataField="b" headerText="B" />
</mx:columns>
</mx:DataGrid>
I have a wee demo (with source) on how to do this on my website Here. Basically, you check to see if the DataGrid sort is the same as the column name in the Item renderer, and if it is, you draw a colored background.
Hope this helps.
Caspar

Assigning an array of objects to a DataGrid

When the dataProvider for an DataGrid is an array of objects, how do I set each column's dataField to a property of the object.
I have an ArrayCollection (say a) where each item is an object
For example a[i] = data:Object
Where the object data has some subproperties - data.name, data.title, data.content etc.
I have a DataGrid in which I want to display this data.
So I put:
<mx:DataGrid id="entries" dataProvider="{resultRSS}">
<mx:columns>
<mx:Array>
<mx:DataGridColumn headerText="Title" dataField="data.title"/>
<mx:DataGridColumn headerText="Date" dataField="data.created"/>
</mx:Array>
</mx:columns>
</mx:DataGrid>
This doesn't seem to work at all. I get an empty DataGrid. How should I assign the dataField property, so that it shows up properly? I've tried {data.title} too.
Thanks.
Edit: sample of my data
-[]arraycollection
--[0]
----id="id1"
----data.
------title="something"
------name="something"
------text="some html"
--[1]
----id="id2"
----data.
------title="something2"
------name="something2"
------text="some html2"
and table should be
|title |name |text |
=================================
|something |something |some html|
|something2|something2|somehtml2|
here is your answer
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="initialize()">
<mx:Script>
<![CDATA[
import mx.collections.HierarchicalData;
var a:Array = new Array();
var o:Object = {};
private function initialize():void{
o["text"]="hello";
o["desc"]="Rahul";
a.push(o);
}
]]>
</mx:Script>
<mx:AdvancedDataGrid width="100%" height="100%" sortExpertMode="true" id="adg1" designViewDataType="tree" dataProvider="{new HierarchicalData(a)}">
<mx:columns>
<mx:AdvancedDataGridColumn headerText="text" dataField="text"/>
<mx:AdvancedDataGridColumn headerText="desc" dataField="desc"/>
</mx:columns>
</mx:AdvancedDataGrid>
</mx:Application>
edit - ok now discard my previous answer according to your data try this
var a:Array = new Array();
var o:Object = {};
private function stringArrayToObjectArray():void{
o["id"]="mauj";
var oj:Object=new Object();
oj["title"]="aaa";
o["data"]=oj;
var oj1:Object=new Object();
oj1["id"]="mauj2";
var oj2:Object=new Object();
oj2["title"]="qqqq";
oj1["data"]=oj2;
a.push(o);
a.push(oj1);
}
private function some_labelFunc(item:Object,th:Object):String {
return item.data.title;
}
]]>
</mx:Script>
<mx:AdvancedDataGrid width="100%" height="100%" sortExpertMode="true" id="adg1" dataProvider="{a}">
<mx:columns>
<mx:AdvancedDataGridColumn headerText="COMPANIES" dataField="data" labelFunction="some_labelFunc"/>
</mx:columns>
</mx:AdvancedDataGrid>
</mx:Application>
try this sorry for such a bad code

Flex CheckBox in Datagrid

In the followin flex Code :
Also viewable at : http://www.cse.epicenterlabs.com/checkBoxDg/checkBoxDg.html
1. Add a row in datagrid by clicking on "AddRow"
2. Click on "CheckDg" to see the values of all the checkboxes
- it shows "checkBox57" or "checkBox64" or some similar string
3. Now, "select" the checkBox in the first row.
4. Click again on "CheckDg"
-it show "true"
So, initially dp.getItemAt(i).date returns a CheckBox
and later it returns the "selected" value of the CheckBox?
Why this difference?
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" viewSourceURL="srcview/index.html">
<mx:Canvas>
<mx:DataGrid x="69" y="119" id="dgFee" editable="true" dataProvider="{dp}">
<mx:columns>
<mx:DataGridColumn headerText="Date" dataField="date" width="100" editable="true"
editorDataField="selected" rendererIsEditor="true">
<mx:itemRenderer>
<mx:Component>
<mx:CheckBox selected="false">
</mx:CheckBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
<mx:DataGridColumn dataField="amount" headerText="Amount" editable="true">
<mx:itemEditor>
<mx:Component>
<mx:TextInput restrict="0-9"/>
</mx:Component>
</mx:itemEditor>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
<mx:CheckBox x="130" y="54" label="Checkbox" selected="true" click="Alert.show(abc.selected.toString())" id="abc"/>
<mx:Script>
<![CDATA[
import mx.controls.CheckBox;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
public var dp:ArrayCollection = new ArrayCollection();
public function addRow():void
{
var tmp:Object = new Object();
tmp['amount'] = 100;
tmp['date'] = new CheckBox();
dp.addItem(tmp);
}
public function delRow():void
{
if(dgFee.selectedIndex != -1)
dp.removeItemAt(dgFee.selectedIndex);
}
public function loop1():void
{
for(var i:int=0;i<dp.length;i++)
{
Alert.show(dp.getItemAt(i).date);
}
}
]]>
</mx:Script>
<mx:Button x="29" y="89" label="AddRow" click="addRow()"/>
<mx:Button x="107" y="89" label="DelRow" click="delRow()"/>
<mx:Button x="184" y="89" label="CheckDg" click="loop1()"/>
</mx:Canvas>
</mx:Application>
You are not supposed to assign objects to data variables but data. Checkbox.select property is set to your check box object first and then true or false after the preceding actions. Try this instead
public function addRow():void
{
var tmp:Object = new Object();
tmp['amount'] = 100;
tmp['date'] = false; // not new CheckBox();
dp.addItem(tmp);
}
PS: Also dp should be attributed with [Bindable] :-)
When you click on the check box in the grid, it writes "true" or "false" into the date field, replacing the original CheckBox object that was there. I believe what itemEditors (you are using your render as an editor) do is they write the .data property from the respective components into the collection.
Set the 'editable' property for that particular datagrid column as false. This will resolve the issue

How to find checkbox value ( checked/unchecked) in iteamreander of data grid ?

I have 3 checkboxes for calculating amount purpose. I used Datagrid within datgrid used
<mx:DataGrid>
<mx:itemRenderer>
<mx:Component>
<mx:CheckBox id=mycheckbox change="calc()"/>
</mx:Component>
</mx:itemRenderer>
...
public function calc():void
{
statistic.dataProvider = mycheckbox.selectedItem;
}
but it's throws error like Call to possibly undfined method (calc)
You can't give the checkbox an id the way you have done and expect it to behave as a single component.
When you specify the checkbox as an item renderer for a column you are not talking about a single checkbox.
You will be dealing with as many check boxes as there are rows in the datagrid.
The following example shows you how to determine if the checkbox in a particular row is selected or not
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.Alert;
private var ac:ArrayCollection=new ArrayCollection([
{name: "John", test: true},
{name: "Joe", test: false}]);
private function init() {
dg.dataProvider=ac;
}
public function check():void {
var obj:Object=dg.selectedItem;
Alert.show("Checkbox=" + obj.test);
}
]]>
</mx:Script>
<mx:DataGrid id="dg"
dataProvider="{ac}"
click="check()">
<mx:columns>
<mx:DataGridColumn dataField="name">
</mx:DataGridColumn>
<mx:DataGridColumn>
<mx:itemRenderer>
<mx:Component>
<mx:CheckBox label="Test"
selected="{data.test}"/>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
</mx:Application>
Sometimes flex seems to have trouble updating the data provider for the datagrid when you have a nested itemrenderer. You can explicitly set the appropriate property of the dataprovider row when the change event occurs on the checkbox as below;
<mx:itemRenderer>
<mx:Component>
<mx:CheckBox label="Test" selected="{data.test}"
change="data.test=selected"/>
</mx:Component>
</mx:itemRenderer>
A checkbox does not have a "selectedItem" function or property...
mycheckbox.selected will return true or false based on whether or not sed checkbox is checked
Not really sure what you're trying to accomplish by setting a dataprovider to true or false, seems to me like you want to use a RadioButtonGroup
use outerDocument.functionname inside itemrenderer, and set the function as public. This is a limitation of Flex, Hierarchy mismanagement.

Resources