当前位置: 代码迷 >> Web前端 >> 带搜寻的comboBox组件
  详细解决方案

带搜寻的comboBox组件

热度:101   发布时间:2013-08-04 18:26:15.0
带搜索的comboBox组件

Flex自带的comboBox也可以支持搜索,但是它是从第一位严格匹配的,如果我想做一个这样条件的搜索:只要lable中有输入的字符,那么就定位到匹配的第一个项。自定义itemMatchingFunction并不会允许客户输入一个字符串,而是当客户输入第一个字符串就立刻匹配并定位,显然这不是我们想要的。

唉,还是上代码吧。

App:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:view="com.view.*">
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx:Declarations>
	<fx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
			import mx.collections.ArrayList;
			
			import spark.components.ComboBox;
			import spark.events.IndexChangeEvent;
			[Bindable]
			public var complexDP:ArrayCollection = new ArrayCollection(
				[    {ingredient:"Salmon", category:"Meat"}, 
					{ingredient:"Potato", category:"Starch"}, 
					{ingredient:"Cucumber", category:"Vegetable"}, 
					{ingredient:"Steak", category:"Meat"}, 
					{ingredient:"Rice", category:"Starch"}, 
					{ingredient:"Cumin", category:"Spice"}
				]                
			);
		]]>
	</fx:Script>
	<s:layout>
		<s:VerticalLayout/>
	</s:layout>
	<view:ComboBoxSearch 
		id="bcc"
		dataProvider="{complexDP}" 
		width="150" 
		selectedIndex="0" 
		labelField="ingredient"/>  
</s:Application>

?ComboBoxSearch:

package com.view
{
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import flashx.textLayout.operations.CutOperation;
	import flashx.textLayout.operations.DeleteTextOperation;
	import flashx.textLayout.operations.FlowOperation;
	import flashx.textLayout.operations.InsertTextOperation;
	
	import mx.core.mx_internal;
	
	import org.osmf.events.TimeEvent;
	
	import spark.components.ComboBox;
	import spark.events.DropDownEvent;
	import spark.events.TextOperationEvent;
	
	public class ComboBoxSearch extends ComboBox
	{
		private var timer:Timer;
		private var tempEvent:TextOperationEvent;
		public function ComboBoxSearch()
		{
			super();
			this.addEventListener(Event.ADDED_TO_STAGE,onAddToStageHandler);
			this.addEventListener(Event.REMOVED_FROM_STAGE,onRemoveToStageHandler);
		}
		
		private function onAddToStageHandler(event:Event):void
		{
			timer = new Timer(300,1);
			timer.addEventListener(TimerEvent.TIMER,onTimerHandler);
		}
		
		private function onRemoveToStageHandler(event:Event):void
		{
			if(timer.running)
			{
				timer.stop();
			}
			timer.removeEventListener(TimerEvent.TIMER,onTimerHandler);
			timer = null;
		}
		
		override protected function textInput_changeHandler(event:TextOperationEvent):void
		{
			tempEvent = event;
			if(timer.running)
			{
				timer.stop();
			}
			timer.reset();
			timer.start();
		}
		
		private function onTimerHandler(event1:TimerEvent):void
		{
			var operation:FlowOperation = tempEvent.operation;
			if (operation is DeleteTextOperation || operation is CutOperation)
			{
				super.mx_internal::changeHighlightedSelection(CUSTOM_SELECTED_ITEM);
				processInputField();
			}
			else
			{
				if (openOnInput)
				{
					if (!isDropDownOpen)
					{
						openDropDown();
						addEventListener(DropDownEvent.OPEN, editingOpenHandler);
						return;
					}   
				}
				processInputField();
			}
		}
		
		private function editingOpenHandler(event:DropDownEvent):void
		{
			removeEventListener(DropDownEvent.OPEN, editingOpenHandler);
			processInputField();
		}
		
		private function processInputField():void
		{
			var matchingItems:Vector.<int>;
			if (!dataProvider || dataProvider.length <= 0)
				return;
			if (textInput.text != "")
			{
				if (itemMatchingFunction != null)
					matchingItems = itemMatchingFunction(this, textInput.text);
				else
					matchingItems = findMatchingItems(textInput.text);
				
				if (matchingItems.length > 0)
				{
					super.mx_internal::changeHighlightedSelection(matchingItems[0], true);
					
					var typedLength:int = textInput.text.length;
					var item:Object = dataProvider ? dataProvider.getItemAt(matchingItems[0]) : undefined;
					if (item)
					{
						var itemString:String = itemToLabel(item);
						textInput.selectAll();
						textInput.insertText(itemString);
						textInput.selectRange(typedLength, itemString.length);
					}
				}
				else
				{
					super.mx_internal::changeHighlightedSelection(CUSTOM_SELECTED_ITEM);
				}
			}
			else
			{
				super.mx_internal::changeHighlightedSelection(NO_SELECTION);  
			}
		}
		
		private function findMatchingItems(input:String):Vector.<int>
		{
			var startIndex:int;
			var stopIndex:int;
			var retVal:int;  
			var retVector:Vector.<int> = new Vector.<int>;
			retVal = findStringLoop(input, 0, dataProvider.length); 
			if (retVal != -1)
				retVector.push(retVal);
			return retVector;
		}
		
		private function findStringLoop(str:String, startIndex:int, stopIndex:int):Number
		{
			for (startIndex; startIndex != stopIndex; startIndex++)
			{
				var itmStr:String = itemToLabel(dataProvider.getItemAt(startIndex));
				if(itmStr)
				{
					if(itmStr.toLowerCase().indexOf(str.toLowerCase()) > -1)
					{
						return startIndex;
					}
				}
			}
			return 0;
		}
	}
}

?当然,如果你想优化搜索的方法,那么就你只要修改findStringLoop方法即可。

?

?

  相关解决方案