• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 806
  • Last Modified:

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?
0
elepil
Asked:
elepil
  • 6
  • 6
  • 2
1 Solution
 
zzynxSoftware engineerCommented:
Can you tell us what 'data' is? Where is it defined?
0
 
elepilAuthor Commented:
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?
0
 
zzynxSoftware engineerCommented:
>> 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?
0
Eye-catchers on the conference table

Challenge: The i-unit group was not satisfied with the audio quality during remote meetings. They were looking for a portable solution with excellent audio quality for use in their conference room but also at their client’s offices.

 
elepilAuthor Commented:
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. :(
0
 
zzynxSoftware engineerCommented:
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...
0
 
elepilAuthor Commented:
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.
0
 
zzynxSoftware engineerCommented:
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...)
0
 
elepilAuthor Commented:
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. :(
0
 
Gary BenadeCommented:
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 :)
0
 
elepilAuthor Commented:
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.
0
 
zzynxSoftware engineerCommented:
Looks like I found it.

This is the code I use.
The result is in the screenshot.

It's not data that is undefined, it's data.index and data.text that return undefined.
'data' represents the object that is in the datagrid, NOT the item that is in the combo box.
So I changed that code into

if (data.gender == dp[i].index)
   this.selectedIndex = i;

and it works.
<mx:Canvas 
	xmlns:mx="http://www.adobe.com/2006/mxml"
	creationComplete="onComplete()" >
 
	<mx:Model id="modelGender">
	      <gender>
	            <sex index="M" text="Male"/>
	            <sex index="F" text="Female"/>
	      </gender>
	</mx:Model>
	
	<mx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
		
			private function onComplete():void {
				var myComboBoxRenderer:ClassFactory = new ClassFactory(ComboBoxRenderer);
				myComboBoxRenderer.properties = { dp:new ArrayCollection(modelGender.sex) };
				dgc.itemRenderer = myComboBoxRenderer;
				
				var data:ArrayCollection = new ArrayCollection();
				var o:Object = new Object();
				o.test = "This is a female";
				o.gender = "F";
				data.addItem(o);
				o = new Object();
				o.test = "This is a male";
				o.gender = "M";
				data.addItem(o);
				dg.dataProvider = data; 
			}
		]]>
	</mx:Script>
 
	<mx:HBox>
		<mx:DataGrid id="dg">
			<mx:columns>
			    <mx:DataGridColumn headerText="Test" dataField="test"/>
				<mx:DataGridColumn id="dgc" dataField="gender" headerText="Gender"/>
			</mx:columns>
		</mx:DataGrid>
	</mx:HBox>
</mx:Canvas>
 
and
 
<?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.events.ListEvent;
            import mx.collections.ArrayCollection;
              
              [Bindable]
              public var dp:ArrayCollection;
              
              private function init():void
              {
                for (var i:int=0; i<dp.length; i++)
                {
                    if (data.gender == dp[i].index)
                    	this.selectedIndex = i;
                }
              }
              
              private function changeHandler(e:ListEvent):void {
              	
              }
        ]]>
      </mx:Script>
      
</mx:ComboBox>

Open in new window

ScreenShot170.jpg
0
 
Gary BenadeCommented:
good job, glad you figured it out :)
0
 
elepilAuthor Commented:
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!
0
 
zzynxSoftware engineerCommented:
>> 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.
0

Featured Post

Get Certified for a Job in Cybersecurity

Want an exciting career in an emerging field? Earn your MS in Cybersecurity and get certified in ethical hacking or computer forensic investigation. WGU’s MSCSIA degree program was designed to meet the most recent U.S. Department of Homeland Security (DHS) and NSA guidelines.  

  • 6
  • 6
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now