Home > Component, Flex, code > Deduped ComboBox Component

Deduped ComboBox Component

November 26th, 2008 Gareth Leave a comment Go to comments

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”.

  1. Ram
    March 16th, 2009 at 11:33 | #1

    Hi
    I was looking for deduping the combo box and I happened to come across your code, but unfortunately it is not working for me. yes it works if you define a array collection and assign data like you did in the above code. It is not working if i have an array collection with data( This array collection has data from my database). Below is the code which i’m using.Iam sure I’m doing something stupid any help will be appreciated

    In the below example the normal combo box displays the arraycollection with duplicates but the dedupe combo is just empty

  1. November 26th, 2008 at 23:53 | #1