sábado, 17 de julho de 2010

Personalizando o componente DateField

Blz?!

Nesse post vou personalizar o componente DataField, vamos ver como usar a propriedade Inspectable já mostrada nesse post.
Além da tradução para português o componente recebeu alguns funções/métodos para facilitar a vida no dia a dia.

1 - DataInicial - Inicializa o componente com a data atual
      - parâmetros: Hoje ou Vazio
2 - CheckDate - Faz a validação da data, mas não interrompe o processo
      - parâmetros: true ou false
3 - KeyDown - Função adicionada para melhorar a usabilidade do componente
      - abre o calendário quando o usuário pressionar a tecla ESPAÇO.


DataInicial e CheckDate você pode setar o valor em modo design equanto a propriedade para abrir o calendário que está atribuída ao evento KeyDown é default no componente e foi criada para melhorar a usabilidade do componente DateField, quanto menos o usuário necessitar do mouse melhor.


    package {
      import flash.events.FocusEvent;
      import flash.events.KeyboardEvent;
      
      import mx.controls.Alert;
      import mx.controls.DateField;
      import mx.events.FlexEvent;
      import mx.events.ValidationResultEvent;
      import mx.validators.DateValidator;
    
      public class FDateField extends DateField {
        [Bindable]
        private var
          FDataInicial: String = 'Vazio',
          FCheckDate: Boolean = true;
          
        [Inspectable(
          category = "eduarmstrong", 
          enumeration = "Hoje,Vazio"
        )]
        public function get DataInicial(): String {
          return(FDataInicial);
        }
        public function set DataInicial(ADataInicial: String): void {
          FDataInicial = ADataInicial;
        }
    
        [Inspectable(
          category = "eduarmstrong", 
          enumeration = "true,false"
        )]
        public function get CheckDate(): Boolean {
          return(FCheckDate);
        }
        public function set CheckDate(ACheckDate: Boolean): void {
          FCheckDate = ACheckDate;
        }
        
        public function FDateField() {
          super();
          // Legenda para os dias da semana
          dayNames = ['D', 'S', 'T', 'Q', 'Q', 'S', 'S'];
          
          // Formato para data
          formatString = 'DD/MM/YYYY';
          
          // Restrict usado para evitar que o usuário digite A-Z
          restrict = "0-9, /";
          
          // Tradução dos meses 
          monthNames = ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 
            'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'];
          
          // Irá permitir que o usuário digite a data
          editable = true;
          
          // Inicia o calendário no Domingo   
          firstDayOfWeek = 0; 
          
          // Habilita a navegação por ano.
          yearNavigationEnabled = true;  
          
          width = 100;
          
          /* Adicionando ao evento de focusOut o método que irá colocar
          máscara na data digitada pelo usuário */
          addEventListener(FocusEvent.FOCUS_OUT, proSetMask, false, 0, true);
          
          /* Adiciona ao evento keyDown o método para "abrir" o calendário
          ao pressionar ESPAÇO */
          addEventListener(KeyboardEvent.KEY_DOWN, proKeyDown, false, 0, true);
          
          // Adicina ao evento creationComplete o método que irá preencher a data
          addEventListener(FlexEvent.CREATION_COMPLETE, proDataInicial, false, 0, true);
        }
        
        private function proDataInicial(E: FlexEvent): void {
          if (FDataInicial == 'Hoje')
             data = new Date();
        }
        
        private function proKeyDown(E: KeyboardEvent): void {
          // Espaço
          if (E.keyCode == 32)
            open();
        }
    
        private function proSetMask(evFocus: FocusEvent): void {
          if ((text.charAt(2) != '/') || (text.charAt(5) != '/')) {
            if (text.length == 6)
              text = text.substr(0, 2) + '/' + text.substr(2,2) + '/' + text.substr(4, 4);
            else if (text.length == 8)
              text = text.substr(0, 2) + '/' + text.substr(2,2) + '/' + text.substr(4, 4);
          }
          
          // Verifica se a opção para validar a data está ativa
          if (FCheckDate)
            proCheckDate();
        }
        
        private function proCheckDate(): void {
          var       
            _rDateValidator: DateValidator = new DateValidator();
            
          _rDateValidator.source = this;
          _rDateValidator.required = false;
          _rDateValidator.property = 'text';
          _rDateValidator.inputFormat = 'dd/mm/yyyy';
          _rDateValidator.allowedFormatChars = '/-';
          _rDateValidator.wrongDayError = 'Favor informar um dia válido para o mês.' 
          _rDateValidator.wrongLengthError = 'Favor informar a data no formato dd/mm/aaaa.' 
          _rDateValidator.wrongMonthError = 'Favor informar um mês entre 1 e 12.' 
          _rDateValidator.validate();
        }
      }
    }
    



    Bons estudos e bom trabalho a todos.

    Abraços

    10 comentários:

    Excelente Explicação..
    Me ajudouu muito =)

    =*

    Muito obrigado Lu, saber que as dicas postadas aqui estão ajudando é um incentivo.

    Obrigado!

    Eduardo, sua dica tem ajudado muitos iniciantes tenho certeza, mas gostaria de lhe pedir uma ajuda.

    Quando estou digitando a data, não está incluindo a contrabarra na data, você poderia me ajudar

    Amarildo,

    Pode me dar exemplos de datas que você digitou? Na minha máquina não tenho mais esse componente e testando esse exemplo publicado a formatação está Ok. Vou tentar simular esse erro que descreu, mas se puder dar mais detalhe me ajuda a identificar a situação e melhorar o código.

    Obrigado pelo feedback

    []´s

    Oi eu sou iniciante no AS3 e preciso muito utilizar esta função dateField gostei do seu exemplo mas como não costumo usar o codigo fora do flash você poderia me dar mais detalhes de como fazer para funcionar? por exemplo qual o codigo que devo colocar no flash para chamar este as e quais objetos deverão ser inseridos?

    Eduardo, volto a procurar tua ajuda, pq ainda não consegui resolver o problema da data, se digitar qq data, ele não coloca as barras. Seu blog tá sendo de muito valia pra mim, pq sou iniciante, mas infelizmente, ainda não tenho conhecimento suficiente pra alterar seus componentes, pois estou apanhando também com o autocomplete, pois os mesmos erros que o cara postou lá, estão acontecendo comigo, só que ele não postou a solução como vc sugeriu. Mesmo assim obrigado pelos posts, estão me ajudando bastante.

    Eduardo
    Muito bom o componente, um detalhe quando digita uma data invalida é mostrado uma mensagem erro, se você digita mais vez errado, é mostrado duas mensagem de erro, ou seja, a cada erro ele vai concatenando as mensagem.
    Obrigado
    Marcos

    Newber, Amarildo e Marcos, antes de mais nada mil desculpas pela demora gigante em voltar ao blog e por ainda não ter respondido nenhuma das perguntas, vou tentar ajudá-los o mais breve possível e muito muito obrigado pelo feedback de vocês!!!

    Como já dizia o poeta Freddy Krueger "vamos por partes"

    Newber, vou ser bem honesto com você, minha experiência com FLASH (puro) é zero então não sei te responder de pronto. Mas vou pesquisar e espero não demorar tanto para te responder.


    Amarildo, não se preocupe com isso, eu apanhei bastante também no começo é assim mesmo depois você percebe que é muito mais simples do que parece. Mas me responda, quando você testa o componente postado no exemplo do blog tbm está ocorrendo o problema de não formatar? pq eu ainda não consegui simular esse erro para te passar uma possível solução. Aguardo teu feedback.


    Marcos, muito obrigado e o erro que você reportou começou a acontecer depois da versão 3.2 do skd, não sei pq e não sei mesmo a partir dai se você debugar vai ver que a propriedade "errorString" agora é um array que vai dando push em cima de push por isso as repetições, a boa notícia que o erro é contornável a ruim é que eu IDIOTAMENTE apaguei a correção mas assim que eu reescrever eu posto aqui p vocês.

    Galera, me desculpem por demorar e responder e não ter ajudado tanto desta vez mas como vocês já sabem, vida de programador é corrida.

    []´s

    bom dia sou iniciante no flex e gostei do seu post! como uso esse código na aplicação?

    Obrigado!

    Para usar o componente há duas maneiras

    1 - Dentro do teu projeto você cria uma nova classe e implementa o código do post (copia e cola, depois é só acertar o pacote conforme a tua aplicação e nome da classe que você escolher).

    2 - Fazer um projeto de biblioteca, implementar a classe. Feito isso vá nas propriedades do projeto que deseja usar o componente e adicione o swc.

    A opção 2 eu considero a melhor pq nessa biblioteca você pode ir engorando com novos componentes, functions...


    Depois de fazer o componente basta arrastar p tua tela, no modo design ele vai aparecer em "custom"


    Qualquer dúvida só avisar.

    []´s

    Postar um comentário

    Twitter Delicious Facebook Digg Stumbleupon Favorites More