自定义Flex ComboBox,根据用户输入过滤数据提供者

时间:2011-05-20 18:36:12

标签: flex actionscript flex4 adobe

我有一个ComboBox,数据提供者是一个包含3个值的ArrayCollection:CA - 加州,纽约 - 纽约,德克萨斯 - 德克萨斯。使用默认行为,当我开始在ComboBox中输入时,它将尝试匹配字符串开头的值,因此如果我开始键入TX,它将调出TX - Texas。

我希望能够搜索字符串的任何部分而不仅仅是从头开始,所以如果我输入“xas”,它将过滤掉选择并仅显示TX - Texas。 Adobe论坛here中有一篇非常有用的帖子,介绍如何通过更改ArrayCollection上的过滤器函数来为ComboBox提供数据,我已经对其进行了调整,但我遇到了一些问题。< / p>

如果用户选择一个值,然后尝试输入新文本,则ComboBox中输入的第一个字母不会显示。

1)在ComboBox中选择值CA - California 2)高亮显示文本并按键盘上的“n”键 3)您希望看到文本框填充“n”但文本框仍为空白

可能导致此问题的原因是什么?只有在您已选择值时才会发生这种情况。如果你从一个空白的ComboBox开始,它按预期工作。

<fx:Script>
    <![CDATA[
        import mx.collections.ArrayCollection;
        import mx.events.FlexEvent;

        import spark.events.TextOperationEvent;

        [Bindable]
        public var arrC:ArrayCollection = new ArrayCollection([{label:'CA - California'},{label:'NY - New York'},{label:'TX - Texas'}]);

        private function changeHandler(e:*):void
        {
            if (arrC.filterFunction != doFilter)
                arrC.filterFunction = doFilter;
            arrC.refresh();
        }

        private function doFilter(item:Object):Boolean
        {
            if(String(item.label).toLowerCase().indexOf(cb.textInput.text.slice(0 ,cb.textInput.selectionAnchorPosition).toLowerCase())>-1)             
            {
                return true;
            }
            return false;
        }                       

        protected function application1_creationCompleteHandler(event:FlexEvent):void
        {
            cb.textInput.addEventListener(TextOperationEvent.CHANGE,changeHandler );
        }

    ]]>
</fx:Script>

<s:ComboBox id="cb" dataProvider="{arrC}"/>

1 个答案:

答案 0 :(得分:7)

为您的问题找到了解决方案(因为我必须找出一个与googles搜索输入框类似的自定义组件)。似乎正常的输入处理通过过滤数据提供者而进入错误的方式。然而,我没有根据需要深入检查意外行为的来源,以提供对导致问题的解释(可能解决方案的想法来得太快;。))。这是:

<?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"
        skinClass="CGoogleComboSkin">
<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 is String) {
                if(String(item).toLowerCase().indexOf(
                    textInput.text.slice(0,
                        textInput.selectionAnchorPosition).toLowerCase())>-1)
                    return true;
            }
            else if (labelField && labelField!= "") {
                if(item.hasOwnProperty(labelField) && 
                        String(item[labelField]).toLowerCase().indexOf(
                        textInput.text.slice(0,
                        textInput.selectionAnchorPosition).toLowerCase())>-1)
                    return true;
            }

            return false;
        }
    ]]>
</fx:Script>
<fx:Declarations>
</fx:Declarations>

这个解决方案背后的想法是通过继承构建自定义Combobox并覆盖数据提供者的setter,以便通过任何textoperation将未过滤的数据提供者作为未更改的源,但让flex组合框以其通常的方式处理集合没有附加过滤器的地方(通过任何输入都是过滤源集合的结果)。这只是一次尝试但是起作用并且适用于我欣赏的快速;。)

快乐编码