1 Reply Latest reply on Feb 20, 2011 9:53 AM by Michael J Roberts

    Calling a function within a itemRenderer

    sadie9954

      This seems like it should be really simple but....

      I have a DataGroup with a custom itemRenderer.  The itemRenderer employes the usual States of normal and hovered, but also a custom State of "disabled".

      Drag and Drop is enabled on the DataGroup.  After the user Drags the item from the DataGroup and drops it on a DataGrid, I want the itemRenderer to be disabled so it cannot be dragged again, which simply means calling a function within the itemRenderer...

       

      ******************************Code**********************************

       

      <?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" width="625" height="540">
          <fx:Declarations>
             
          </fx:Declarations>
          <fx:Script>
              <![CDATA[
                  import components.RentalItemRenderer;
                 
                  import flash.events.MouseEvent;
                 
                  import mx.collections.ArrayCollection;
                  import mx.core.DragSource;
                  import mx.core.UIComponent;
                  import mx.events.DragEvent;
                  import mx.managers.DragManager;
                 
                  import spark.components.supportClasses.ItemRenderer;
                 
                  // Embed icon images for Spark BitmapImage.
                  [Embed(source='assets/First_Ten.png')]
                  public var Image01:Class;
                  [Embed(source='assets/HoopShot.png')]
                  public var Image02:Class;
                  [Embed(source='assets/DartGame.png')]
                  public var Image03:Class;
                  [Embed(source='assets/BigMouth.png')]
                  public var Image04:Class;
                  [Embed(source='assets/PrizeWheel.png')]
                  public var Image05:Class;
                  [Embed(source='assets/RingToss.png')]
                  public var Image06:Class;

       

                 
                  [Bindable]
                  private var rentalItems:ArrayCollection = new ArrayCollection([
                      {name:"First And Ten", price:"$20",available:"true", imageFile:Image01},
                      {name:"Hoop Shot", price:"$20",available:"true", imageFile:Image02},
                      {name:"Dart Game", price:"$20",available:"false", imageFile:Image03},
                      {name:"Big Mouth", price:"$20",available:"true", imageFile:Image04},
                      {name:"Prize Wheel", price:"$20",available:"true", imageFile:Image05},
                      {name:"Ring Toss", price:"$20",available:"true", imageFile:Image06}
                      ]);
                 
                 
                 
                  [Bindable]
                  private var reserveArray:ArrayCollection = new ArrayCollection();

       

                 
                  private function inititateDrag(event:MouseEvent):void{
                       if(event.target is ItemRenderer){
                          var source:DragSource = new DragSource();
                          var itemData:Object = event.target.data;
                          source.addData(itemData,"rentalItem");
                          DragManager.doDrag(event.target as UIComponent, source, event);
                      }
                  }

       

                  private function dragEnterHandler(event:DragEvent):void{
                      if(event.dragSource.hasFormat("rentalItem")){
                          var dropTarget:DataGrid = DataGrid(event.currentTarget);

                          DragManager.acceptDragDrop(dropTarget);
                      }
                  }

       

                  private function dragDropHandler(event:DragEvent):void{
                      var dragData:Object = event.dragSource.dataForFormat("rentalItem");               
                      var itemIndex:int = rentalItems.getItemIndex(dragData);
                      dragData.available = "false";
                      reserveArray.addItem(dragData);

                    //Call function in itemRenderer
                  }
                 
                 
              ]]>
          </fx:Script>
       
              <s:Panel width="100%" title="Drag you rental items to the right pane" top="215" height="318" right="5">
                  <s:HGroup width="100%" bottom="5" left="5" top="5" gap="1">
                      <s:DataGroup id="rentalDataGroup" dataProvider="{rentalItems}" itemRenderer="components.RentalItemRenderer"
                                   width="200" height="100%" clipAndEnableScrolling="true" mouseDown="inititateDrag(event);">
                          <s:layout>
                              <s:TileLayout horizontalGap="5" verticalGap="5"/>
                          </s:layout>
                      </s:DataGroup>   
                      <s:VScrollBar id="iconScrollBar" viewport="{rentalDataGroup}"
                                    height="{rentalDataGroup.height}"
                                    left="{rentalDataGroup.x + rentalDataGroup.width}"
                                    top="10"/>
                     
                     
                      <mx:DataGrid id="reviewGrid" width="100%" right="5" height="100%" dataProvider = "{reserveArray}"
                                   tabEnabled="false" dragEnter="dragEnterHandler(event)"
                                   dragDrop="dragDropHandler(event)">
                          <mx:columns>
                              <mx:DataGridColumn headerText="Item" dataField="name" width="300"/>
                              <mx:DataGridColumn headerText="Price" dataField="price"/>
                          </mx:columns>
                      </mx:DataGrid>
                  </s:HGroup>
              </s:Panel>
      </s:Application>

       

      <?xml version="1.0" encoding="utf-8"?>
      <s:ItemRenderer 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="96" height="134"
                      creationComplete="init();">

       

          <fx:Script>
              <![CDATA[
                  private function init():void{               
                      trace("init " + this);
                      if(data.available == "false"){
                          this.currentState = "disabled";
                          this.enabled = false;
                      }
                  }

       

                public function disable():void{               
                           this.currentState = "disabled";
                           this.enabled = false;
                   }

       

                 
              ]]>
          </fx:Script>
         
          <s:states>
              <s:State name = "normal"/>
              <s:State name = "hovered"/>
              <s:State name = "disabled"/>
          </s:states>

       

              <s:layout>
                  <s:BasicLayout/>
              </s:layout>
          <s:Rect width="96" height="134" x="0" y="0">
              <s:fill>
                  <s:SolidColor color.normal="#00569A" color.hovered="#BA181A"/>           
              </s:fill>
              <s:stroke>
                  <s:SolidColorStroke color="#000000" weight="1"/>
              </s:stroke>
          </s:Rect>
             
              <s:BitmapImage source="{data.imageFile}" width="92" height="114" alpha.disabled="0.6" x="3" y="2" fillMode="clip"/>
              <s:Label text="{data.price}" text.disabled="Unavailable" color="#FFFFFF" x="1" bottom="1" width="94"
                       textAlign="center"  fontWeight="bold"/>
             
      </s:ItemRenderer>

        • 1. Re: Calling a function within a itemRenderer
          Michael J Roberts

          I don't think you'll want to set the disabled state directly on the itemRenderer since the renderer may be resued for different data, if your datagrid ever scrolls. I think you'll want to tie the "available" attribute to your disable() method in your renderer. So, in your itemRenderer's init() method (or add a set data() method) you can put this:

           

          private var changeWatcher:ChangeWatcher;
          
          override public function set data(value:Object):void{
             super.data = value;
             if(changeWatcher != null){
               changeWatcher.unwatch();
               changeWatcher = null;
             }
             changeWatcher = BindingUtils.bindSetter(disable, data, 'available');
          }
          
          public function disable(available:Boolean):void{ 
             if(available == false){ 
               this.currentState = "disabled";
               this.enabled = false;
            }
          }
          

           

          This way when you set the attrbute "available" in the main part of the applicaton, the relevant itemRenderer will auto-update.  Also, to make sure your changes propagate to the itemRenderer, ensure you call refresh() on your dataProviders like so:

           

          private function dragDropHandler(event:DragEvent):void{
              var dragData:Object = event.dragSource.dataForFormat("rentalItem");                
              var itemIndex:int = rentalItems.getItemIndex(dragData);
              dragData.available = "false";
              reserveArray.addItem(dragData);
              reserveArray.refresh()
          }

           

          I hope this information helps!

           

          -Mike
          ramblingdeveloper.com