我正在使用Spark Combobox和过滤器功能来过滤firstName
和lastName
中的字符。当用户输入" a"下拉列表显示所有过滤的项目,选择" aram,babu"在下拉菜单中还显示文字为" aram,babu"在textinput中。如果用户按下" r",则文本输入显示" aram,babu",但下拉列表选择消失。点击输入或点击下拉菜单外的鼠标会导致错误的项目(最后一项,即" armu,babu")被选中。
<?xml version="1.0"?>
<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" xmlns:local="*">
<fx:Script><![CDATA[
import mx.collections.ArrayCollection;
private function labelField(item:Object):String {
if (item && item as SalesPerson && item.lastName && item.firstName) {
return item.firstName + "," + item.lastName;
}
return "";
}
private var arr:ArrayCollection;
private var arr1:ArrayCollection;
private var salesPer:SalesPerson;
private function getData():ArrayCollection
{
arr1 = new ArrayCollection();
var salesPerson:SalesPerson = new SalesPerson();
salesPerson.userName = "ravi kumar";
salesPerson.firstName = "ravi";
salesPerson.lastName = "kumar";
var salesPerson1:SalesPerson = new SalesPerson();
salesPerson1.userName = "kiran kumar";
salesPerson1.firstName = "kiran";
salesPerson1.lastName = "kumar";
var salesPerson2:SalesPerson = new SalesPerson();
salesPerson2.userName = "james bond";
salesPerson2.firstName = "james";
salesPerson2.lastName = "bond";
var salesPerson3:SalesPerson = new SalesPerson();
salesPerson3.userName = "ravi babu";
salesPerson3.firstName = "ravi";
salesPerson3.lastName = "babu";
var salesPerson4:SalesPerson = new SalesPerson();
salesPerson4.userName = "rakesh babu";
salesPerson4.firstName = "rakesh";
salesPerson4.lastName = "babu";
var salesPerson5:SalesPerson = new SalesPerson();
salesPerson5.userName = "ramesh babu";
salesPerson5.firstName = "ramesh";
salesPerson5.lastName = "babu";
var salesPerson6:SalesPerson = new SalesPerson();
salesPerson6.userName = "aram babu";
salesPerson6.firstName = "aram";
salesPerson6.lastName = "babu";
var salesPerson7:SalesPerson = new SalesPerson();
salesPerson7.userName = "armu babu";
salesPerson7.firstName = "armu";
salesPerson7.lastName = "babu";
arr1.addItem(salesPerson);
arr1.addItem(salesPerson1);
arr1.addItem(salesPerson2);
arr1.addItem(salesPerson3);
arr1.addItem(salesPerson4);
arr1.addItem(salesPerson5);
arr1.addItem(salesPerson6);
arr1.addItem(salesPerson7);
return arr1;
}
]]></fx:Script>
<s:VGroup width="100%" height="100%">
<local:FilterCombo labelFunction="labelField" dataProvider="{getData()}"/>
</s:VGroup>
</s:Application>
<?xml version="1.0"?>
<s:ComboBox xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" click="clickHandler(event)">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.collections.IList;
import spark.events.TextOperationEvent;
private var unfilteredDataProvider:IList;
override public function set dataProvider(value:IList):void {
super.dataProvider = value;
unfilteredDataProvider = value;
}
override protected function textInput_changeHandler(event:TextOperationEvent):void {
super.textInput_changeHandler(event);
if (unfilteredDataProvider is ArrayCollection) {
ArrayCollection(unfilteredDataProvider).filterFunction = filterMatches;
ArrayCollection(unfilteredDataProvider).refresh();
super.dataProvider = new ArrayCollection(unfilteredDataProvider.toArray());
}
}
protected function filterMatches(item:Object):Boolean {
if (item && item.lastName && item.firstName) {
if (String(item.lastName + item.firstName).toLowerCase().indexOf(textInput.text.slice(0, textInput.selectionAnchorPosition).toLowerCase()) > -1) {
// trace("traderDoFilter true")
return true;
}
}
return false;
}
private function clickHandler(event:MouseEvent):void {
}
]]>
</fx:Script>
</s:ComboBox>
答案 0 :(得分:0)
基本上,Combobox搜索工作基于labelfield,您可以看到Combobox框架代码。
验证下面提到的功能: ComboBox - &gt; processInputField(功能)
if (itemMatchingFunction != null)//itemMatchingFunction allways null untill we assign our callback function
matchingItems = itemMatchingFunction(this, textInput.text);
else
matchingItems = findMatchingItems(textInput.text);//calling by default
所以我们需要将自定义回调函数分配给 itemMatchingFunction(public)
我在你的代码中做了一些修改试试这个,它有一些错误
<?xml version="1.0" encoding="utf-8"?>
<s:ComboBox xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" click="clickHandler(event)">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.collections.IList;
import spark.events.TextOperationEvent;
import spark.utils.LabelUtil;
private var unfilteredDataProvider:IList;
namespace mx_internal;
override public function set dataProvider(value:IList):void {
super.dataProvider = value;
this.itemMatchingFunction = itemMatchingFunction1;
}
override protected function textInput_changeHandler(event:TextOperationEvent):void {
super.textInput_changeHandler(event);
if (dataProvider is ArrayCollection) {
ArrayCollection(dataProvider).filterFunction = filterMatches;
ArrayCollection(dataProvider).refresh();
}
}
protected function filterMatches(item:Object):Boolean {
if (item && item.lastName && item.firstName) {
if (String(item.lastName +","+ item.firstName).toLowerCase().indexOf(textInput.text.slice(0, textInput.selectionAnchorPosition).toLowerCase()) > -1) {
return true;
}
}
return false;
}
/**
* @private
*/
// Returns an array of possible values
private function itemMatchingFunction1(comB:ComboBox,input:String):Vector.<int>
{
// For now, just select the first match
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
{
// Try to find the item based on the start and stop indices.
for (startIndex; startIndex != stopIndex; startIndex++)
{
var itmStr:String = itemToLabel(dataProvider.getItemAt(startIndex));
itmStr = itmStr.substring(0, str.length);
if (str == itmStr || str.toUpperCase() == itmStr.toUpperCase())
{
return startIndex;
}
}
return -1;
}
/**
* Given a data item, return the correct text a renderer
* should display while taking the <code>labelField</code>
* and <code>labelFunction</code> properties into account.
*
* @param item A data item
*
* @return String representing the text to display for the
* data item in the renderer.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
override public function itemToLabel(item:Object):String
{
if (item && item.lastName && item.firstName)
return item.lastName +","+ item.firstName;
return item[labelField];
}
]]>
</fx:Script>
</s:ComboBox>