Blz?!
Quando comecei a trabalhar com Flex um dos componentes mais bacanas que eu encontrei foi o AutoComplete da Adobe.
Mas olhando o source o compenente vi que é baseado em um ComboBox oque para mim não ajuda muito porque eu já tenho um componente baseado no TextInput que contém várias implementações, máscara, UpperCase, Numerico, ou seja, ter que reescrever essas implementações para o AutoComplete seria perder tempo e aumentar o nível de complexidade de manutenção, oque é um tiro no pé e como eu não gosto de atirar no meu pé eu escrevi o componente FAutoComplete que é baseado em um TextInput. Vão observar que eu fiz extends para o FTextInput, basta substituir por TextInput.
Há comentários no fonte então a história acaba aqui e vamos ao source.
Source da classe
package Componente {
import flash.events.Event;
import flash.events.KeyboardEvent;
import mx.collections.ArrayCollection;
import mx.controls.ComboBox;
import mx.controls.TextInput;
import mx.events.DropdownEvent;
public class FAutoComplete extends FTextInput {
private var
FField: String = '',
FDataProvider: ArrayCollection = new ArrayCollection(),
_uCombo: ComboBox = new ComboBox();
[Inspectable(
category = "eduarmstrong",
defaultValue = ""
)]
public function get LabelField(): String {
return(FField);
}
public function set LabelField(AField: String): void {
FField = AField;
}
[Inspectable(
category = "eduarmstrong",
defaultValue = ""
)]
public function get DataProvider(): ArrayCollection {
return FDataProvider;
}
public function set DataProvider(ADataProvider: ArrayCollection): void {
var
I: int;
// Faz add do todos os item usando um for para não alterar a estrutura do arrayCollection
for (I = 0; I < ADataProvider.length; I++)
FDataProvider.addItem(ADataProvider[I]);
}
public function FAutoComplete() {
// Listener para os eventos observados
addEventListener(Event.CHANGE, proChangeEvent);
addEventListener(KeyboardEvent.KEY_DOWN, proKeyDownEvent);
super();
}
private function proKeyDownEvent(EvKey: KeyboardEvent): void {
// Quando o usuário pressionar a seta para baixo muda o foco para comboBox
if (EvKey.keyCode == 40) {
if (_uCombo.visible)
_uCombo.setFocus();
}
// Quando usuário pressionar Ctrl + ESPAÇO abre a lista completa
else if (EvKey.ctrlKey && EvKey.keyCode == 32) {
// Removo o filtro
FDataProvider.filterFunction = null;
FDataProvider.refresh();
// Exibe a comboBox
_uCombo.open();
_uCombo.visible = true;
_uCombo.selectedIndex = 0;
}
}
private function proChangeEvent(EvChange: Event): void {
if (text != '') {
FDataProvider.filterFunction = fncFiltraDataProvider;
FDataProvider.refresh();
function fncFiltraDataProvider(Item: Object): Boolean {
var
_rConsiste: Boolean,
_rTamanho: int;
// Tamanho da String digitada
_rTamanho = text.length;
// Filtro para simular like ' %' do SQL
if (String(Item[FField]).toUpperCase().substr(0, _rTamanho) == text.toUpperCase())
_rConsiste = true;
else
_rConsiste = false;
return _rConsiste;
}
/* Depois de aplicar a filterFunction se ainda "existir"
dados no arrayCollection abre a comboBox */
if (FDataProvider.length > 0) {
_uCombo.open();
_uCombo.visible = true;
}
else
proHideCombo();
}
else
proHideCombo();
}
private function proHideCombo(): void {
_uCombo.close();
_uCombo.visible = false;
setFocus();
}
private function proCloseComboBox(EvClose: DropdownEvent): void {
proHideCombo();
text = _uCombo.selectedItem.DS;
}
override protected function createChildren(): void {
super.createChildren();
// Configuração para comboBox
_uCombo.labelField = FField;
_uCombo.selectedIndex = - 1;
_uCombo.setStyle('arrowButtonWidth', '0');
_uCombo.editable = true;
_uCombo.visible = false;
_uCombo.addEventListener(DropdownEvent.CLOSE, proCloseComboBox);
_uCombo.dataProvider = FDataProvider;
addChild(_uCombo);
}
override protected function updateDisplayList(w:Number, h:Number): void {
super.updateDisplayList(w, h);
_uCombo.width = width;
_uCombo.x = 0;
_uCombo.y = (height + 2);
}
}
}
Como utilizar
[Bindable]
private var
_rDado: ArrayCollection = new ArrayCollection([
{CD: '1', DS:'Andriano'},
{CD: '2', DS:'Adriana'},
{CD: '3', DS:'Ana'},
{CD: '4', DS:'Amanda'},
{CD: '5', DS:'Beatriz'},
{CD: '6', DS:'Beti'},
{CD: '7', DS:'Barbara'},
{CD: '8', DS:'Bia'},
{CD: '9', DS:'Francisco'},
{CD: '10', DS:'Fred'},
{CD: '11', DS:'Floriano'}
]);
// DataProvider - Informa o ArrayCollection que servirá de base para o componente
// LabelField - Qual field dentro do ArrayCollection deverá ser listado
Bons estudos e bom trabalho a todos.
Abraços


2 comentários:
Perfeito.
Só fiz alguns ajustes, por exemplo: Quando seta pra baixo, não ia direto pro primeiro item do combo, ajustei pra ir; e Quando seleciona o item, mandar foco pro final da palavra, antes ficava na letra digitada.
Obrigada ;)
Muito obrigado, fico contente em saber que o post foi aproveitado.
Se puder compartilhar as melhorais =D
Obrigado.
Postar um comentário