21 Replies Latest reply on Dec 9, 2011 12:11 PM by Code Girl

    List ComboBox ItemEditor

    Michelle5002 Level 1

      I was told to use a list control instead of a datagrid when there is only one object in my dataprovider list and only one column is needed even though that object is a complex object.  In the datagrid the item editor wanted to return the value to a datafield and since there was no datafield it was giving me troubles.  Now I am trying to implement this in a list.  However, FB is giving me a hard time with the ItemEditor and when I search on how to implement an Item Editor I find lots of examples on Datagrids and if there is an example of one with a list they reference the editor but never give the code on how it was implemented.  So, would someone please provide an example on how to implement an Item Editor for a spark List.

        • 1. Re: List ComboBox ItemEditor
          Claudiu Ursica Level 4

          Can you share some code?

          C

          • 2. Re: List ComboBox ItemEditor
            Code Girl Level 1

            This compiles but the combo box does not come up

             

            {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"

            xmlns:vo="valueObjects.*"

            width="464" height="100%">

            <fx:Script>

            <![CDATA[

            import mx.collections.ArrayCollection;

            import mx.events.FlexEvent;

             

            protected function aCBLabel(item:Object):String

            {

            if (item != null)

            return item.name;

            else

            return "";

            }

             

            protected function bL_creationCompleteHandler(event:FlexEvent):void

            {

            bL.selectedIndex = 0;

            }

             

            ]]>

            </fx:Script>

            <fx:Declarations>

            <vo:ADto id="aDto"/>

            <vo:BDto id="bDto"/>

            <s:ArrayCollection id="aList">

            <vo:ADto>

            <vo:id>1</vo:id>

            <vo:name>a1</vo:name>

            <vo:bs>

            <vo:BDto>

            <vo:id>1</vo:id>

            <vo:name>b1</vo:name>

            </vo:BDto>

            <vo:BDto>

            <vo:id>2</vo:id>

            <vo:name>b2</vo:name>

            </vo:BDto>

            <vo:BDto>

            <vo:id>0</vo:id>

            <vo:name></vo:name>

            </vo:BDto>

            </vo:bs>

            </vo:ADto>

            <vo:ADto>

            <vo:id>2</vo:id>

            <vo:name>a2</vo:name>

            <vo:bs>

            <vo:BDto>

            <vo:id>3</vo:id>

            <vo:name>b3</vo:name>

            </vo:BDto>

            <vo:BDto>

            <vo:id>0</vo:id>

            <vo:name></vo:name>

            </vo:BDto>

            </vo:bs>

            </vo:ADto>

            </s:ArrayCollection>

            <s:ArrayCollection id="bList">

            <vo:BDto>

            <vo:id>1</vo:id>

            <vo:name>b1</vo:name>

            </vo:BDto>

            <vo:BDto>

            <vo:id>2</vo:id>

            <vo:name>b2</vo:name>

            </vo:BDto>

            <vo:BDto>

            <vo:id>3</vo:id>

            <vo:name>b3</vo:name>

            </vo:BDto>

            </s:ArrayCollection>

            </fx:Declarations>

            <fx:Binding source="aCB.selectedItem as ADto" destination="aDto"/>

            <s:Form id="AForm" x="0" y="2" width="700" height="46">

            <s:layout>

            <s:BasicLayout/>

            </s:layout>

            <s:HGroup x="0" y="1" width="670" height="28">

            <s:Label height="25" fontWeight="bold" text="Find an A" verticalAlign="middle"/>

            <s:ComboBox id='aCB'

            prompt="Enter or Select an A Name"

            labelFunction="aCBLabel"

            x="110" y="10" width="375">

            <mx:ArrayCollection id="asList" list="{aList}"/>

            </s:ComboBox>

            </s:HGroup>

            </s:Form>

            <s:Label x="10" y="56" fontWeight="bold" text="List of B's"/>

            <mx:List id="bL" x="68" y="66" width="370" height="151"

            labelField="name"

            creationComplete="bL_creationCompleteHandler(event)"

            dataProvider="{aDto.bs}">

            <mx:itemEditor>

            <fx:Component>

            <mx:Canvas implements="mx.managers.IFocusManagerComponent">

            <fx:Script>

            <![CDATA[

            import mx.collections.ArrayCollection;

            import mx.controls.dataGridClasses.DataGridListData;

            import mx.controls.listClasses.BaseListData;

            import mx.events.FlexEvent;

             

            import spark.events.DropDownEvent;

            import spark.events.IndexChangeEvent;

             

            [Bindable]

            public var bs:ArrayCollection;

             

            override public function setFocus():void

            {

            cb.setFocus();

            }

             

            protected function cb_InitializeHandler(event:FlexEvent):void

            {

            bs = outerDocument.bList;

            bDto = outerDocument.bL.selectedItem as BDto;

            if (bDto != null)

            {

            var t:BDto;

            for (var i:int = 0; i<bs.length; i++)

            {

            t = bs[i];

            if (bDto.id == t.id)

            {

            cb.selectedIndex = i;

            break;

            }

            }

            }

            }

             

            public function get value():BDto

            {

            if (cb.isDropDownOpen)

            cb.closeDropDown(true);

            cb.validateNow();

            bDto = new BDto();

            if (cb.selectedIndex > -1)

            bDto = cb.selectedItem as BDto;

            outerDocument.aDto.bs[outerDocument.bL.selectedIndex] = bDto;

            return bDto

            }

             

             

            protected function cb_closeHandler(event:DropDownEvent):void

            {

            bDto = new BDto();

            if (cb.selectedIndex > -1)

            bDto = cb.selectedItem as BDto;

            outerDocument.aDto.bs[outerDocument.bL.selectedIndex] = bDto;

            }

             

            protected function cb_creationCompleteHandler(event:FlexEvent):void

            {

            cb.setFocus();

            }

             

            ]]>

            </fx:Script>

            <fx:Declarations>

            <vo:BDto id="bDto"/>

            <!-- Place non-visual elements (e.g., services, value objects) here -->

            </fx:Declarations>

            <s:ComboBox id="cb"

            width = "100%"

            prompt="{bDto.name}"

            dataProvider="{bs}"

            labelField="name"

            initialize="cb_InitializeHandler(event)"

            creationComplete="cb_creationCompleteHandler(event)"

            close="cb_closeHandler(event)">

            </s:ComboBox>

            </mx:Canvas>

            </fx:Component>

            </mx:itemEditor>

            </mx:List>

            </s:Application>

            {Code}

             

             

            {Code}

             

             

            package valueObjects

            {

            import com.adobe.fiber.services.IFiberManagingService;

            import com.adobe.fiber.valueobjects.IValueObject;

            import mx.collections.ArrayCollection;

            import valueObjects.BDto;

            import com.adobe.fiber.core.model_internal;

             

            use namespace model_internal;

             

            public class ADto implements com.adobe.fiber.valueobjects.IValueObject

            {

            private var _internal_id : int;

            private var _internal_name : String;

            private var _internal_bs : ArrayCollection;

            model_internal var _internal_bs_leaf:valueObjects.BDto;

             

            public function ADto()

            {

            }

             

            public function get id() : int

            {

            return _internal_id;

            }

             

            public function get name() : String

            {

            return _internal_name;

            }

             

            public function get bs() : ArrayCollection

            {

            return _internal_bs;

            }

             

            public function set id(value:int) : void

            {

            var oldValue:int = _internal_id;

            if (oldValue !== value)

            {

            _internal_id = value;

            }

            }

             

            public function set name(value:String) : void

            {

            var oldValue:String = _internal_name;

            if (oldValue !== value)

            {

            _internal_name = value;

            }

            }

             

            public function set bs(value:*) : void

            {

            var oldValue:ArrayCollection = _internal_bs;

            if (oldValue !== value)

            {

            if (value is ArrayCollection)

            {

            _internal_bs = value;

            }

            else if (value is Array)

            {

            _internal_bs = new ArrayCollection(value);

            }

            else if (value == null)

            {

            _internal_bs = null;

            }

            else

            {

            throw new Error("value of bs must be a collection");

            }

            }

            }

             

            private var _managingService:com.adobe.fiber.services.IFiberManagingService;

             

            public function set managingService(managingService:com.adobe.fiber.services.IFiberManagingService):void

            {

            _managingService = managingService;

            }

            }

            }

            {Code}

             

             

            {Code}

             

            package valueObjects

            {

            import com.adobe.fiber.services.IFiberManagingService;

            import com.adobe.fiber.valueobjects.IValueObject;

            import mx.collections.ArrayCollection;

            import com.adobe.fiber.core.model_internal;

            use namespace model_internal;

            public class BDto implements com.adobe.fiber.valueobjects.IValueObject

            {

            private var _internal_id : int;

            private var _internal_name : String;

            private static var emptyArray:Array = new Array();

            public function BDto()

            {

            }

            public function get id() : int

            {

            return _internal_id;

            }

            public function get name() : String

            {

            return _internal_name;

            }

            public function set id(value:int) : void

            {

            var oldValue:int = _internal_id;

            if (oldValue !== value)

            {

            _internal_id = value;

            }

            }

            public function set name(value:String) : void

            {

            var oldValue:String = _internal_name;

            if (oldValue !== value)

            {

            _internal_name = value;

            }

            }

            private var _managingService:com.adobe.fiber.services.IFiberManagingService;

            public function set managingService(managingService:com.adobe.fiber.services.IFiberManagingService):void

            {

            _managingService = managingService;

            }

            }

            }

             

            {Code}

            • 3. Re: List ComboBox ItemEditor
              Code Girl Level 1

              oh, Michelle5002 is my home login and CodeGirl is my work login

              • 4. Re: List ComboBox ItemEditor
                Flex harUI Adobe Employee

                Looks like you didn’t set editable=true on the List?

                • 5. Re: List ComboBox ItemEditor
                  Code Girl Level 1

                  Once I set Editable to true the combo box came up but when I entered b3 and pressed enter I got a

                  ReferenceError: Error #1069: Property text not found on ABsInnerClass0 and there is no default value.

                               at mx.controls::List/itemEditorItemEditEndHandler()[E:\dev\4.5.1\frameworks\projects\mx\src\ mx\controls\List.as:2821]

                  • 6. Re: List ComboBox ItemEditor
                    Code Girl Level 1

                    Turns out i also forgot the Editor Data Field.  Maybe its time to go back and remember some of the little things I learned when I first started Learning flex that I have forgotten now.

                    • 7. Re: List ComboBox ItemEditor
                      Flex harUI Adobe Employee

                      It looks like you have multiple threads open on this subject.  I’m going to let the others die since I think this one has the most promise.

                       

                      I got the TAB working.  I’m not sure you want to use ComboBox and have deleting the text imply “null”.  Might be best to have an entry properly labeled as null and use DropDownList instead.  I updated your example to use itemEditEnd as it is the recommended practice

                       

                      <?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"
                                     xmlns:vo="valueObjects.*"
                                     width="464" height="100%">
                         <fx:Script>
                             <![CDATA[
                                  import mx.collections.ArrayCollection;
                                  import mx.events.FlexEvent;
                                  import mx.events.ListEvent;
                      
                                  protected function aCBLabel(item:Object):String
                                  {
                                      if (item != null)
                                          return item.name;
                                      else
                                         return "";
                                  }
                      
                                  protected function bL_creationCompleteHandler(event:FlexEvent):void
                                 {
                                      bL.selectedIndex = 0;
                                  }
                      
                                  private function saveData(event:ListEvent):void
                                 {
                                      var value:BDto = bL.itemEditorInstance["value"];
                                      bL.dataProvider[bL.selectedIndex] = value;
                                      trace(value);
                                      bL.destroyItemEditor();
                                      event.preventDefault();
                                  }
                      
                              \]\]\>
                          </fx:Script>
                         <fx:Declarations>
                             <vo:ADto id="aDto"></vo:ADto>
                             <vo:BDto id="bDto"></vo:BDto>
                             <s:ArrayCollection id="aList">
                                 <vo:ADto>
                                     <vo:id>1</vo:id>
                                     <vo:name>a1</vo:name>
                                     <vo:bs>
                                         <vo:BDto>
                                             <vo:id>1</vo:id>
                                             <vo:name>b1</vo:name>
                                         </vo:BDto>
                                         <vo:BDto>
                                             <vo:id>2</vo:id>
                                             <vo:name>b2</vo:name>
                                         </vo:BDto>
                                         <vo:BDto>
                                             <vo:id>0</vo:id>
                                             <vo:name></vo:name>
                                         </vo:BDto>
                                     </vo:bs>
                                 </vo:ADto>
                                 <vo:ADto>
                                     <vo:id>2</vo:id>
                                     <vo:name>a2</vo:name>
                                     <vo:bs>
                                         <vo:BDto>
                                             <vo:id>3</vo:id>
                                             <vo:name>b3</vo:name>
                                         </vo:BDto>
                                         <vo:BDto>
                                             <vo:id>0</vo:id>
                                             <vo:name></vo:name>
                                         </vo:BDto>
                                     </vo:bs>
                                 </vo:ADto>
                             </s:ArrayCollection>
                             <s:ArrayCollection id="bList">
                                 <vo:BDto>
                                     <vo:id>1</vo:id>
                                     <vo:name>b1</vo:name>
                                 </vo:BDto>
                                 <vo:BDto>
                                     <vo:id>2</vo:id>
                                     <vo:name>b2</vo:name>
                                 </vo:BDto>
                                 <vo:BDto>
                                     <vo:id>3</vo:id>
                                     <vo:name>b3</vo:name>
                                 </vo:BDto>
                             </s:ArrayCollection>
                         </fx:Declarations>
                         <fx:Binding source="aCB.selectedItem as ADto" destination="aDto"></fx:Binding>
                         <s:Form id="AForm" x="0" y="2" width="700" height="46">
                             <s:layout>
                                 <s:BasicLayout></s:BasicLayout>
                             </s:layout>
                             <s:HGroup x="0" y="1" width="670" height="28">
                                 <s:Label height="25" fontWeight="bold" text="Find an A" verticalAlign="middle"></s:Label>
                                 <s:ComboBox id='aCB'
                                              prompt="Enter or Select an A Name"
                                              labelFunction="aCBLabel"
                                              x="110" y="10" width="375">
                                     <mx:ArrayCollection id="asList" list="{aList}"></mx:ArrayCollection>
                                 </s:ComboBox>
                             </s:HGroup>
                         </s:Form>
                         <s:Label x="10" y="56" fontWeight="bold" text="List of B's"></s:Label>
                         <mx:List id="bL" x="68" y="66" width="370" height="151"
                                   labelField="name" editable="true"
                                   itemEditEnd="saveData(event)"
                                   keyFocusChange="bL.enabled=false;bL.enabled=true"
                                   creationComplete="bL_creationCompleteHandler(event)"
                                   dataProvider="{aDto.bs}">
                             <mx:itemEditor>
                                 <fx:Component>
                                     <mx:Canvas implements="mx.managers.IFocusManagerComponent">
                                         <fx:Script>
                                             <![CDATA[
                                                  import mx.collections.ArrayCollection;
                                                  import mx.controls.dataGridClasses.DataGridListData;
                                                  import mx.controls.listClasses.BaseListData;
                                                  import mx.events.FlexEvent;
                      
                                                  import spark.events.DropDownEvent;
                                                  import spark.events.IndexChangeEvent;
                      
                                                  [Bindable]
                                                  public var bs:ArrayCollection;
                      
                                                  override public function setFocus():void
                                                 {
                                                      cb.setFocus();
                                                  }
                      
                                                  protected function cb_InitializeHandler(event:FlexEvent):void
                                                 {
                                                      bs = outerDocument.bList;
                                                      bDto = outerDocument.bL.selectedItem as BDto;
                                                      if (bDto != null)
                                                      {
                                                          var t:BDto;
                                                          for (var i:int = 0; i<bs.length; i++)
                                                          {
                                                              t = bs[i];
                                                              if (bDto.id == t.id)
                                                              {
                                                                  cb.selectedIndex = i;
                                                                  break;
                                                              }
                                                          }
                                                      }
                                                  }
                      
                                                  public function get value():BDto
                                                  {
                                                      if (cb.isDropDownOpen)
                                                          cb.closeDropDown(true);
                                                      cb.validateNow();
                                                      bDto = new BDto();
                                                      if (cb.selectedIndex > -1)
                                                          bDto = cb.selectedItem as BDto;
                                                      return bDto
                                                  }
                      
                                                  protected function cb_creationCompleteHandler(event:FlexEvent):void
                                                 {
                                                      cb.setFocus();
                                                  }
                      
                                              \]\]\>
                                          </fx:Script>
                                         <fx:Declarations>
                                             <vo:BDto id="bDto"></vo:BDto>
                                             <!-- Place non-visual elements (e.g., services, value objects) here -->
                                         </fx:Declarations>
                                         <s:ComboBox id="cb"
                                                      width = "100%"
                                                      prompt="{bDto.name}"
                                                      dataProvider="{bs}"
                                                      labelField="name"
                                                      initialize="cb_InitializeHandler(event)"
                                                      creationComplete="cb_creationCompleteHandler(event)"
                                                      >
                                         </s:ComboBox>
                                     </mx:Canvas>
                                 </fx:Component>
                             </mx:itemEditor>
                         </mx:List>
                      </s:Application>
                      
                      

                       

                      1 person found this helpful
                      • 8. Re: List ComboBox ItemEditor
                        Code Girl Level 1

                        No, I like the combobox so I can do a typed search.  Dropdown lists only allows first character search

                        • 9. Re: List ComboBox ItemEditor
                          Code Girl Level 1

                          and this is not the thread with the tab issue

                          The tab issues is with a multi-column datagrid

                          • 10. Re: List ComboBox ItemEditor
                            Flex harUI Adobe Employee

                            I found what appeared to be the same Tab issue on the List.  Do you really plan to have all three configurations in your app (List, one-column DG, multi-columnDG)?  Otherwise, choose one and we’ll try to get things working.

                            • 11. Re: List ComboBox ItemEditor
                              Michelle5002 Level 1

                              Believe it or not but I will be using the first combo box to select which app the SQL tables belong to.  Then there will be a list to display the list of tables which are assosiated with that app.  Then there will be a Datagrid which is associated with the table in the list which displays the lookup tables, link tables, extended tables, and children tables and will display what the field are that link them.  The app will be used to help create queries my customer ask me to do to get data for them or create reports for them.  The Database has several hundred tables because the programmers of the apps normalized the tables to death and some tables are not so obvious and they didnt do the dependancies.  So my app will make all the connections to make my job easier.  It also shows the programmers on the main app how good my app is and maybe there is a better way than the way they do things.  Besides, I like Java much better than ASP.NET anyways.

                              • 12. Re: List ComboBox ItemEditor
                                Flex harUI Adobe Employee

                                OK.  If you apply the principles of the code I posted to your other examples, what problems remain?

                                • 13. Re: List ComboBox ItemEditor
                                  Code Girl Level 1

                                  This did not fix the tab issue I was having.  Maybe you should look at the thread I started which you have not yet responded to.  The subject is Tab not working properly for Datagrid ItemEditor ComboBox and was created on Dec 7th at 11:57AM

                                   

                                  Also, I noticed even in the List we cant seem to post the single object data without violating encapsulation rules.  Same problem I was having with the Data Grid.

                                  • 14. Re: List ComboBox ItemEditor
                                    Flex harUI Adobe Employee

                                    I see.  The ComboBox is not opening and goes down a different path.  I was able to see this in the List as well.  I got around it by subclassing ComboBox and adding this:

                                     

                                                            override protected function textInput_changeHandler(event:TextOperationEvent):void
                                                           {
                                                                if (textInput.text == "")
                                                                    event.operation = null;
                                    
                                                                super.textInput_changeHandler(event);
                                                            }
                                    

                                     

                                    1 person found this helpful
                                    • 15. Re: List ComboBox ItemEditor
                                      Code Girl Level 1

                                      Funny, I also came up with a fix too.  You are right, when the tab key is hit, the selection is not changed so I solved it by adding in the value function if (cb.textInput.text == "")  cb.selectedIndex = -1;  This updated the selection and worked.

                                      • 16. Re: List ComboBox ItemEditor
                                        Code Girl Level 1

                                        What do you think about the solution presented in this article

                                         

                                        http://www.adobe.com/devnet/flash/articles/detecting_datagrid_edits.html

                                        • 17. Re: List ComboBox ItemEditor
                                          Flex harUI Adobe Employee

                                          Well, this is about the Flash components, not the Flex ones, but they borrowed enough of our code that it probably applies.

                                           

                                          However, in Flex the new value is available in itemEditorInstance[column.editorDataField] so you shouldn’t need to wire up two itemEditEnd handlers.  In the code I posted, I show how to use only one itemEditEnd handler and if you want to test for changes, you can do it in the saveData method.

                                           

                                          If the Flash components also have itemEditorInstance and editorDataField, then the author missed an easier way to do what he wanted.  He was looking for a newValue/oldValue in the event, which might be a good thing to add someday.

                                          • 18. Re: List ComboBox ItemEditor
                                            Code Girl Level 1

                                            The itemeditorend function worked great for the list but for some reason it didn’t work well for my Single Column Datagrid.  In the Datagrid version, it is running the get Value function but the combo box is no longer in context and all combo box references fail.  Which then led me to wonder why this was different in the list because the list is using combo box references in its get value function.  I suspect in the list, the value is ran earlier and stored and so when the itemeditorend function calls for value it just gets the stored value.  Where as and I am guessing, in the datagrid, the function has not been called yet and so when the itemeditorend calls the get value  it fires the function which the combobox is no longer in context.  Do you agree or not?

                                            • 19. Re: List ComboBox ItemEditor
                                              Flex harUI Adobe Employee

                                              I went back to the single column DG example.  I didn’t see any ComboBox access issues, but I did see an infinite loop which I worked around like this:

                                               

                                                          private var inEndEdit:Boolean = false;
                                              
                                                          private function saveData(event:DataGridEvent):void
                                                         {
                                                              if (!inEndEdit)
                                                              {
                                                                  inEndEdit = true;
                                                                  var value:BDto = bDG.itemEditorInstance["value"];
                                                                  bDG.dataProvider[bDG.selectedIndex] = value;
                                                                  trace(value);
                                                                  bDG.destroyItemEditor();
                                                                  inEndEdit = false;
                                                              }
                                                              event.preventDefault();
                                                          }
                                              

                                               

                                              • 20. Re: List ComboBox ItemEditor
                                                Code Girl Level 1

                                                If you remove the reference to outer document in value and close handler then you will.  Also, you might delete the creation complete function too.  These were work arounds.  What infinite loop?  I didn’t know I had one.  How and where?

                                                • 21. Re: List ComboBox ItemEditor
                                                  Code Girl Level 1

                                                  Oh, the value thing was in an infinite loop.  This worked.

                                                   

                                                  Thank you for taking the time to work with me on this.  I actually think we have the combo box working as an item editor now.  Thank You