6 Replies Latest reply on Jul 23, 2010 12:44 AM by domifa200000

    Putting ANYTHING dynamically in mx:List

    domifa20000

      Hi!

       

      I have been struggling with this for hours and hours and would very much like some help.

       

      I have a list which I wish to populate with a bunch of different classes (RichTextEditor, Label, etc.) which the users drag-and-drops onto the list.

       

       

       <mx:List dropEnabled="true"
           dragEnabled="true" 
            dragMoveEnabled="true" 
            id="eqlist" width="100%" 
            dataProvider="{aData}"
            dragEnter="dragEnterHandler(event);"
            dragOver="dragOverHandler(event);"
            dragDrop="dragDropHandler(event);"
            dragExit="dragExitHandler(event);" >
                      <mx:itemRenderer>
                              <mx:Component>        
                              <customManagement:DocumentListItem json="{data.json}" creationComplete="this.refresh()" />
                              </mx:Component>
                      </mx:itemRenderer>
              </mx:List>
      

      So this is the MXML code i started with. aData is a simple ArrayCollection and DocumentListItem is a canvas wich adds different items to itself upon running "refresh()". It knows which type of item to add depending on the json which comes from the dataprovider.

       

      But this does not work very well. When I remove something from aData and add something else, the old object appears again in the list. Also if I remove the creationComplete event, only empty canvases are shown in the list (since refresh is the method which populates them using addChild).

       

      Really, I need some input here. Am I approaching this the wrong way?

       

       

      Summary: I get JSON objects which corresponds to different Flex components. I wish to add the components to a List dynamically in runtime. Also there must be a way to remove them from the list.

       

      Any help is much appreciated!

        • 1. Re: Putting ANYTHING dynamically in mx:List
          UbuntuPenguin Level 4

          Can you post the source code of your itemrenderer.  Usually when an itemrenderer is not refreshing , it is due to the set data function not being implemented properly.

           

          Sincerely ,

            Ubu

          • 2. Re: Putting ANYTHING dynamically in mx:List
            domifa200000

            The itemRenderer is a standard itemRenderer. So it HAS to be overridden?

            • 3. Re: Putting ANYTHING dynamically in mx:List
              UbuntuPenguin Level 4

              If you were using a standard itemerenderer you wouldn't be having these problems.  The fact you are using the flash lifecycle stuff in an itemrenderer is kind of odd.

              • 4. Re: Putting ANYTHING dynamically in mx:List
                domifa200000 Level 1

                What do you mean by lifecycle stuff?

                 

                You can't remove itemRenderer nor Component from the List because then you get "Multiple initializers for property 'dataProvider'."

                I really appreciate your attempts to help but I still don't get it!

                • 5. Re: Putting ANYTHING dynamically in mx:List
                  jsd99 Level 3

                  Change

                   

                   <mx:itemRenderer>
                                          <mx:Component>       
                                          <customManagement:DocumentListItem json="{data.json}" creationComplete="this.refresh()" />
                                          </mx:Component>
                                  </mx:itemRenderer>

                   

                  to itemRenderer="customManagement.documentListItem" (or whatever the class of your itemRenderer is)

                   

                  you can add the creationComplete event in the renderer itself if you need it.

                  • 6. Re: Putting ANYTHING dynamically in mx:List
                    domifa200000 Level 1

                    OK, I did it but it does not change the behaviour. Also I tried changing it to a DataGrid but no success.

                     

                    <mx:DataGrid height="600" variableRowHeight="true" dropEnabled="true"
                         dragEnabled="true" 
                          dragMoveEnabled="true" 
                          id="eqlist" width="100%" 
                          dataProvider="{aData}"
                          dragEnter="dragEnterHandler(event);"
                          dragOver="dragOverHandler(event);"
                          dragDrop="dragDropHandler(event);"
                          dragExit="dragExitHandler(event);" >
                      <mx:columns>
                            <mx:DataGridColumn headerText="Name" width="400" itemRenderer="DocumentListItem"/>
                      </mx:columns>
                    </mx:DataGrid>
                    

                     

                     

                    Here are all the drop handlers

                                private function dragOverHandler(event:DragEvent):void {
                                        event.preventDefault();
                                        eqlist.showDropFeedback(event);              
                                }
                                
                                private function dragDropHandler(event:DragEvent):void {                 
                                     eqlist.hideDropFeedback(event);              
                                        var index:int = eqlist.calculateDropIndex(event);
                                        if (event.dragSource.hasFormat("jsonobj")){
                                             var obj:DocumentListItem = new DocumentListItem();
                                             obj.json = event.dragSource.dataForFormat("jsonobj");
                                             aData.addItemAt(obj, index);
                                             aData.refresh();
                                             return;
                                        }
                                    dragExitHandler(event);
                                }            
                    
                         private function dragExitHandler(event:DragEvent):void {
                              event.currentTarget.setStyle('borderColor', tempBorderColor);
                              borderColorSet = true;
                            }
                    
                         public function dragEnterHandler(event:DragEvent):void {
                              event.preventDefault();
                              DragManager.acceptDragDrop(event.target as UIComponent);
                              eqlist.showDropFeedback(event);                    
                         }
                         
                         public function beginNewFieldDrag( mouseEvent:MouseEvent ):void {
                                   
                         // the drag initiator is the object being dragged (target of the mouse event)
                              var dragInitiator:IUIComponent = mouseEvent.currentTarget as IUIComponent;
                                        
                              // the drag source contains data about what's being dragged
                              var dragSource:DragSource = new DragSource();
                              
                              //dragSource.addData("Red", "color" );
                              eqlist.invalidateDisplayList();
                              eqlist.validateNow();
                              eqlist.validateProperties();
                                             
                              var jsonobj:Object = new Object();
                              if((dragInitiator as Button).id == "addText"){
                                   jsonobj["att_type"] = "text";
                              }
                              dragSource.addData(jsonobj,"jsonobj");
                              
                              // ask the DragManger to begin the drag
                              DragManager.doDrag( dragInitiator, dragSource, mouseEvent, null );
                                        
                         }
                    

                     

                     

                    beginNewFieldDrag is called when dragging in a button (which should spawn a new DocumentListItem containing a RTE).

                    <mx:Button id="addText" label="Add Text" />
                    ...
                    // and on initialize:
                    this.addText.addEventListener( MouseEvent.MOUSE_DOWN, beginNewFieldDrag );
                    

                     

                     

                    Here is the code for DocumentListItem (which I guess is my itemRenderer)

                     

                    <?xml version="1.0" encoding="utf-8"?>
                    <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="350" verticalScrollPolicy="off" horizontalScrollPolicy="off">
                         <mx:Script>
                              <![CDATA[
                                   import mx.collections.ArrayCollection;
                                   import mx.controls.List;
                                   import mx.controls.Alert;
                                   import mx.controls.Button;
                                   import mx.controls.RichTextEditor;
                                   import mx.events.CloseEvent;
                                   import flash.display.DisplayObject;
                                   
                                   [Bindable]
                                   public var _data:Object;
                                   [Bindable]
                                   public var json:Object;
                                   [Bindable]
                                   public var is_initialized:Boolean = false;
                                   
                                   public function refresh():void{
                                        try{
                                             if (is_initialized) {
                                                  return;
                                             }
                                             if (json == null){
                                                  return;
                                             }
                                             if (json['att_type'] == "text") {
                                                  addFreeTextEditor();
                                             }          
                                             //is_initialized = true;
                                        } catch(e:Error){
                                             // well this sucked
                                        }
                                        
                                   }
                                   public function addFreeTextEditor():void {
                                        var editor:RichTextEditor = new RichTextEditor();
                                        editor.title = json['att_title'];
                                        editor.height = this.height;
                                        editor.width = this.width * 0.9;
                                        editor.text = json['att_value'];
                                        this.addChild(editor);
                                        this.invalidateDisplayList();
                                        this.validateNow();
                                   }
                                   
                                   protected function button1_clickHandler(evt:MouseEvent):void {
                                    Alert.show(data.label,
                                            "Are you sure you want to delete this item?",
                                            Alert.YES|Alert.CANCEL,
                                            null,
                                            alrt_closeHandler);
                                }
                     
                                protected function alrt_closeHandler(evt:CloseEvent):void {
                                    switch (evt.detail) {
                                        case Alert.YES:
                                        case Alert.OK:              
                                             Object(owner).dataProvider.removeItemAt(Object(owner).dataProvider.getItemIndex(data));                   
                                                    Object(owner).dataProvider.refresh();
                                            break;
                                        case Alert.CANCEL:
                                        case Alert.NO:
                                            break;
                                        default:
                                            break;
                                    }
                                }
                    
                                override public function set data(value:Object):void
                                {
                                     this.removeAllChildren();
                                     super.data = value;
                                     this.json = value.json;                 
                                     this.refresh();            
                                }
                                   
                              ]]>
                         </mx:Script><!--
                        <mx:Button id="btn"
                                   emphasized="true"
                                   width="20" height="20"
                                   paddingBottom="0"
                                   paddingLeft="0"
                                   paddingTop="0"
                                   paddingRight="0"
                                   x="{this.width - 30}"
                                   y="{this.height/2}"
                                   label="X"
                                   mouseDown="button1_clickHandler(event);" />-->
                    
                    </mx:Canvas>
                    
                     
                    

                     

                    Sooo, if I feed it with an object containing att_type = text, I would like to append a RTE to the canvas. When this works, I'd like to provide different types; Label for example.

                     

                    Now, dragging in new RTEs and removing them work BUT moving them around does not. They get cleared when dragging them inside the DataGrid (previously known as List). How can I prevent the data from being erased?