Number of items in a combobox in Flex - apache-flex

HI,
How do i retreive the total number of items (count) of a combo box in Flex?

random idea for you:
var dp : Object = combobox.dataProvider ;
if(dp is Array)
{
//do something cool
}
else if(dp is ArrayCollection){
//do something equally as cool
}
etc...

I've confirmed that this will work:
(comboBox.dataProvider as ArrayCollection).length

Try using:
combobox.collection.length
where combobox is the combobox you are using
I'm not sure this will work though. You may need to subclass the control because collection is a protected member :(

The dataprovider of combobox is an arraycollection. You can use the length property to count the number.

Related

Flex DataGrid: Programmatically Highlighting Rows

This seems like something that should be painfully simple, but I can't even find how to loop through rows in a Flex DataGrid.
Basically what I'm trying to accomplish is something like this pseudo-code:
for each(var row:Row in myDataGrid.Rows)
{
if(row.DataObject.Number == 1)
{
row.Color = Red;
}
}
I'm trying to have a Save button that upon being clicked either processes the save, or highlights the invalid rows and pops up a message telling the user why the rows are invalid. Because of some other complexities, I am not able to validate each row as it is entered. Any help is appreciated! Thanks.
Data grids are intended to be driven by their data rather than manipulated directly. One way to accomplish what you are trying to do is to add some sort of property, say "valid", to the data objects in your provider and add code to the renderer to alter its appearance based on the state of "valid". In that way you could loop through the objects in your data provider and set the "valid" property based on your validation check, which would cause the rows in the data grid to change their appearance automatically.
Hope that helps.
Try something like this:
for each(var o:Object in myDataGrid.dataProvider)
{
if(o.Number == 1) {
myDataGrid.selectedItems.push(o);
}
}
In your mxml you can set the selectionColor of the datagrid to red. See: http://blog.flexexamples.com/2008/02/19/setting-the-selection-color-and-selection-disabled-color-for-a-row-in-the-flex-datagrid-control/
Let me know if this works for you!
I am not sure you can do it on the data grid itself, but if you have an item renderer for each of the items, you can have your highlighting logic there.
basically, you define your datagrid's item renderer class:
<mx:DataGrid itemRenderer="ItemRendererClass"(...) ></mx:DataGrid>
and then you define the class "ItemRendererClass" as implementing IDataRenderer:
implements="mx.core.IDataRenderer"
This is a simplistic explanation, assuming you can figure out how to do this on yourself :)
I achieved this by overriding the set data. I have provided the sample code below.
override public function set data(value:Object):void
{
super.data=value;
if(value!=null && value.hasOwnProperty("state") && value.state == "Final State"){
setStyle("color", 0xb7babc);
}else{
setStyle("color", 0x000000);
}
this.selectable=false;
super.invalidateDisplayList();
}

how to hide a row without deleting item from dataprovidor in DataGrid...AS3,Flex?

How we can hide a row at specific index of DataGrid in AS3 ?
If dataProvider of your DataGrid is ArrayCollection you can specify filterFunction property for it, something like that
dataProvider.filterFunction =
function (item:Object):Boolean{
if (dataProvider.getItemIndex(item)==indexOfRowYouWantToHide){
return false;
}
return true;
};
The item will still be in ArrayCollection but will be made invisible by the filter. Not the most efficient solution but it works. You need to call
dataProvider.refresh();
to apply the filter.
UPDATE: To access raw, unfiltered data of ArrayCollection you should use list property, so if you hid item at index 0 and still want to be able to access it you do that like this:
dataProvider.list.getItemAt(0);
No (easy) way. You can try to subclass DataGrid to add this functionality, but this will be really heavy task.

Force all item renderers to commitProperties?

I have an item renderer that checks an external source for display information. If that information changes, I want to force all item renderer instances to check it.
What's the best way for force all the item renderers in a list or grid to either commitProperties or execute some other method?
I've read that resetting the
grid.itemRenderer property will make
them all initialize.
I've also received the suggestion to
iterate recursively through all the
grid's children and call invalidateProperties
on all the UIComponents I find.
Any thoughts? Alternatives?
Remember that in Flex Lists you're dealing with virtualization and itemRenderer recycling, so generally only the currently visible itemRenderers actually exist, and are therefore the ones that actually need updating.
The following works for Spark list-based controls:
for ( var i:int=0; i< sparkList.dataGroup.numElements; i++ )
{
var element:UIComponent = sparkList.dataGroup.getElementAt( i ) as UIComponent;
if ( element )
element.invalidateProperties();
else
trace("element " + i.toString() + " wasn't there");
}
If you've got 100 items, this will update the 10 visible ones and ignore the virtual rest.
If you're working with mx DataGrid, you might want to try a variant of this- but it doesn't use DataGroup / Spark virtualization so I don't have an answer for you off the top of my head.
P.S. I'm putting the finishing touches on a completely Spark-based DataGrid, I'll post the link when I'm done.
Datagroup has getItemIndicesInView() which will give you the indicies of all item renderers that are in view. Call getElementAt with those indicies.
I also usually extend ItemRenderer and add the following which will cause the item renderer's state to refresh.
public function invalidateSkinState():void
{
super.invalidateRendererState();
}
public function updateAllRenderer():void
{
if (!list.dataGroup)
return;
if (!list.dataGroup.dataProvider)
return;
for ( var index:int=0; index< list.dataGroup.numElements; index++ )
{
var item:Object = list.dataGroup.dataProvider.getItemAt(index);
var renderer:IVisualElement = list.dataGroup.getElementAt( index ) as IVisualElement;
if ( renderer )
list.updateRenderer( renderer, index, item );
}
}
works fine for me

Flex: Is there a way to bind ComboBox's selectedItem to a variable?

OK I have a ComboBox, the dataProvider is an array of objects with label properties that give the ComboBox the list of options.
Is there a way I can have a variable like mySelectedItem, and bind the ComboBox's selectedItem to it so that if it changes, the ComboBox's selectedItem will change to whatever it is?
I hope this makes sense.
Thanks!
Yes, ComboBox's selectedItem property is bindable.
It would go something like this:
<mx:ComboBox selectedItem="{mySelectedItem}">
</mx:ComboBox>
In your AS:
[Bindable]
var mySelectedItem:Object;
Changes to mySelectedItem should show up in ComboBox. You may get errors if the item referenced by mySelectedItem does not exist in the ComboBox's dataProvider.
On the surface, it's as simple as:
<mx:ComboBox id="myComboBox"
dataProvider="{myDataProvider}"
selectedItem="{defaultItem}"/>
When you set defaultItem (make sure it is [Bindable]) to one of the items in the data provider, it will update the control.
But there are problems with this approach. Unless currentDefaultItem always changes AFTER myDataProvider, the binding to dataProvider may undo the selection, reverting to the default (first item in the list).
One way around this is to force selectedItem to be rebound after dataProvider, by including dataProvider in the call providing the selectedItem.
<mx:ComboBox id="myComboBox"
dataProvider="{myDataProvider}"
selectedItem="{getSelectedItem(myComboBox.dataProvider, defaultItem)}"/>
What this does is ensure selectedItem will be rebound when either currentDefaultItem changes, or after the dataProvider changes. I'd be interested in other solutions myself.
Use an event listener for the Change event and do your processing there.
// update a label item's text with that of the Combobox's selectedItem
private function changeEvt(event:Event):void {
label.text =event.currentTarget.selectedItem.label + " " +
}
or, you could do something like this if you don't mind extending ComboBox;
This is pseudocode (sorry, identification of matches depends on the object type) - but you get the idea...
public class IndexRetainingComboBox extends ComboBox
{
public function IndexRetainingComboBox()
{
super();
}
override public function set dataProvider(value:Object):void
{
var originalSelection:Object = this.selectedItem;
super.dataProvider = value;
var newIdx:uint = [find originalSelection idx in combobox or return 0 ]
this.selectedIndex = newIdx;
}
}
I know this is how its described in the documentation.
As in a change to the selectedItem will fire the change listener. However for me, this does not happen. Anyone else encounter the same behavior?
This looks like a great approach: make the value attribute writeable:
http://flex.sys-con.com/node/312098

Flex ComboBox, default value and dataproviders

I have a Flex ComboBox that gets populated by a dataprovider all is well...
I would now like to add a default " -- select a item --" option at the 0 index, how can I do this and still use a dataprovider? I have not seen any examples of such, but I can't imagine this being hard...
If you don't need the default item to be selectable you can use the prompt property of ComboBox and set the selectedIndex to -1. That will show the string you set propmt to as the selected value until the user chooses another. It will not appear in the list of options, however.
I came across this problem today and wanted to share my solution.
I have a ComboBox that has an ArrayCollection containing Objects as it's dataprovider. When the application runs, it uses a RemoteObject to go out and get the ArrayCollection/Objects. In my event handler for that call I just have it append another object to the beginning of the ArrayCollection and select it:
var defaultOption:Object = {MyLabelField: "Select One"};
myDataProvider.addItemAt(defaultOption, 0);
myComboBox.selectedIndex = 0;
This is what my ComboBox looks like for reference:
<mx:ComboBox id="myComboBox" dataProvider="{myDataProvider}" labelField="MyLabelField" />
The way I've dealt with this in the past is to create a new collection to serve as the data provider for the combobox, and then I listen for changes to the original source (using an mx.BindingUtils.ChangeWatcher). When I get such a notification, I recreate my custom data provider.
I wish I knew a better way to approach this; I'll monitor this question just in case.
This can be used following code for selected default value of combobox
var index:String = "foo";
for(var objIndex:int = 0; objIndex < comboBox.dataProvider.length; objIndex++) {
if(comboBox.dataProvider[objIndex].label == index)
{
comboBox.selectedIndex = objIndex;
break;
}
}
<mx:ComboBox id="comboBox" dataProvider="{_pageIndexArray}" />

Resources