Archive

Posts Tagged ‘combobox’

Deduped ComboBox Component

November 26th, 2008 Gareth 1 comment

There are times that I have wanted to remove all duplicates from a combobox’s dataprovider, but haven’t wanted to requery the database or roll my own code snippet each time to remove those duplicates.  To make my life a little easier (and hopefully anyone else that may be in need of this feature), I’ve created the DedupeComboBox class.

This handy little item allows you to set the dataprovider of the combobox to an array or arraycollection, and set the labelField value and the combobox will then handle the rest.  The labelfield is important as that is what allows the component to remove the duplicates from the arraycollection (if it is an array, it must also be an array of objects with properties that match the labelField or it will not remove anything). Also, as the items populate the deduped dictionary instance, the value of that item in the arraycollection is saved to that “key” in the dictionary, allowing for retrieval of it later on if necessary.

package com.archfamily {
 
	import flash.utils.Dictionary;
 
	import mx.collections.ArrayCollection;
	import mx.controls.ComboBox;
 
	public class DedupeComboBox extends ComboBox {
 
		/**
		 * 
		 * Needed to override the standard dataprovider in order to reset
		 * the duplicate value each time
		 * 
		 */
		override public function set dataProvider( value:Object ):void {
 
			var _localArray:Array = ( value is ArrayCollection ) ? ( value as ArrayCollection ).source : value as Array;
			var _map:Dictionary = new Dictionary( true );
 
			if ( labelField.length > 0 ) {
				_localArray.forEach( function( item:*, index:int, array:Array ):void {
					_map[ item[ this ] ] = item; // in the loop, this == labelField
				}, labelField );
			}
 
			var _returnArray:Array = [];
			for each ( var object:Object in _map ) {
				_returnArray.push( object );
			}
 
			super.dataProvider = _returnArray;
		}
 
		public function DedupeComboBox() {
			super();
		}
 
	}
}

then to implement it from your code you could do something as simple as this

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:archfamily="com.archfamily.*">
	<mx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
			[Bindable] private var ac:ArrayCollection = new ArrayCollection([ { name: "car", total: 100 },{ name: "bus", total: 200 },{ name: "bike", total: 300 },{ name: "train", total: 200 },{ name: "boat", total: 400 },{ name: "car", total: 500 },{ name: "bus", total: 200 },{ name: "convertible", total: 100 },{ name: "gizmo", total: 300 },{ name: "boat", total: 300 },{ name: "car", total: 100 },{ name: "dune buggy", total:300 },{ name: "motorcycle", total: 100 }]);
		]]>
	</mx:Script>
 
	<archfamily:DedupeComboBox id="testing" dataProvider="{ ac }" labelField="name" />
</mx:Application>

You can even get just the non-duplicate totals by changing labelField=”name” to labelField=”total”.