Flex Spark datagrid - actionscript-3

i have an error adding dataprovider on my spark datagrid:
Multiple initializers for property 'dataProvider'. (note: 'dataProvider' is the default property of 'spark.components.DataGrid').
My data is from s:httpService declaration and i put it in data grid something like this
<s:DataGrid includeIn="formState" x="348" y="57" width="287" dataProvider="{myHttpService}">
<s:columns>
<s:ArrayList>
<s:GridColumn dataField="data1" headerText="Data Field 1"></s:GridColumn>
<s:GridColumn dataField="data2" headerText="Data Field 2"></s:GridColumn>
<s:GridColumn dataField="data3" headerText="Data Field 3"></s:GridColumn>
</s:ArrayList>
</s:columns>
<s:typicalItem>
<fx:Object dataField1="Sample Data" dataField2="Sample Data" dataField3="Sample Data"></fx:Object>
</s:typicalItem>
<s:ArrayList>
<fx:Object data1="data1" data2="data1" data3="data1"></fx:Object>
<fx:Object data1="data2" data2="data2" data3="data2"></fx:Object>
<fx:Object data1="data3" data2="data3" data3="data3"></fx:Object>
<fx:Object data1="data4" data2="data4" data3="data4"></fx:Object>
</s:ArrayList>
</s:DataGrid>
and my http service is:
<s:HTTPService id="myHttpService" url="http://host.com/mydata.php"/>

Your code specifies the dataProvider twice, inadvertently I think.
The first time it is specified as a property on the tag, on this line.
<s:DataGrid includeIn="formState" x="348" y="57" width="287" dataProvider="{myHttpService}">
The second time it is specified as a child of the DataGrid, with these blocks:
<s:ArrayList>
<fx:Object data1="data1" data2="data1" data3="data1"></fx:Object>
<fx:Object data1="data2" data2="data2" data3="data2"></fx:Object>
<fx:Object data1="data3" data2="data3" data3="data3"></fx:Object>
<fx:Object data1="data4" data2="data4" data3="data4"></fx:Object>
</s:ArrayList>
You can't specify the dataProvider in both cases.
Additionally, I'll add that your code, as is, is using myHttpService as the dataProvider (in thef irst line). You probably want to use the results of the myHttpService call as the dataProvider; not the actual myHttpService object.
I believe you could bind to myHttpService.lastResults if you wanted, by my preference is to have a formal results handler that deals with handling the results, Conceptually like this:
<s:HTTPService id="myHttpService" url="http://host.com/mydata.php" result="onMyResult(event)"/>
protected function onMyResult(event:ResultEvent):void{
this.myDataGrid.dataProvider = new ArrayCollection(event.results as Array);
}

Related

Moving combo box up dynamically when changing combo box?

I'm using Flex builder 4.5. I'm having five combos in my web application.
Combo 1 loads as staff and student.
Combo 2 loads department,
Combo 3 loads staff names,
Combo 4 loads student batch and
Combo 5 loads student names respectively.
When i'm selecting student in 1st combo, combo 4 and combo 5 should move up dynamically. Kindly advise on this...
It is not a good practice to manipulate the coordinates of controls. Instead of it I would use a ViewStack control and change the selected index according to the item of the first combo.
So you have more control over your view representation and less problem with future changes.
<?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">
<s:VGroup x="10" y="10">
<s:ComboBox id="cbMain" selectedIndex="0">
<s:ArrayList>
<fx:Object label="Staff"/>
<fx:Object label="Student"/>
</s:ArrayList>
</s:ComboBox>
<mx:ViewStack id="vsMain" width="200" height="200" selectedIndex="{cbMain.selectedIndex}">
<s:NavigatorContent id="ncStaff" width="100%" height="100%">
<s:VGroup>
<s:ComboBox id="cbStaffDep" selectedIndex="0">
<s:ArrayList>
<fx:Object label="Department01"/>
<fx:Object label="Department02"/>
</s:ArrayList>
</s:ComboBox>
<s:ComboBox id="cbStaffName" selectedIndex="0">
<s:ArrayList>
<fx:Object label="StaffName01"/>
<fx:Object label="StaffName02"/>
</s:ArrayList>
</s:ComboBox>
</s:VGroup>
</s:NavigatorContent>
<s:NavigatorContent id="ncStudent" width="100%" height="100%">
<s:VGroup>
<s:ComboBox id="cbStudentBatch" selectedIndex="0">
<s:ArrayList>
<fx:Object label="Batch01"/>
<fx:Object label="Batch02"/>
</s:ArrayList>
</s:ComboBox>
<s:ComboBox id="cbStudentName" selectedIndex="0">
<s:ArrayList>
<fx:Object label="StudentName01"/>
<fx:Object label="StudentName02"/>
</s:ArrayList>
</s:ComboBox>
</s:VGroup>
</s:NavigatorContent>
</mx:ViewStack>
</s:VGroup>
</s:Application>

Flex binding List selectedItem

I`m new with flex, and trying to combine data for 2 List selections, (SEE CODE BELOW):
<s:Label x="538" y="130" text="Industry of Interest:"/>
<s:List id="reIndustry" x="538" y="150" width="165" height="122" dataProvider="{recruitIndustries}" labelField="industry"></s:List>
<s:Label x="723" y="130" text="Qualifications:"/>
<s:List id="reQualifications" x="723" y="150" width="165" height="122" selectedItem="reIndustry.selectedItem.qualification" labelField="qualification"></s:List>
What i would like to accomplish is that when you select data from "reIndustry", more data of the selected item will then show in "reQualifications" List.
Here is my Data:
<s:ArrayList id="recruitIndustries">
<fx:Object industry="Admin/PA/Secretary" qualification="Other"/>
<fx:Object industry="Automotive" qualification="Painter"/>
<fx:Object industry="Building/Construct/Mine"/>
<fx:Object industry="Engineering"/>
<fx:Object industry="Finance/Accounting"/>
<fx:Object industry="FMCG"/>
<fx:Object industry="General Employment"/>
<fx:Object industry="Health and Skincare"/>
<fx:Object industry="Insurance"/>
<fx:Object industry="International"/>
<fx:Object industry="IT/Computer"/>
<fx:Object industry="Legal"/>
<fx:Object industry="Logistics"/>
<fx:Object industry="Management"/>
<fx:Object industry="Manufacturing"/>
<fx:Object industry="Medical"/>
<fx:Object industry="Part Time/ Temps"/>
<fx:Object industry="Professions"/>
<fx:Object industry="Retail"/>
<fx:Object industry="Sales and Marketing"/>
<fx:Object industry="Tourism/Hospitality"/>
</s:ArrayList>
If possible, how can I add more values for showing in the second List "reQualifications".
#RIAstar question is Correct.
You can do it by below code:-
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import spark.events.IndexChangeEvent;
[Bindable]
private var moreDataProvider:ArrayCollection = new ArrayCollection();
private function itemClickHandler(event:IndexChangeEvent):void
{
moreDataProvider.removeAll();
if(Object(reIndustry.selectedItem).hasOwnProperty('qualification'))
moreDataProvider.addItem(reIndustry.selectedItem);
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout/>
</s:layout>
<s:Label x="538" y="130" text="Industry of Interest:"/>
<s:List id="reIndustry" dataProvider="{recruitIndustries}" x="538" y="150" width="165" height="122"
labelField="industry" change="itemClickHandler(event)"/>
<s:Label x="723" y="130" text="Qualifications:"/>
<s:List id="reQualifications" dataProvider="{moreDataProvider}" x="723" y="150" width="165" height="122"
labelField="qualification"/>

Selection highlighting in List doesn't disapear after intercepting value commit event

I am using a spark List and wanted to maintain the selection after changing the content of the list that is the data provider. If you set a new data provider the List sets its selectedIndex back to -1. We solved this problem by intercepting the valueCommit event that is fired when teh List wants to set itself back to -1 and setting the previously selected item (if the new data provider still contains it). This works so far but we are getting strange behaviour:
initially the previously selected item is still selected and highlighted as intended
if another item is selected, the highlighting stays on the intial item. It doesn't matter how often I select another one, the initial item is still highlighted but not selected. The newly selected item is in fact selected and also highlighted.
if the initial item is selected again the List is behaving normal again. When I select another item after I reselected the initial one once, the highlighting disapears.
The List is declared in an MXML like this:
<s:List dataProvider="{model.dataProvider}"
selectedIndex="#{model.selectedIndex}"
valueCommit="model.handleInputObjectListValueCommit(event)"/>
The code in the model class is very complex but this should be the relevant part:
[Bindable]
public var dataProvider:ArrayCollection;
[Bindable]
public var selectedIndex:int;
private var _indexToSelect:int = -1;
public function setNewContent(newContent:ArrayCollection):void {
undoManager.ignore(function ():void {
dataProvider.removeAll();
dataProvider.addAll(newContent);
_indexToSelect = selectedIndex;
});
}
public function handleValueCommit(event:Event):void {
if (_indexToSelect != -1) {
const localIndex:int = _indexToSelect;
_indexToSelect = -1;
selectedIndex = localIndex;
}
}
The undManager is a class that takes care of undo/redo. The ignore function takes care that the undoManager doesn't register the change in the dataProvider as an undoable action because only user interaction should be undoable.
any ideas?
I got the described result when capturing change events, and fixing it there would require either a hackish solution or a custom UI component to fix what seems like a bug in the List component. But it seems to work if you handle the logic as you change the data provider rather than trying to capture events:
public function setDataProvider(data:IList):void {
var previous:Object = theSparkList.selectedItem;
theSparkList.dataProvider = data;
var index:int = theSparkList.dataProvider.getItemIndex(previous);
if (index > -1) {
theSparkList.selectedIndex = index;
}
}
This might still require some refactoring, and it might not work with your architecture- you might have to provide more detail on that. Is capturing events the only choice?
Maybe when changing the dataProvider, re-instantiate the list control ...... list = new List();, or something along those lines to clear the settings for that control.
<?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"
creationComplete="_creationCompleteHandler()">
<s:layout>
<s:HorizontalLayout />
</s:layout>
<fx:Declarations>
<s:ArrayList id="d1">
<fx:Object label="Obj1" />
<fx:Object label="Obj2" />
<fx:Object label="Obj3" />
<fx:Object label="Obj4" />
<fx:Object label="Obj5" />
<fx:Object label="Obj6" />
<fx:Object label="Obj7" />
<fx:Object label="Obj8" />
<fx:Object label="Obj9" />
<fx:Object label="Obj10" />
<fx:Object label="Obj11" />
<fx:Object label="Obj12" />
<fx:Object label="Obj13" />
<fx:Object label="Obj14" />
</s:ArrayList>
<s:ArrayList id="d2">
<fx:Object label="AA1" />
<fx:Object label="AA2" />
<fx:Object label="AA3" />
<fx:Object label="AA4" />
<fx:Object label="AA5" />
<fx:Object label="AA6" />
<fx:Object label="AA7" />
<fx:Object label="AA8" />
<fx:Object label="AA9" />
</s:ArrayList>
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.IList;
import mx.events.PropertyChangeEvent;
import spark.events.IndexChangeEvent;
[Bindable]
public var listDataProvider:IList;
private var _lastSelectedItemIndex:int = -1;
private function _creationCompleteHandler():void
{
list.addEventListener(IndexChangeEvent.CHANGE, _list_changeHandler);
addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, _propertyChangeHandler);
listDataProvider = d1;
}
private function changeButt_clickHandler():void
{
listDataProvider = d2;
}
private function _propertyChangeHandler(event:PropertyChangeEvent):void
{
list.selectedIndex = _lastSelectedItemIndex;
}
private function _list_changeHandler(event:IndexChangeEvent):void
{
_lastSelectedItemIndex = list.selectedIndex;
}
]]>
</fx:Script>
<s:List id="list"
dataProvider="{listDataProvider}"
height="200" />
<s:Button label="changeButt"
click="changeButt_clickHandler()" />
</s:Application>

datagrid inline itemrender change dataprovider value

I create a datagrid with inline itemrenderer.
The renderer is a dropdownlist.
When dropdowlist value change, I'd like to update dataprovider but I didn't found how to do that.
Can you help me?
Thanks
[Bindable] private var DP_PRAT_INIT:ArrayCollection;
<s:DataGrid id="dgTuVous" fontWeight="normal"
dataProvider="{DP_PRAT_INIT}"
width="100%" height="100%"
horizontalScrollPolicy="on"
fontSize="10"
>
<s:columns>
<s:ArrayList>
<s:GridColumn dataField="prInitiales" width="40" headerText="Prat" />
<s:GridColumn width="75" dataField="prTuVous"
headerText="Tu/Vous" editable="true">
<s:itemRenderer>
<fx:Component>
<s:GridItemRenderer>
<fx:Script>
<![CDATA[
import spark.events.IndexChangeEvent;
protected function ddlTuVous_changeHandler(event:IndexChangeEvent):void
{
DP_PRAT_INIT[ddlTuVous.selectedIndex].prTuVous=ddlTuVous.selectedItem;
trace ("ddlTuVous.selectedItem" +ddlTuVous.selectedItem) ;
}
]]>
</fx:Script>
<s:DropDownList width="100%" selectedIndex="1" id="ddlTuVous"
change="ddlTuVous_changeHandler(event)">
<s:dataProvider>
<s:ArrayList>
<fx:String>Tu</fx:String>
<fx:String>Vous</fx:String>
</s:ArrayList>
</s:dataProvider>
</s:DropDownList>
</s:GridItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
</s:ArrayList>
</s:columns>
</s:DataGrid>
You reference the host control with the outerDocument property... so you would call outerDocument.DP_PRAT_INIT if you want to access that array. BUT, that array is private, so you have to make it public. Or, you can make a public function that you can call on outerDocument but ... yuck.
If I am understanding your code properly, you should access the data property of the GridItemRenderer which is the same as outerDocument.DP_PRAT_INIT[ddlTuVous.selectedIndex] except that it is better because you don't have possible index mismatches...
So, what you really want is:
data.prTuVous = ddlTuVous.selectedItem;

Checkboxes in a DataGrid get selected after Scrolling down in actionscript 3

i have implemented code, where i put Checkboxes in a DataGrid. The problem is, when a checkbox is checked and i scroll down, other checkboxes are checked as well, without me having checked them. If i scroll up again, the checkbox, which i initially checked, isnt checked anymore. Can anybody help me please.
Here is the Code:
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
initialize="main()" textAlign="right" textRotation="rotate270" title="HomeView">
<fx:Script>
<![CDATA[
import mx.collections.ArrayList;
import mx.graphics.SolidColorStroke;
import spark.primitives.Rect;
import spark.skins.spark.DefaultComplexItemRenderer;
import spark.skins.spark.DefaultItemRenderer;
private var bL:ArrayList;
public function main():void{
hey.dataProvider=dataprovider;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<s:ArrayList id="dataprovider">
<fx:Object actName="myact1" actnumber="2" name="1"/>
<fx:Object actName="myact2" actnumber="55" name="2"/>
<fx:Object actName="myact1" actnumber="2" name="3"/>
<fx:Object actName="myact2" actnumber="55" name="4"/>
<fx:Object actName="myact1" actnumber="2"/>
<fx:Object actName="myact2" actnumber="55"/>
<fx:Object actName="myact1" actnumber="2"/>
<fx:Object actName="myact2" actnumber="55"/>
<fx:Object actName="myact1" actnumber="2" name="1"/>
<fx:Object actName="myact2" actnumber="55" name="2"/>
<fx:Object actName="myact1" actnumber="2" name="3"/>
<fx:Object actName="myact2" actnumber="55" name="4"/>
<fx:Object actName="myact1" actnumber="2"/>
<fx:Object actName="myact2" actnumber="55"/>
<fx:Object actName="myact1" actnumber="2"/>
<fx:Object actName="myact2" actnumber="55"/>
<fx:Object actName="myact1" actnumber="2" name="1"/>
<fx:Object actName="myact2" actnumber="55" name="2"/>
<fx:Object actName="myact1" actnumber="2" name="3"/>
<fx:Object actName="myact2" actnumber="55" name="4"/>
<fx:Object actName="myact1" actnumber="2"/>
<fx:Object actName="myact2" actnumber="55"/>
<fx:Object actName="myact1" actnumber="2"/>
<fx:Object actName="myact2" actnumber="55"/>
</s:ArrayList>
</fx:Declarations>
<s:DataGrid id="hey" x="-2" y="-1" width="323" height="415">
<s:columns>
<s:ArrayList>
<s:GridColumn id="my" dataField="wierd">
</s:GridColumn>
<s:GridColumn id="hi" dataField="checkboxes">
<s:itemRenderer>
<fx:Component>
<s:GridItemRenderer>
<fx:Script>
<![CDATA[
protected function checkbox1_clickHandler(event:MouseEvent):void
{
trace("clicked");
}
]]>
</fx:Script>
<s:CheckBox click="checkbox1_clickHandler(event)">
</s:CheckBox>
</s:GridItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
</s:ArrayList>
</s:columns>
</s:DataGrid>
</s:View>
Here is a way to fix this issue. ( a work around )
The reason for this has something to do with the way it is implemented inside the Datagrid.
Eg: When you create 50 rows inside the Datagrid. It does not create 50 different instances of the row.. ( in a scrolling scenario ) rather, as you scroll up or down the same rows are populated with the differing data..( giving you a seamless experience of scrolling and viewing them )
So the trick to solving this problem would be to study the sample found in this link
http://www.actionscript.org/forums/attachment.php3?attachmentid=38409&d=1335099663
You would have to analyse the code in the cell renderer class found in the sample. In your case you would have to modify the DefaultItemRenderer or the DefaultComplexItemRenderer which ever is used by the Datagrid column.