Comunidad de diseño web y desarrollo en internet online

Filtrar datos en AS3 con filterFunction y ArrayCollection

La clase ArrayCollection de Actionscript 3 incluye una propiedad heredada de ListCollectionView llamada filterFunction con la cual podemos mandar llamar una función que nos devolverá un valor Boolean con el cual evaluaremos si al final el ArrayCollection muestra o no algún elemento.

Antes de mostrar el ejemplo de uso, veamos como tenemos que construir la función que será el valor de la propiedad filterFunction:

Código :

ff(item:Object):Boolean
El nombre de la función lo escoge el desarrollador, sin embargo, el parámetro de entrada y el tipo de dato de regreso si se tienen que especificar según lo indica la documentación. El parámetro de entrada tiene que ser de tipo Object, pues es cada elemento del proveedor de datos que estará mandando a la función para evaluar y el tipo de dato de regreso es de tipo Boolean, pues cuando sea true se agregará al proveedor y cuando sea false se ignorará.

A continuación un ejemplo de como un proveedor de datos tipo ArrayCollection funciona sobre ComboBox, List y DataGrid's:



Para ver el código y descargar el proyecto, click derecho sobre el swf y luego click en View Source. El MXML lo incluyo acá abajo:

Código :

<?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="400" minHeight="600"
               width="400" height="370" xmlns:flexlib="http://code.google.com/p/flexlib/"
               creationComplete="this_creationCompleteHandler()" viewSourceURL="srcview/index.html">
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.events.FlexEvent;
            import mx.utils.StringUtil;
            
            //variable en la que guardaremos el token a buscar
            private var str2search:String = "";
            //dejamos la variable como Bindable para que detecte automaticamente los cambios al proveedor
            [Bindable]private var acDataProvider:ArrayCollection;
            
            protected function this_creationCompleteHandler():void
            {
                //llenamos con informacion falsa el proveedor
                //este proveedor tambien podria ser llenado desde una Base de Datos, XML, etc
                acDataProvider = new ArrayCollection([
                    {nombre: "Daniel", nick: "master_of_puppetz", clablevel: 24243},
                    {nombre: "Alberto", nick: "betornillo", clablevel: 15431},
                    {nombre: "Juan", nick: "jhonny", clablevel: 76453},
                    {nombre: "Miguel", nick: "mickey", clablevel: 2151345},
                    {nombre: "Luis", nick: "lucho", clablevel: 3245},
                    {nombre: "Carlos", nick: "charly", clablevel: 1235345},
                    {nombre: "Oscar", nick: "lirask8", clablevel: 3452},
                    {nombre: "Giovanni", nick: "giolink", clablevel: 1234234}
                ]);
            }
            
            /**
             * Este metodo se disparara cada vez que se escriba algo en la caja de texto de busqueda
             */
            protected function tiBuscar_changeHandler(event:Event):void
            {
                //recuperamos el texto de la caja de busqueda y lo convierto a minusculas
                str2search = StringUtil.trim(tiBuscar.text).toLowerCase();
                //validamos que no este vacia
                if (str2search != "")
                {
                    //si no esta vacia, aplicamos la funcion
                    acDataProvider.filterFunction = busca;
                }
                else
                {
                    //si esta vacia, quitamos la funcion de filtrado
                    acDataProvider.filterFunction = null;
                }
                //despues de cualquier filterFunction, se tiene que aplicar el metodo refresh
                acDataProvider.refresh();
            }
            
            private function busca(item:Object):Boolean
            {
                //variable de retorno
                var ret:Boolean = false;
                //variable que almacenara el nombre de cada indice del elemento
                var p:String = "";
                //variable que almacenara el valor del elemento
                var str:String = "";
                //recorro cada indice del elemento
                for (p in item)
                {
                    //no quiero que busque en la propiedad mx_internal_uid
                    if (p != "mx_internal_uid")
                    {
                        //recupero el valor del elemento y lo convierto a minusculas
                        str = String(item[p]).toLowerCase();
                        //veo si la cadena de busqueda existe en el valor del elemento
                        if (str.indexOf(str2search) != -1)
                        {
                            //si existe, regreso un true para que el elemento sea agregado al proveedor
                            ret = true;
                            //termino el ciclo, no hay necesidad de seguir buscando
                            break;
                        }
                    }
                }
                //regreso el valor Boolean
                return ret;
            }

        ]]>
    </fx:Script>
    <s:HGroup width="100%" horizontalAlign="right">
        <flexlib:PromptingTextInput id="tiBuscar" prompt="Buscar..." change="tiBuscar_changeHandler(event)"/>
    </s:HGroup>
    <s:ComboBox dataProvider="{acDataProvider}" labelField="nick" width="100%"/>
    <mx:AdvancedDataGrid dataProvider="{acDataProvider}" width="100%" height="150" designViewDataType="flat">
        <mx:columns>
            <mx:AdvancedDataGridColumn headerText="Nombre" dataField="nombre"/>
            <mx:AdvancedDataGridColumn headerText="Nick" dataField="nick"/>
            <mx:AdvancedDataGridColumn headerText="Clablevel" dataField="clablevel"/>
        </mx:columns>
    </mx:AdvancedDataGrid>
    <s:List dataProvider="{acDataProvider}" width="100%" labelField="nick" height="150"/>
</s:Application>


Nota: el ejemplo fue hecho en Flash Builder 4 con el Flex SDK 4.0, si se quisiera probar en Flex Builder 3 únicamente se cambian los componentes por los mx y el código en AS3 quedaría igual.

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Publica tu comentario

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate