Blog

22Nov
2006
Flex ComboBox With selectedValue Support

One of the things I like most about ColdFusion's <CFSELECT> tag is the SELECTED attribute, give it a value and it figures out which one to pre-select. The Flex ComboBox allows you to set selectedIndex (the relative element position) but not selectedValue. Actually, ComboBox does have a selectedValue property, but that is used to read the value of the selected item, and can't be used to set the value of the item to be selected.

Coincidentally, while I was working on this, both Scott Stroz and Ray Camden posted solutions to the exact same problem. Scott's solution involved calling a method to set the value, and I really think that the selectedValue property should be used to be consistent with how ComboBox itself works. Ray's solution allows for a property to be set (he defined a new property for this), but his solution would not work for me as my dataProvider was being populated after the control had been created (it is being populated by a call to a CFC).

So, here is my solution. It's bit more complex than what Scott and Ray suggested, but it does support selectedValue, it'll also allow that property to be changed as needed (even after control creation), and it also properly handles delayed dataProvider population.

Here is the code:

view plain print about
1<?xml version="1.0" encoding="utf-8"?>
2<mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml">
3
4    <mx:Script>
5        <![CDATA[
6            private var _selectedValue:String;
7            private var bSelectedValueSet:Boolean = false;
8            private var bDataProviderSet:Boolean = false;
9
10            // Override committ, this may be called repeatedly
11

12            override protected function commitProperties():void
13            {
14                // invoke ComboBox version
15

16                super.commitProperties();
17
18                // If value set and have dataProvider
19

20                if (bSelectedValueSet && bDataProviderSet)
21                {
22                    // Set flag to false so code won't be called until selectedValue is set again
23

24                    bSelectedValueSet=false;
25                    // Loop through dataProvider
26

27                    for varr i:int=0;i<this.dataProvider.length;i++)
28                    {
29                        // Get this item's data
30

31                        var item:String = this.dataProvider[i].data;
32    
33                        // Check if is selectedValue
34

35                        if(item == _selectedValue)
36                        {
37                            // Yes, set selectedIndex
38

39                            this.selectedIndex = i;
40                            break;
41                        }
42                    }
43                }
44            }
45
46            // Trap dataProvider being set
47

48            override public function set dataProvider(o:Object):void
49            {
50                // invoke ComboBox version
51

52                super.dataProvider = o;
53
54                // This may get called before dataProvider is set, so make sure not null and has entries
55

56                if (o!=null && o.length)
57                {
58                    // Got it, set flag
59

60                    bDataProviderSet = true;
61                }
62            }
63
64            // set for selectedValue
65

66            public function set selectedValue(s:String):void
67            {
68                // Set flag
69

70                bSelectedValueSet = true;
71                // Save value
72

73                _selectedValue = s;
74                // Invalidate to force commit
75

76                invalidateProperties();
77            }
78        ]]>
79    </mx:Script>
80
81</mx:ComboBox>

And here is a simple test case:

view plain print about
1<?xml version="1.0" encoding="utf-8"?>
2<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:ns1="*">
3<mx:Script>
4    <![CDATA[
5        [Bindable]
6        private var comboData:Array=
7        [{label:"Item1", data:"1"},
8        {label:"Item2", data:"2"},
9        {label:"Item3", data:"3"}];
10    ]]>
11</mx:Script>
12<ns1:ComboBox2 dataProvider="{comboData}" selectedValue="3" />
13</mx:Application>

Related Blog Entries

Comments (57)



  • Scott Stroz

    Ben - I like this way much better as it does feel more like native properties in Flex.

  • Scott Stroz

    Ben - quick question. You mentioned that the dataProvider was being populated by a call to a CFC. If you set selectedValue before the dataprovider is populated with data from the CFC, I assume the correct value will still be selected. How is this happening? Is commitProperties called when the dataProvider is populated with data?

  • Ben Forta

    Scott, yes, I believe that that is the case.

    --- Ben

    #3Posted by Ben Forta | Nov 23, 2006, 01:11 PM
  • Scott Stroz

    Ben - Thanx! This opens up a lot of possibilities for other custom components.

  • Dirk Eismann

    Ben, maybe I'm missing the point here, but ComboBox (and a few others like List and DataGrid ) not only offers the selectedIndex property to select an item by using a numeric index but also a selectedItem property which selects an item from the dataProvider by passing in a reference.

    #5Posted by Dirk Eismann | Nov 28, 2006, 02:25 AM
  • Pete Capra

    Lifesaver! I had written some really convoluted, long-winded function to set my selectedIndex property. This is great. Thanks again..

    #6Posted by Pete Capra | Nov 29, 2006, 07:32 PM
  • Tristan Hauser

    Works only if your OBJECT has the property "value" ... I think. It would be great if the Combobox has a property, where you can select the valueField (like labelField)

  • Tristan Hauser

    I extended the ComboBox a little bit. You can now define the dataField (Default: data), so you can easily point to the right field.

    Here's the code:
    http://www.tristanhauser.com/flex/ExtendedComboBox...

  • Jack Freudenheim

    Thanks Ben! I'm new to flex, with a background in vb/access then java/swing then c#, and I expected combobox to do this out of the box, but your code works beautifully and gives me a look into how to extend components as well!

    #9Posted by Jack Freudenheim | Dec 5, 2006, 10:14 AM
  • Andrew

    Ben,

    I noticed in your example you used an Array with static data to set the combo box values. Would it be possible to show an example using mx:WebService?

    #10Posted by Andrew | Dec 10, 2006, 07:46 AM
  • Mitch Aunger

    Ben - thank you so much for this - i just saved a bunch of time trying to figure out how to set that selectedIndex. Just wanted you to know that this is working and we thank you!

    #11Posted by Mitch Aunger | Jan 5, 2007, 12:11 PM
  • wujian

    this is my solution:
    public function initCombobox(obj:Object):void{
                for(var i:int=0;i<obj.dataProvider.length;i++){
                   var selected:String = obj.dataProvider[i].selected;
                   
                   if(selected != null){
                      if(selected == "true"){
                         obj.selectedIndex = i;
                         break;
                      }
                   }
                }
             }

    <area>
    <item label="??" data="-1" />
    <item label="??" data="0570" />
    <item selected="true" label="??" data="0571" />
    <item label="??" data="0572" />
    <item label="??" data="0573" />
    <item label="??" data="0574" />
    <item label="??" data="0575" />
    <item label="??" data="0576" />
    <item label="??" data="0577" />
    <item label="??" data="0578" />
    <item label="??" data="0579" />
    <item label="??" data="0580" />
    </area>

    #12Posted by wujian | Jan 17, 2007, 01:33 AM
  • wujian

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"; layout="absolute">
       <mx:Script>
          <![CDATA[
             public function initCombobox(obj:Object):void{
                for(var i:int=0;i<obj.dataProvider.length;i++){
                   var selected:String = obj.dataProvider[i].selected;
                   
                   if(selected != null){
                      if(selected == "true"){
                         obj.selectedIndex = i;
                         break;
                      }
                   }
                }
             }
          ]]>
       </mx:Script>
       <mx:ArrayCollection id="ac">
          <mx:Array>
             <mx:Object label="A" data="1"/>      
             <mx:Object label="B" data="2"/>      
             <mx:Object label="C" data="3"/>      
             <mx:Object label="D" data="4"/>      
             <mx:Object label="E" data="5" selected="true"/>      
             <mx:Object label="F" data="1"/>      
             <mx:Object label="G" data="1"/>      
          </mx:Array>
       </mx:ArrayCollection>
       <mx:ComboBox id="testComb" dataProvider="{ac}" x="37" y="64"></mx:ComboBox>
       <mx:ComboBox id="testComb2" dataProvider="{ac}" creationComplete="initCombobox(testComb2)" x="37" y="94"></mx:ComboBox>
    </mx:Application>

    #13Posted by wujian | Jan 17, 2007, 01:51 AM
  • Tommy 10 Fingers

    Ben Forta you rock! I'm new to Flex and been having some adjustments coming from a pure Cold Fusion background. I was surprised to find the orginal Flex Combobox without a direct selectvalue property. I spent too much time trying to figure this out. I'm so glad you write this custom component....life saver.

    #14Posted by Tommy 10 Fingers | Feb 12, 2007, 08:20 PM
  • Neil

    A great help - the only thing I added was setting selectedIndex=-1 before the search - otherwise, if the data is not found it will show whatever the previously selected value was. This can happen when used with a database which has some incorrect or empty values, and if it shows the previous value it is not obvious there is a problem. With -1, the CB is blank, making it clear.

    #15Posted by Neil | Mar 19, 2007, 12:26 PM
  • GSuhr

    Thanks to wujian's post I was finally able to overcome this frustrating obstacle. However being a coldfusion /.net developer, it seems to me that this is something that should be built into the component. I'm just learning flex/as3 and finding I'm writing volumes of code to do the simplest mundane things. This is what makes ASP.NET so popular, the controls do all the heavy lifting and much of this grunt coding is built into the controls themselves. Flex is supposed to be an RIA langueage remember. Ben please pass my frustions and opinions on to the flex team. I DONT WANT TO WRITE CODE THAT SHOULD BE BUILT INTO A COMPONENT!
    Just my 2 cents. I feel better now. :-)

    #16Posted by GSuhr | Apr 27, 2007, 11:47 AM
  • Joe

    Ben (or anyone, for that matter!), not sure if this thread is still monitored or not but I have a question:

    I have duplicated this control - THANKS - by extending mx:List. Because this list is necessarily several thousand items long (everyone in our firm), I have added the following to the logic in order to show the highlighted dp item:

    ...
    this.selectedIndex = i;
    //added:
    this.verticalScrollPosition = i;
    ...

    It works great, except for the first time that it's called - the correct item is selected, but the verticalScrollPosition doesn't take effect. If you scroll down the list you can see that the correct item is selected - it just doesn't scroll down to that position. I'm assuming this is because the parent component hasn't been completely rendered yet (this is a Cairngorm app where selectedValue property is bound to a property of a value object in the modelLocator), but the creationComplete event is dispatched before the selectedValue setter is called so I'm at a loss. Each subsequent view of that screen correctly scrolls to the item in the list.

    Any advice on how to force this to scroll on the first call?

    Thanks in advance,
    Joe

    #17Posted by Joe | May 10, 2007, 01:03 PM
  • Leif

    (flex newbie here)

    thanks for this... but how do i 'bind' the selected index to a datagrid selection?
    ie, something like, ideally:
    <comp:ComboBox2 x="112" y="39" dataProvider="{rstClients}" selectedValue="<b>{surveyGrid.selectedItem.SCLIENTNAME}</b>" labelField="SCLIENTNAME" width="205" />

    compared to textinput controls' bindings, triggering combobox updates through datagrid's itemfocusin seems 'dirty'.

    #18Posted by Leif | Jun 2, 2007, 07:49 PM
  • James Schell

    I have slight twist on this, I have cfselect that gets its data from a cfdirectory tag. The cfselect provides the user with a list of xml file in a directory. After the user selects an xml file I need to read the values in the xml file and put them into text boxes on the flash form.

    I can get everything but cannot get the value of the selectedItem from the cfselect combo box.

    Any suggestions here as I know nothign about flex

    Thanks

    Jim

    #19Posted by James Schell | Jun 12, 2007, 10:05 PM
  • Elton

    This is a very delayed reply to Joe's query above.
    You could try this.scrollToIndex(i);

    #20Posted by Elton | Jul 6, 2007, 12:08 PM
  • Joe

    thanks Elton - Because of real estate limitations, I ended up switching back to the data aware combo box class.

    In theory these should be pretty darned identical in behavior, but I think what might have gotten it to work was setting the creationPolicy="all" attribute on the application.

    Not sure whether this was definitely the fix, but it sure did seem to help with a lot of other little gotcha's throughout the application and eliminated a bunch of null checking, etc.

    Just thought I would add this note to the thread incase it helps someone else.

    #21Posted by Joe | Jul 9, 2007, 04:38 PM
  • jaq

    I tried the this.scrollToIndex(i); It doesn't scroll to the right position and my datagrid shows empty rows when I scroll up and down with the mouse. And then they will appear after a while. Any suggestions?

    Jaqueline

    #22Posted by jaq | Jul 21, 2007, 01:26 AM
  • Matt Hart

    Hi,

    Another newbie to Flex here..

    I'm trying to Bind this to a selectedItem from a DataGrid to a Combo box please can someone tell me if this is possible with this Combobox as Flex does no support SelectedItem..

    I see you can use a static value in the SelectedValue and it works fine, but if you put a Dynamic Value in ie. selectedValue="{datagrid.selectedItem.column}" it doesn't seem to work..

    Any adive would be great..

    Matt

    #23Posted by Matt Hart | Jul 22, 2007, 06:11 PM
  • Liz

    Thank you. I had the same problem of the dataprovider not being populated at the time of the control creation. This is a very clean implementation.

    #24Posted by Liz | Sep 19, 2007, 12:28 PM
  • Tom

    I too am grateful to you Ben for posting this solution. I spent no less than 10 hours f'ing with a stupid ComboBox trying to get it to do something I could EASILY do in HTML, JSP, or JSF years ago! It's utterly amazing that Adobe has not provided an OOB solution for this common scenario.

    I'm new to Flex and recently committed to using it to develop a large portion of my small startup company's product, but this ComboBox nonsense is making me wonder if I made the right choice. How many more wasted days will I experience chasing solutions to problems that should be part of the OOB product.

    Thanks again Ben!

    Tom

    #25Posted by Tom | Sep 24, 2007, 07:31 PM
  • Derek

    Hi Ben,

    Thanks for this great extension to the ComboBox! Thanks mostly for commenting the code because I was having so much trouble getting this thing to work. It turned out I was setting the dataProvider with databinding, BEFORE I populated the dataProvider.

    Making the call to set dataProvider right after populating my label data object did the trick. I'm planning on always using this ComboBox.

    Question, why doesn't the Flex framework already define a selectedValue method for mx:ComboBox in the first place, does it have anything to do with data binding?

    thanks,

    Derek

    #26Posted by Derek | Sep 25, 2007, 12:48 AM
  • David

    Thanks so much. I was fortunate enough to do a quick search before I wasted too much time trying to find the "selectedValue" property. This has been a great help, and it is very much appreciated!

    #27Posted by David | Oct 16, 2007, 12:51 PM
  • George

    Tristan, great work! :-) This is what I really wanted!

    Let's hope that Adobe will add this into Flex 3 .... it's really not to have this very basic functionality in a combobox!

    thnx

    #28Posted by George | Oct 21, 2007, 05:37 PM
  • seo services

    I like this way much better as it does feel more like native properties in Flex.

  • Ryan Phelan

    Great post! My previous - less elegant solution was to use a helper function to convert the item to an index...

    public function findItemIndex( dp:IList, data:String ):int
    {
    for( var i:int = 0; i < dp.length; ++i )
    {
    if( dp.getItemAt(i).data == data )
    return i;
    }
    return -1;
    }

    &lt;mx:ComboBox dataProvider="{myDP}" selectedIndex="{findItemIndex(myDP, selectedItem) }" /&gt;

  • rimona

    This opens up a lot of possibilities for other custom components.

    #31Posted by rimona | Apr 26, 2008, 12:17 AM
  • Dylan

    Thanks Ben! This is amazing.

    In case anyone wants to make their comboBox default to the size of the DataProvider (it defaults to a drop down of only a few items and you have to scroll to the rest) then you can add code like this:

    <?xml version="1.0" encoding="utf-8"?>
    <mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml";
        rowCount="{myDataProvider.length}">

    #32Posted by Dylan | Jul 17, 2008, 11:30 AM
  • Mags

    Thanks Ben. Excellent post. Very much appreciated when people post really useful stuff like this.

    #33Posted by Mags | Jul 18, 2008, 09:34 AM
  • Mike Jones

    Thanks Ben! This helps!

  • Lu Sancea

    Don't forget that if the dataprovider is coming from a webservice to change
    var item:String = this.dataProvider[i].data; to
    var item:String = this.dataProvider[i].DATA;

    :)

    #35Posted by Lu Sancea | Aug 10, 2008, 04:28 PM
  • jesse

    You Rule! This saved me a lot of time.

    Thanks Ben.

    #36Posted by jesse | Aug 11, 2008, 11:52 PM
  • Ken boyd

    thanks is one word because coming from HTML, Java to flex this was eye opening that built in combobox has no simple properties like this..

    flex is open source that doesn't mean Adobe should leave to developer but basic properties are their responsibility. Anyways new comers like us face more problems because other part of world has all methods for doing simple work like selecting index where value = ?

    #37Posted by Ken boyd | Sep 2, 2008, 03:39 AM
  • Josh

    If your dataprovider is ever updated the selectedValue will be lost and the comboBox will reset itself to the first value in the list. You can fix this by changing the set dataProvider function and adding bSelectedValueSet = true as follows:

    if (o!=null && o.length)
    {
    // Got it, set flag
    bDataProviderSet = true;
    bSelectedValueSet = true;
    }

    #38Posted by Josh | Feb 3, 2009, 09:09 AM
  • Maggie

    Thanks so much for this post - it is still relevant! I am dealing with a Cairngorm application and have a header in one view, using this comboBox component. I have changed the selectedValue parameter to equal {modelLocator.workflowSate}.

    I have another view with the navigation that has tree component that offers a secondary option to change the workflowState. I am missing a step though, because if I click on a node in the tree, the view successfully changes, but the comboBox in the header view does not "automagically" adjust.

    How can I set the comboBox view to "listen" to see if the workflowSate has changed, and adjust accordingly? If it is too much to explain in the comments, if anyone could forward me to a relevant post, I would be very grateful! TIA!

    #39Posted by Maggie | Feb 6, 2009, 02:39 PM
  • Phillip Molaro

    Ben, thx for posting this. It works great. I was creating a new property on my object called "propIndex" and dynamically setting it when my "prop" property was being set by a setter. However, even though the propIndex was bindable, and the data was changing, the combobox didn't change. I switched to your combobox and set selectedValue = {prop} and it works great. THX!!

  • Leslie Bertels

    You could also override the combobox and create that method inside of it:

    package flex.components.util {

       import mx.collections.IList;
       import mx.controls.ComboBox;

       public class ComboBoxExt extends ComboBox {

          public function findItemIndex(data:String):int {
             var list:IList = IList(this.dataProvider);
             for (var i:int = 0; i<list.length; ++i) {
                if (list.getItemAt(i).data == data) return i;
             }
             
             return -1;
          }

       }
    }

    And you can call something like this in your script section

    myView.myCombo.selectedIndex = myView.myCombo.findItemIndex("somedata");

    Hope this sheds another light ;-)

    #41Posted by Leslie Bertels | Feb 20, 2009, 06:11 AM
  • George

    I dont get it. Im using this component NEXT to a datagrid. I select a row in the datagrid and the ComboBox changes how I want it to. But now I want to be able to change the combobox and sent that to a server but I can only seem to get the index. I want the label and data. when I use code hinting, It shows me that I can now use the slectedValue but it causes an error. How do I see all the values assosiated with the combo box, Label, Data?

    #42Posted by George | Jun 26, 2009, 12:00 PM
  • Mike

    In my flex app, I have 2 datagrids and when the app opens both datagrids get populated with data, dg2 visibilty is set to false; dg1 visibility is set to true. When the user clicks on a row in dg1, it populates combo boxes with that row data. That all works according your suggestion above (Thx!). I have a button, when clicked, it makes visible dg2. When I click on the button, dg2 becomes visible but then I want to be able to populate the same combo boxes with the row data in dg2. However, I've tried it and nothing gets selected in the combo boxes. any suggestions or examples? I'm using flex 3. Any help is appreciated.

    #43Posted by Mike | Jun 26, 2009, 04:59 PM
  • Mike

    In my flex app, I have 2 datagrids and when the app opens both datagrids get populated with data, dg2 visibilty is set to false; dg1 visibility is set to true. When the user clicks on a row in dg1, it populates combo boxes with that row data. That all works according your suggestion above (Thx!). I have a button, when clicked, it makes visible dg2. When I click on the button, dg2 becomes visible but then I want to be able to populate the same combo boxes with the row data in dg2. However, I've tried it and nothing gets selected in the combo boxes. any suggestions or examples? I'm using flex 3. Any help is appreciated.

    #44Posted by Mike | Jun 26, 2009, 04:59 PM
  • Gary

    Hi, Thanks your example, And I made a little change of yours, I think it will be more convenient

    override protected function commitProperties():void
    {
    // invoke ComboBox version

    super.commitProperties();

    // If value set and have dataProvider

    if (bSelectedValueSet && bDataProviderSet)
    {
    // Set flag to false so code won't be called until selectedValue is set again

    bSelectedValueSet=false;
    // Loop through dataProvider

    for (var i:int=0;i<this.dataProvider.length;i++)
    {
    // Get this item's data

    var item:String = this.dataProvider[i][this.data]; //The little change

    // Check if is selectedValue

    if(item == _selectedValue)
    {
    // Yes, set selectedIndex

    this.selectedIndex = i;
    break;
    }
    }
    }
    }

    In this way , Our value field name of our dataprovider can not be data but the other name.
    thank you.

    #45Posted by Gary | Aug 13, 2009, 03:52 AM
  • Navis Michael Bearly

    Thanks a lot....

    For Xml list
    =============================================
    <?xml version="1.0"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"; xmlns:ns2="myComponents.*">
    <mx:Script>
    <![CDATA[
    import mx.managers.PopUpManager;
    import mx.core.IFlexDisplayObject;
    private var helpWindow:IFlexDisplayObject;
    private var books:XML = <books>
    <book publisher="Addison-Wesley" name="Design Patterns" ids="0"/>
    <book publisher="Addison-Wesley" name="The Pragmatic Programmer" ids="1"/>
    <book publisher="Addison-Wesley" name="Test Driven Development" ids="2"/>
    <book publisher="Addison-Wesley" name="Refactoring to Patterns" ids="3"/>
    <book publisher="O'Reilly Media" name="The Cathedral & the Bazaar" ids="4"/>
    <book publisher="O'Reilly Media" name="Unit Test Frameworks" ids="5"/>
    </books>;
    private function his():void {
    xselect.selectedValue = "5";
    }
    ]]>
    </mx:Script>
    <ns2:xmlcmbbox id="xselect" dataProvider="{books.book}" labelField="@name" />
    <mx:Button click="his();" label="hiss"/>
    </mx:Application>
    =============================================================
    <?xml version="1.0" encoding="utf-8"?>
    <mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml";>
    <mx:Script>
    <![CDATA[
    private var _selectedValue:String;
    private var bSelectedValueSet:Boolean = false;
    private var bDataProviderSet:Boolean = false;
    // Override committ, this may be called repeatedly
    override protected function commitProperties():void {
    // invoke ComboBox version
    super.commitProperties();
    // If value set and have dataProvider
    if (bSelectedValueSet && bDataProviderSet) {
    // Set flag to false so code won't be called until selectedValue is set again
    bSelectedValueSet=false;
    // Loop through dataProvider
    for (var i:int=0;i<this.dataProvider.length;i++){
    // Get this item's data
    var item:String = this.dataProvider[i].@ids;
    // Check if is selectedValue
    if(item == _selectedValue) {
    // Yes, set selectedIndex
    this.selectedIndex = i;
    break;
    }
    }
    }
    }
    // Trap dataProvider being set

    override public function set dataProvider(o:Object):void {
    // invoke ComboBox version
    super.dataProvider = o;
    // This may get called before dataProvider is set, so make sure not null and has entries
    if (o!=null && o.length) {
    // Got it, set flag
    bDataProviderSet = true;
    }
    }

    // set for selectedValue
    public function set selectedValue(s:String):void {
    // Set flag
    bSelectedValueSet = true;
    // Save value
    _selectedValue = s;
    // Invalidate to force commit
    invalidateProperties();
    }
    ]]>
    </mx:Script>
    </mx:ComboBox>
    ============================================================

  • Chris

    Thanks so much for this. Why didn't Adobe do this it seems so obvious!

    #47Posted by Chris | Sep 29, 2009, 12:18 PM
  • John

    Why would I get always get [object Object] when I switch from the regular combobox to this one? I am using a webservice connected to a CFC.

    #48Posted by John | Oct 24, 2009, 11:01 PM
  • kid

    I guess we can use selectedIndex={x.y} in combobox with y as part of data source xml itself.

    #49Posted by kid | Nov 30, 2009, 10:17 AM
  • David Brannan

    Very close to what I want to do.

    This solution works until you set the combobox to be editable.

    What I am trying to has three indexes in the combobox (-1, 0, and one that the user can type in a value). Using your solution I can make the combobox value aware, but as soon as I flag the combobox as editable it will no longer lets me submit a value.

    Does anyone have a work around for that?

  • Chris

    Thanks! Just what I needed.

    #51Posted by Chris | Jan 29, 2010, 03:59 AM
  • jay

    You cannot assign the value in the commitProperties function. This causes the selectedItem value to not be available right away. Which will give you false results until the next validation routine runs.

    <?xml version="1.0" encoding="utf-8"?>
    <mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml">;

    <mx:Script>
    <![CDATA[
    import mx.events.ListEvent;

    public function set selectedValue(str:String):void{
    if( this.selectedValue == str ){ // if value already selected do nothing
    return;
    }

    for (var i:int=0;i<this.dataProvider.length;i++){// Loop through dataProvider
    if(this.dataProvider[i] == str){ // the match
    this.selectedIndex = i;// set selectedIndex
    //this.invalidateProperties();// Invalidate to force commit -- not sure we need to do this
    this.dispatchEvent( new ListEvent( ListEvent.CHANGE ) ) // since we are changing it we need to dispatch it
    break;
    }
    }
    }


    public function get selectedValue( ):String{
    if( this.selectedIndex >= 0){
    return dataProvider[this.selectedIndex]
    }else{
    return ""; // could be an issue if there is an empty string label
    }
    }

    ]]>
    </mx:Script>
    </mx:ComboBox>

    #52Posted by jay | Aug 23, 2010, 10:49 AM
  • Jay

    You cannot assign the value in the commitProperties function. This causes the selectedItem value to not be available right away. Which will give you false results until the next validation routine runs.

    <?xml version="1.0" encoding="utf-8"?>
    <mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml">;

    <mx:Script>
    <![CDATA[
    import mx.events.ListEvent;

    public function set selectedValue(str:String):void{
    if( this.selectedValue == str ){ // if value already selected do nothing
    return;
    }

    for (var i:int=0;i<this.dataProvider.length;i++){// Loop through dataProvider
    if(this.dataProvider[i] == str){ // the match
    this.selectedIndex = i;// set selectedIndex
    //this.invalidateProperties();// Invalidate to force commit -- not sure we need to do this
    this.dispatchEvent( new ListEvent( ListEvent.CHANGE ) ) // since we are changing it we need to dispatch it
    break;
    }
    }
    }


    public function get selectedValue( ):String{
    if( this.selectedIndex >= 0){
    return dataProvider[this.selectedIndex]
    }else{
    return ""; // could be an issue if there is an empty string label
    }
    }

    ]]>
    </mx:Script>
    </mx:ComboBox>

    #53Posted by Jay | Aug 23, 2010, 10:50 AM
  • Luis

    How would this example to Flash Builder 4?

    #54Posted by Luis | Oct 21, 2010, 07:24 PM
  • Daniel

    This doesn't seem to work in Flex 4, any ideas?

    #55Posted by Daniel | Apr 14, 2011, 12:28 PM
  • rahul

    Thanks alot....

    #56Posted by rahul | May 2, 2011, 01:14 AM
  • ahmar

    <s:View xmlns:fx="http://ns.adobe.com/mxml/2009";
          xmlns:s="library://ns.adobe.com/flex/spark"
          title="Rate Search">
    [Binndable]
    public var arr:ArrayCollection=new ArrayCollection([{ origincity: "new delhi" },{ origincity: "new york" }{ origincity: "London" }]);

    <fx:Script>
          <![CDATA[
          
             import mx.collections.ArrayCollection;
             import mx.events.FlexEvent;
             import mx.utils.ArrayUtil;
             
    protected function Button1_clickHandler(event:MouseEvent):void
    {
    Combobox1.dataProvider=arr;
    Combobox1.labelField="origincity"
    Lbl1.text=Combobox1.selectedItem.origincity
    }

    ]]>
    </fx:Script>

    <s:ComboBox id="ComboBox1/>
    <s:Button id="Button1"/>
    <s:Label id="Lbl1" text=""/>
    </s:view>

    #57Posted by ahmar | Jan 20, 2012, 02:10 AM