Link to home
Start Free TrialLog in
Avatar of elepil
elepil

asked on

How to set selectedItem in a combobox

I have a combobox component that is being used as an ITEMRENDERER. Here is it's dataProvider data:

<mx:Model id="modelGender">
      <gender>
            <sex index="M" text="Male"/>
            <sex index="F" text="Female"/>
      </gender>
</mx:Model>

Here is the code for this component:

<?xml version="1.0" encoding="utf-8"?>
<mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml"
      dataProvider="{dp}"
      labelField="text"
      change="changeHandler(event)"
      creationComplete="init()">
      
      <mx:Script>
            <![CDATA[
                  import mx.collections.ArrayCollection;
                  
                  [Bindable]
                  public var dp:ArrayCollection;
                  
                  private function init():void
                  {
                        for (var i:int=0; i<dp.length; i++)
                        {
trace(data.index, data.text); // ****** 'data' is still undefined here
                              if (data.index == dp[i].index)
                                    this.selectedIndex = i;
                        }
                  }
            ]]>
      </mx:Script>
      
</mx:ComboBox>

I am using the 'creationComplete" event within the component to set the selectedIndex property of the combobox, but the problem is that the keyword 'data' is still undefined at this point.

So how can I pre-set the selectedItem of the combobox in this scenario?
Avatar of zzynx
zzynx
Flag of Belgium image

Can you tell us what 'data' is? Where is it defined?
Avatar of elepil
elepil

ASKER

Hello again, zzynx, thank you for responding.

zzynx, 'data' is a reserved keyword in Flex that is usable ONLY within an itemrenderer component during the datagrid data population stage; it allows the itemrenderer component to access any dataProvider data for that row ONLY. So if I had two columns in my datagrid whose dataProvider names were firstName and lastName, and I wanted to access these data within the itemrenderer component, I can fetch these two fields through data.firstName and data.lastName.

The 'data' keyword works for me all the time, except this time, it is somehow coming in as 'undefined'. I guess my mistake could be relying on the 'creationComplete' event because the 'data' keyword might not yet have been assigned a reference to the row data, and I don't know how to get around this.

Maybe I should not use the 'creationComplete' event because it would still be too early. Do you know of any other event I can use, one that occurs after the component has already been populated with data, hoping that the 'data' keyword might already be assigned the reference to the row data?
>> Do you know of any other event I can use
There's also "initialize" but that one comes after "creationComplete", so that's of no use for you.
(http://livedocs.adobe.com/flex/201/html/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Book_Parts&file=containers_intro_063_12.html)
But I think using "creationComplete" is just fine here.

>> ... hoping that the 'data' keyword might already be assigned the reference to the row data?
I think the problem might be the combination of

dataProvider="{dp}"

and

public var dp:ArrayCollection;

Where/when do you fill up that "dp" ArrayCollection (which is the dataprovider of your combo box)
Can you be sure that "dp" is filled up before init() is called?
Avatar of elepil

ASKER

zzynx, this component is an itemrenderer, and thanks to your help on other posts I have, I was able to successfully pass the dataProvider (dp property). The dataProvider was passed in via:

var myComboBoxRenderer:ClassFactory = new ClassFactory(itemrenderers.ComboBoxRenderer);
myComboBoxRenderer.properties = { dp:new ArrayCollection(modelGender.sex) };
dgc.itemRenderer = myComboBoxRenderer;

If you look at my original code sample back at my very first post on this thread, you will see a trace statement. Although I did not include the outputting of dp[i].index, it actually prints the expected data.

So really, the only problem is 'data' being undefined. :(
Another idea is not to rely on 'data', but  to set the selected item the same way you set the 'dp' property:

>> var myComboBoxRenderer:ClassFactory = new ClassFactory(itemrenderers.ComboBoxRenderer);
>> myComboBoxRenderer.properties = { dp:new ArrayCollection(modelGender.sex), selectedIndex:1 };
>> dgc.itemRenderer = myComboBoxRenderer;

Don't know if that is possible. Just a wild idea...
Avatar of elepil

ASKER

Well, there are multiple rows in the dataGrid, and hence, multiple comboboxes that need to be initialized. Passing it in the way you suggested happens only once.
You're right. Of course.
Well, I'm sorry to say, but I'm running out of ideas...

>> the problem is that the keyword 'data' is still undefined at this point.
Do you manage to find another point in time/your code where 'data' IS defined?
I mean, is it really a matter of "data not being defined yet" or rather "data never being defined". (and the more I think about it the more I think it is the last...)
Avatar of elepil

ASKER

Well, in the past times I've used itemrenderers/itemeditors, data had always been defined; this is actually the first time I've encountered this issue. So based on past experience, I am inclined to think that data will eventually be defined. I hate issues like this. :(
Just had a quick read through this, so apologies if you've already discussed or tried this:

data will always be valid inside an itemRenderer as long as the component has a dataProvider assigned

Try making modelGender an ArrayCollection instead of a Model..

<mx:ArrayCollection id="modelGender">
      <mx:Object index="M" text="Male"/>
      <mx:Object index="F" text="Female"/>
</mx:ArrayCollection>

my 2 cents :)
Avatar of elepil

ASKER

Thanks for responding, hobbit72.

I don't think I reflected this in my code in the orignal post, and it's my fault, but the way the model data was passed was like this:

var myComboBoxRenderer:ClassFactory = new ClassFactory(itemrenderers.ComboBoxRenderer);
myComboBoxRenderer.properties = { dp:new ArrayCollection(modelGender.sex) };
dgc.itemRenderer = myComboBoxRenderer;

If you'll notice, I had already wrapped the model data inside an ArrayCollection. But nevertheless, I thought maybe all that conversion going on may have caused this problem, so I actually did try your recommendation.

I replaced the mx:Model with the mx:ArrayCollection you showed in your post, then I changed the second line to:

myComboBoxRenderer.properties = { dp:modelGender) };

Unfortunately, 'data' was still undefined within the component. It's these times I wish I had a technical support contract with Adobe, but it costs $1500 for a year. :(

But thanks again for trying, hobbit72.
ASKER CERTIFIED SOLUTION
Avatar of zzynx
zzynx
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
good job, glad you figured it out :)
Avatar of elepil

ASKER

Aagh!! You're right! I can't believe I screwed up this way.:( I must've been spaced out when I did this, and I can't believe I didn't see that after the many times I've looked over this stupid code.

You're right, zzynx, I was treating 'data' as the data in the combobox, a total blunder on my part, causing me to use 'data.index'. In your example, you used 'gender' as the field for the 'M' or 'F' value. I actually used 'genderKey'. So I should've been using data.genderKey instead data.index.

It works now. Really excellent work, zzynx. I would give you 1000 points if I could for all the effort and time you had expended, but it won't let me do that, unfortunately. Instead, accept my many many thanks!
>> I would give you 1000 points if I could
:o)

>> Instead, accept my many many thanks!
I do. Glad I could help.
Thanks for your kind words.