Flex multiple spark lists with scrolling synced - actionscript-3

I have several horizontal scrolling lists with differing item widths stacked inside a Vertical Group. On an item click all any selected item from the other lists will be cleared. When any of the lists are scrolled all the other lists should scroll exactly the same amount in the same direction, simalar to http://www.foxsports.com.au/tvguide.
The synced scrolling is throwing an undefined error and has crashed the adl(it is a mobile app) on one occasion. This happens only when I add more than 2 synced scrolling lists via event listeners.
So my question is: Can anyone see why this errors or is there a better way to achieve this type of horizontal scrolling multi-list, possibly a really wide data-grid or group of buttons inside a scroller?
<?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" creationComplete="view1_creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.events.PropertyChangeEvent;
// listen for scroll event
protected function view1_creationCompleteHandler(event:FlexEvent):void
{
list1.scroller.viewport.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, propertyChangeHandler1);
list2.scroller.viewport.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, propertyChangeHandler2);
list3.scroller.viewport.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, propertyChangeHandler3);
}
// scroll all lists together
private function propertyChangeHandler1(evt:PropertyChangeEvent):void
{
var n:Number = Number(evt.newValue);
list2.dataGroup.horizontalScrollPosition = n;
list3.dataGroup.horizontalScrollPosition = n;
}
private function propertyChangeHandler2(evt:PropertyChangeEvent):void
{
var n:Number = Number(evt.newValue);
list1.dataGroup.horizontalScrollPosition = n;
list3.dataGroup.horizontalScrollPosition = n;
}
private function propertyChangeHandler3(evt:PropertyChangeEvent):void
{
var n:Number = Number(evt.newValue);
list2.dataGroup.horizontalScrollPosition = n;
list1.dataGroup.horizontalScrollPosition = n;
}
// on click clear currently selected
protected function listClickHandler(_iList:int, _index:int):void
{
switch(_iList)
{
case 1:
{
list2.selectedIndex = -1;
list3.selectedIndex = -1;
break;
}
case 2:
{
list1.selectedIndex = -1;
list3.selectedIndex = -1;
break;
}
case 3:
{
list2.selectedIndex = -1;
list1.selectedIndex = -1;
break;
}
}
}
]]>
</fx:Script>
<fx:Declarations>
<s:ArrayCollection id="myArrayCollection">
<fx:Object label="FIRST" message="54.99"/>
<fx:Object label="Stapler" message="3.59"/>
<fx:Object label="Printer" message="129.99"/>
<fx:Object label="Notepad" message="2.49"/>
<fx:Object label="Mouse" message="21.79"/>
<fx:Object label="Keyboard" message="32.99"/>
<fx:Object label="Ink" message="54.99"/>
<fx:Object label="Stapler" message="3.59"/>
<fx:Object label="Printer" message="129.99"/>
<fx:Object label="Notepad" message="2.49"/>
<fx:Object label="Mouse" message="21.79"/>
<fx:Object label="Keyboard" message="32.99"/>
<fx:Object label="Ink" message="54.99"/>
<fx:Object label="Stapler" message="3.59"/>
<fx:Object label="Printer" message="129.99"/>
<fx:Object label="Notepad" message="2.49"/>
<fx:Object label="Mouse" message="21.79"/>
<fx:Object label="Keyboard" message="32.99"/>
<fx:Object label="Ink" message="54.99"/>
<fx:Object label="Stapler" message="3.59"/>
<fx:Object label="LAST" message="32.99"/>
</s:ArrayCollection>
</fx:Declarations>
<s:VGroup id="lists" gap="0" left="0" right="0" top="0" bottom="0" width="180%" height="100%" >
<s:List id="list1" width="100%" click="listClickHandler(1, list1.selectedIndex)" horizontalScrollPolicy="on" verticalScrollPolicy="off" selectedIndex="0" dataProvider="{myArrayCollection}">
<s:layout>
<s:HorizontalLayout gap="0" />
</s:layout>
</s:List>
<s:List id="list2" width="100%" click="listClickHandler(2, list2.selectedIndex)" horizontalScrollPolicy="on" verticalScrollPolicy="off" selectedIndex="0" dataProvider="{myArrayCollection}">
<s:layout>
<s:HorizontalLayout gap="0" />
</s:layout>
</s:List>
<s:List id="list3" width="100%" click="listClickHandler(3, list3.selectedIndex)" horizontalScrollPolicy="on" verticalScrollPolicy="off" selectedIndex="0" dataProvider="{myArrayCollection}">
<s:layout>
<s:HorizontalLayout gap="0" />
</s:layout>
</s:List>
</s:VGroup>
</s:View>

Here is the simple way to do it, obviously the lists need to be wider than stage for it to scroll.
<s:Scroller id="sc" horizontalScrollPolicy="on" verticalScrollPolicy="off" width="100%">
<s:VGroup id="lists" gap="0" left="0" right="0" top="0" bottom="0">
<s:List id="list1" horizontalScrollPolicy="off" verticalScrollPolicy="off" dataProvider="{data}">
<s:layout>
<s:HorizontalLayout gap="0" />
</s:layout>
</s:List>
<s:List id="list2" horizontalScrollPolicy="off" verticalScrollPolicy="off" dataProvider="{data}">
<s:layout>
<s:HorizontalLayout gap="0" />
</s:layout>
</s:List>
<s:List id="list3" horizontalScrollPolicy="off" verticalScrollPolicy="off" dataProvider="{data}">
<s:layout>
<s:HorizontalLayout gap="0" />
</s:layout>
</s:List>
</s:VGroup>
</s:Scroller>

Dont go for Long code,
You can put your two listboxes inside Two scrollviewers and in the scrollviewer's viewChanged event write your code in codebehind.
private void ScrollViewer1_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
ScrollViewer2.ScrollToHorizontalOffset(double.Parse(ScrollViewer1.HorizontalOffset.ToString()));
}

Tested your example on a computer with 4.6 sdk but i see no errors.
Still your code will not work on lists of different size (in this case your lists will scroll only for the smallest list size) .
Also instead of using PropertyChangeEvent on viewport try using Event.CHANGE on scrollBar:
protected function view1_creationCompleteHandler(event:FlexEvent):void
{
list1.scroller.horizontalScrollBar.addEventListener(Event.CHANGE, propertyChangeHandler1);
list2.scroller.horizontalScrollBar.addEventListener(Event.CHANGE, propertyChangeHandler2);
list3.scroller.horizontalScrollBar.addEventListener(Event.CHANGE, propertyChangeHandler3);
}
// scroll all lists together
private function propertyChangeHandler1(evt:Event):void
{
var source = evt.currentTarget as Scroller;
var n:Number = list1.scroller.viewport.horizontalScrollPosition;
list2.dataGroup.horizontalScrollPosition = n;
list3.dataGroup.horizontalScrollPosition = n;
}
private function propertyChangeHandler2(evt:Event):void
{
var n:Number = list2.scroller.viewport.horizontalScrollPosition;
list1.dataGroup.horizontalScrollPosition = n;
list3.dataGroup.horizontalScrollPosition = n;
}
private function propertyChangeHandler3(evt:Event):void
{
var n:Number = list3.scroller.viewport.horizontalScrollPosition;
list2.dataGroup.horizontalScrollPosition = n;
list1.dataGroup.horizontalScrollPosition = n;
}
And if you need to change the scroll programmatically use also FlexEvent.VALUE_COMMIT

Related

Flex - How to do calculation in Flash Builder

<?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" title="BMI Calculator">
<fx:Script>
<![CDATA[
protected function calculate_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:actionContent>
<s:Button label="Back" click="navigator.pushView(MainHomeView)" styleName="back"/>
</s:actionContent>
<s:Label x="33" y="61" fontSize="30" text="Weight(kg) :"/>
<s:Label x="34" y="140" fontSize="30" text="Height(cm) :"/>
<s:TextInput id="mywieght" x="216" y="40" width="228" prompt="0.0kg" textAlign="right"/>
<s:TextInput id="myheight" x="216" y="119" width="228" prompt="0.0cm" textAlign="right"/>
<s:Button id="calculation" x="31" y="260" width="413" label="Calculate" fontSize="36"
fontStyle="italic"/>
<s:Label id="myresult" left="31" right="36" height="146" fontSize="72" fontStyle="normal"
fontWeight="bold" text="0.0" textAlign="center" verticalAlign="middle"
verticalCenter="99"/>
</s:View>
this is the gui for a BMI calculator. i dont really have the basic of using flash builder. can anyone teach me how to use the data input by user inside the textinput and then use it for calculation and display it? thanks
First you assign a click handler to your button so your calculate_clickHandler method will be called on button click:
<s:Button id="calculation" x="31" y="260" width="413" label="Calculate" fontSize="36" fontStyle="italic" click="calculate_clickHandler(event)"/>
Then you do your calculations and pass your result to the myresult Label:
protected function calculate_clickHandler(event:MouseEvent):void
{
var height:Number = Number(myheight.text);
var weight:Number = Number(mywieght.text); // you have a typo here, wiegth instead of weight ;)
myresult.text = height * weight;
}
And you probably want a popView() on back button click. This will remove the current view and go back to your last view. push() will add another view:
<s:Button label="Back" click="navigator.popView()" styleName="back"/>
Try this:
<?xml version="1.0"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script>
<![CDATA[
protected function calculate_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
const myWeightInKG:Number = Number(myWeight.text);
const myHeightInMeter:Number = Number(myHeight.text) * 0.01;
const BMI:Number = myWeightInKG / (myHeightInMeter * myHeightInMeter);
const BMI_withOneDecimalPlace:Number = int(BMI * 10)/10;
myResult.text = BMI_withOneDecimalPlace.toString();
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Label x="33" y="61" fontSize="30" text="Weight(kg) :"/>
<s:Label x="34" y="140" fontSize="30" text="Height(cm) :"/>
<s:TextInput id="myWeight" x="216" y="40" width="228" prompt="Weight in Kg(e.g. 56)" textAlign="right"/>
<s:TextInput id="myHeight" x="216" y="119" width="228" prompt="Weight in cm(e.g. 157)" textAlign="right"/>
<s:Button id="calculation" x="31" y="260" width="413" label="Calculate" fontSize="36"
fontStyle="italic" click="calculate_clickHandler(event)"/>
<s:Label id="myResult" left="31" right="36" height="146" fontSize="72" fontStyle="normal"
fontWeight="bold" text="0.0" textAlign="center" verticalAlign="middle"
verticalCenter="99"/>
</s:Application>

Flex bind variable has no effect

No matter what I do, I cannot have any effect on Flex MXML elements during initialization.
I want to display a different logo depending on whether a flashVar is true or not.
For some reason the flashvar has no effect on how the elements appear.
Am I missing anything ?
<?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:components="ru.kutu.grindplayer.views.components.*"
mouseEnabled="false"
implements="ru.kutu.grind.views.api.IMainView"
preinitialize="preinitialize(event)"
>
<s:states>
<s:State name="initializing" />
<s:State name="ready" />
<s:State name="error" />
</s:states>
<s:BorderContainer
id="logoContainer"
left="0" right="0"
top="0" bottom="0"
mouseEnabled="false"
includeIn="initializing"
backgroundColor="0x070707"
borderVisible = "false"
>
<s:Image
id="logoPaid"
verticalCenter="0"
horizontalCenter="0"
source="#Embed('/../assets/skin/dark.png')"
visible="{is_paid}"
/>
<s:Image
id="logoFree"
verticalCenter="0"
horizontalCenter="0"
source="#Embed('/../assets/skin/dark_free.png')"
visible="{!is_paid}"
/>
</s:BorderContainer>
<components:PlayerView
id="playerView"
left="0" right="0"
top="0" bottom="0"
visible="false"
visible.ready="true"
/>
<s:Label
id="errorDisplay"
width="80%"
mouseEnabled="false"
verticalCenter="0"
horizontalCenter="0"
includeIn="error"
itemCreationPolicy="immediate"
/>
<s:transitions>
<s:Transition
fromState="*" toState="*"
autoReverse="true"
interruptionBehavior="stop"
>
<s:Fade
target="{this}"
duration="300"
/>
</s:Transition>
</s:transitions>
<fx:Script>
<![CDATA[
import mx.core.FlexGlobals;
import mx.events.FlexEvent;
[Bindable]
private var is_paid:Boolean;
public function set errorText(value:String):void {
errorDisplay.text = value;
}
public function initializing(is_paid:Boolean):void {
currentState = "initializing";
}
public function ready():void {
currentState = "ready";
}
public function error():void {
currentState = "error";
}
private function preinitialize(event:FlexEvent):void {
is_paid = FlexGlobals.topLevelApplication.parameters.is_paid;
}
]]>
</fx:Script>
I think you parse String into Boolean. Cause params names and values are String, try this instead:
is_paid = FlexGlobals.topLevelApplication.parameters.is_paid == 'true';

Flex 4.6 : Make action for button in list

I'm beginner in Flex . my issue when to add button to list , i put the button in the itemrender but the action of navigator.pushView(views.Listde,ProblemsList.selectedItem);
make an error "Acess of undefined property navigator .
Code :
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script>
<![CDATA[
import views.ButList;
protected function button1_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
navigator.pushView(views.Listde,ProblemsList.selectedItem);
}
]]>
</fx:Script>
<s:Group width="100%" height="100%" styleName="PCS.css">
<s:HGroup width="100%" height="100%" gap="2" verticalAlign="middle" horizontalAlign="center" paddingBottom="5" paddingLeft="5"
paddingRight="5" paddingTop="5">
<s:HGroup width="30%" height="100%" verticalAlign="middle" horizontalAlign="center">
<s:Label text="{data._AddedDate}" textAlign="left" verticalAlign="bottom" width="100%" height="100%"/>
</s:HGroup>
<s:VGroup width="50%" height="100%" verticalAlign="middle" horizontalAlign="right">
<s:BitmapImage source="images/{data.image}"/>
<s:TextArea editable="false" text="{data.description}"/>
<s:Label text="{data.price}"/>
<s:Button label="s" click="button1_clickHandler(event)"/>
</s:VGroup>
</s:HGroup>
</s:Group>
if any solution to resolve it by list or any component instead of list then i want button to navigate to view with the selected item and the change of the list to navigate to another view with the selected item also , then the change of list work success but the button action cannot defined with the navigator.
Thanks in advance for any help .
Create a custom event with data property and dispatch the event from item renderer or dispatch the list change event from the item renderer when clicking the button.
package myEvents
{
import flash.events.Event;
public class CustomEvent extends Event
{
public function CustomEvent(type:String,
data:Object=null) {
// Call the constructor of the superclass.
super(type);
// Set the new property.
this.data = data;
}
// Define static constant.
public static const MY_BUTTON_CLICKED:String = "myButtonClicked";
// Define a public variable to hold the state of the enable property.
public var data:Object;
// Override the inherited clone() method.
override public function clone():Event {
return new CustomEvent(type, data);
}
}
}
MyItemRenderer.mxml
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script>
<![CDATA[
import views.ButList;
protected function button1_clickHandler(event:MouseEvent):void
{
// dispatch a custom
(this.owner as List).dispatchEvent(new CustomEvent(CustomEvent.MY_BUTTON_CLICKED, data));
//navigator.pushView(views.Listde,ProblemsList.selectedItem);
}
]]>
</fx:Script>
<s:Group width="100%" height="100%" styleName="PCS.css">
<s:HGroup width="100%" height="100%" gap="2" verticalAlign="middle" horizontalAlign="center" paddingBottom="5" paddingLeft="5"
paddingRight="5" paddingTop="5">
<s:HGroup width="30%" height="100%" verticalAlign="middle" horizontalAlign="center">
<s:Label text="{data._AddedDate}" textAlign="left" verticalAlign="bottom" width="100%" height="100%"/>
</s:HGroup>
<s:VGroup width="50%" height="100%" verticalAlign="middle" horizontalAlign="right">
<s:BitmapImage source="images/{data.image}"/>
<s:TextArea editable="false" text="{data.description}"/>
<s:Label text="{data.price}"/>
<s:Button label="s" click="button1_clickHandler(event)"/>
</s:VGroup>
</s:HGroup>
</s:Group>
Your view class
<?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"
title="MY View">
<s:layout>
<s:VerticalLayout paddingTop="10"/>
</s:layout>
<fx:Script>
<![CDATA[
import spark.events.IndexChangeEvent;
private function onListCreationComplete_Handler():void
{
myList.addEventListener(CustomEvent.MY_BUTTON_CLICKED, onItemRendererButtonClicked);
}
protected function onItemRendererButtonClicked(event:CustomEvent):void {
var data:Object = event.data;
navigator.pushView(views.Listde,data);//myList.selectedItem
}
]]>
</fx:Script>
<s:Label text="Select an view"/>
<s:List id="myList"
width="100%" height="100%"
labelField="firstName" itemRenderer="MyItemRenderer"
change="myList_changeHandler(event)" creationComplete="onListCreationComplete_Handler()">
<s:ArrayCollection>
<fx:Object description="Fruits" image="assets/icons/1.png" _AddedDate="15/05/14" price="154"/>
<fx:Object description="New Item" image="assets/icons/2.png" _AddedDate="15/05/14" price="154"/>
<fx:Object description="Doll" image="assets/icons/3.png" _AddedDate="15/05/14" price="154"/>
</s:ArrayCollection>
</s:List>
</s:View>
I hope this might help u. There are tons of examples out there for list and item renderer for mobile.
Based on your ItemRenderer, you can simply listen to the IndexChangeEvent in your View. In this case, you don't need a separate button at all - the whole ItemRenderer can act as the button.
<?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"
title="MY View">
<s:layout>
<s:VerticalLayout paddingTop="10"/>
</s:layout>
<fx:Script>
<![CDATA[
import spark.events.IndexChangeEvent;
import views.ButList;
protected function myList_changeHandler(event:IndexChangeEvent):void {
navigator.pushView(views.Listde,myList.selectedItem);
}
]]>
</fx:Script>
<s:Label text="Select an view"/>
<s:List id="myList"
width="100%" height="100%"
labelField="firstName" itemRenderer="MyItemRenderer"
change="myList_changeHandler(event)">
<s:ArrayCollection>
<fx:Object description="Fruits" image="assets/icons/1.png" _AddedDate="15/05/14" price="154"/>
<fx:Object description="New Item" image="assets/icons/2.png" _AddedDate="15/05/14" price="154"/>
<fx:Object description="Doll" image="assets/icons/3.png" _AddedDate="15/05/14" price="154"/>
</s:ArrayCollection>
</s:List>
</s:View>

Disable unselected items in a List After 5 items are selected

Im new to flex development. I have a dynamically data bound list component. I need to restrict user from selecting more than 5 items.
List is made with checkboxes and labels
getSelectionCount() method returns the number of currently selected items.
Here is my code
<s:VGroup width="100%" height="100%">
<s:List id="chkLst" visible="{isMultipleSelectionAllowed}" width="100%" height="100%" borderVisible="false"
fontFamily="segoeui"
dataProvider="{filteredDataSet}" >
<s:itemRenderer>
<fx:Component>
<s:ItemRenderer>
<fx:Script>
<![CDATA[
import mx.controls.Alert;
//-----------------------------------------------
//
// Checkbox select
//
//-----------------------------------------------
protected function chk_clickHandler(event:MouseEvent):void
{
var selection:Array = new Array();
for each(var item:Object in outerDocument.chkLst.dataProvider)
{
selection.push(item);
}
var count:int = 0;
for each(var sItem:Object in selection)
{
outerDocument.setSelectionCount(0);
if(sItem.selected)
{
count++;
}
outerDocument.setSelectionCount(count);
}
Alert.show(outerDocument.getSelectionCount()+"","test");
if(CheckBox(event.target).selected && outerDocument.getSelectionCount() <= 5){
outerDocument.setSelectionCount(outerDocument.getSelectionCount()+1);
}
if(outerDocument.getSelectionCount() >= 6){
}
}
]]>
</fx:Script>
<s:HGroup width="100%" height="30" gap="2" paddingLeft="5" paddingRight="5" verticalAlign="middle" clipAndEnableScrolling="true">
<s:CheckBox id="chk"
label="{data.label}" change="{data.selected = chk.selected}" selected="{data.selected}"
maxWidth="215" click="chk_clickHandler(event)" />
</s:HGroup>
</s:ItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:List>
How can disable the checkboxes which user has not selected when user selection count exceeds 5 ?
2 I also need to enable all check boxes back if user unticks some checks in order that selection count go below 5
Thank You
First you need to add enabled property in your arraycollection like below which also make bindable in itemRenderer enabled="{data.enabled}". If count reach 5 we disable all button except selected one which the help of enabled property and magic here we need to update arraycollection items by using mx.collections.IList.itemUpdated(item:Object, property:Object=null, oldValue:Object=null, newValue:Object=null):void method so that only it will reflect disable the other checkboxes. In our case use outerDocument.chkLst.dataProvider.itemUpdated(item);
Sample arraycollection structure:
<fx:Declarations>
<s:ArrayCollection id="filteredDataSet" >
<fx:Object selected="false" enabled="true" label="one"/>
<fx:Object selected="true" enabled="true" label="two"/>
<fx:Object selected="false" enabled="true" label="three"/>
<fx:Object selected="false" enabled="true" label="four"/>
<fx:Object selected="false" enabled="true" label="five"/>
<fx:Object selected="false" enabled="true" label="six"/>
<fx:Object selected="false" enabled="true" label="seven"/>
<fx:Object selected="false" enabled="true" label="eight"/>
<fx:Object selected="false" enabled="true" label="nine"/>
</s:ArrayCollection>
</fx:Declarations>
<s:List id="chkLst" width="100%" height="100%" borderVisible="false"
fontFamily="segoeui"
dataProvider="{filteredDataSet}" >
<s:itemRenderer>
<fx:Component>
<s:ItemRenderer>
<fx:Script>
<![CDATA[
import mx.controls.Alert;
protected function chk_clickHandler(event:MouseEvent):void
{
data.selected = chk.selected;
var selection:Array = [];
for each(var item:Object in outerDocument.chkLst.dataProvider)
{
if(item.selected)
selection.push(item);
}
if(selection.length>=5)
{
for each(var item:Object in outerDocument.chkLst.dataProvider){
item.enabled = item.selected;
outerDocument.chkLst.dataProvider.itemUpdated(item);
}
}else{
for each(var item:Object in outerDocument.chkLst.dataProvider){
item.enabled = true;
outerDocument.chkLst.dataProvider.itemUpdated(item);
}
}
}
]]>
</fx:Script>
<s:HGroup width="100%" height="30" gap="2" paddingLeft="5" paddingRight="5" verticalAlign="middle" clipAndEnableScrolling="true">
<s:CheckBox id="chk" label="{data.label}" selected="{data.selected}" enabled="{data.enabled}"
maxWidth="215" click="chk_clickHandler(event)" />
</s:HGroup>
</s:ItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:List>

flex spark list Drag and drop an item on a spark canvas component

i have a spark list that displays a list of images that represent products. i am trying to implement a drag and drop functionality that allows the user to drag the products he wants to buy from the list to canvas area where he can see the products he choose before buying them. i am using the code below but i cannot figure out what is wrong with it , it seems that i am unable to use the list item as a draginitiator, can any one help please:
private function onMouseDown( event : MouseEvent ) : void
{
var list:List = List(event.currentTarget);
var dragInitiator:Image = Image (list.selectedItem);
var source : DragSource = new DragSource();
source.addData(dragInitiator, "img");
DragManager.doDrag(dragInitiator, source, event);
}
protected function canvas1_dragEnterHandler(event:DragEvent):void
{
DragManager.acceptDragDrop(Canvas(event.currentTarget));
}
protected function canvas1_dragDropHandler(event:DragEvent):void
{
Image(event.dragInitiator).x =
Canvas(event.currentTarget).mouseX;
Image(event.dragInitiator).y =
Canvas(event.currentTarget).mouseY; }
<fx:Model id="categoriesModel" source="Data/Categories.xml"/>
<s:ArrayList id="CategoriesCollection" source="{categoriesModel.Category}"/>
<fx:Model id="productsModel" source="Data/Products.xml"/>
<s:ArrayList id="ProductsCollection" source="{productsModel.Product}" />
</fx:Declarations>
<s:VGroup gap="5" horizontalAlign="center">
<s:HGroup gap="5">
<Components:PROExpressLogo/>
<s:List id="categoryList" scroller="{null}" visible="true"
itemRenderer="Renderers.categoryItemRenderer" width="700" borderAlpha="0"
change="categoryList_changeHandler(event)">
<s:layout>
<s:HorizontalLayout/>
</s:layout>
</s:List>
</s:HGroup>
<s:List id="productList" scroller="{null}" contentBackgroundAlpha="0.4" contentBackgroundColor="0xabcdef"
itemRenderer="Renderers.productItemRenderer" width="880" borderAlpha="0" visible="true" horizontalCenter="0"
dragEnabled="false" mouseDown="onMouseDown(event)"
>
<s:layout>
<s:HorizontalLayout/>
</s:layout>
</s:List>
<s:HGroup gap="20">
<s:Group>
<s:Image id="planImage" width="500" height="300" horizontalCenter="0"
toolTip="Drag your items on your Plan and drop them were you plan to install them"
/>
<mx:Canvas width="500" height="300" backgroundAlpha="0.1"
backgroundColor="#abcdef" borderColor="#abcdef" borderStyle="inset"
contentBackgroundColor="#abcdef" cornerRadius="10"
dragDrop="canvas1_dragDropHandler(event)"
dragEnter="canvas1_dragEnterHandler(event)" dropShadowVisible="true"
horizontalCenter="0"/>
</s:Group>
<s:List id="cart" width="200" height="300"/>
</s:HGroup>
I 'm thinking you need add drag initiator should be the item renderer that you are dragging rather than the entire List control.
Not list.selectedItem that simple object that is not like UIComponent or VisualElement you have to point some ui component like group.