• Artigos
  • Projetos
  • Download
  • Lista
  • Docs
  • Comunidade
  • ?

Máscara de formatação

30/01/2007  Leonardo Castilhos Thibes  Ler e Comentar

Neste meu primeiro artigo para a comunidade estou postando uma adaptação da classe Gtk2_EntryMask desenvolvida inicialmente pelo Pablo Dall'Oglio para formatação de campos entry.

A classe foi adaptada para uso em conjunto com o Glade, funcionalidade que antes não havia.

Agora é possível aplicar a funcionalidade de máscaras de formatação nos campos entry feitos no Glade, e não mais "na mão" como era o funcionamento anterior da classe.

É importante enfatizar que a classe foi desenvolvida pelo Pablo Dall'Oglio, eu apenas fiz uma adaptação das funcionalidades que já existiam.

Espero que aproveitem bem esta minha primeira contribuíção, que eu espero ser a primeira de muitas.

Leonardo C. Thibes


XML DO GLADE
---------------------------------------------------------
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">

<glade-interface>

<widget class="GtkWindow" id="window1">
  <property name="width_request">278</property>
  <property name="height_request">100</property>
  <property name="title" translatable="yes">Máscara de Formatação</property>
  <property name="type">GTK_WINDOW_TOPLEVEL</property>
  <property name="window_position">GTK_WIN_POS_NONE</property>
  <property name="modal">False</property>
  <property name="resizable">True</property>
  <property name="destroy_with_parent">False</property>
  <property name="decorated">True</property>
  <property name="skip_taskbar_hint">False</property>
  <property name="skip_pager_hint">False</property>
  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
  <property name="focus_on_map">True</property>
  <property name="urgency_hint">False</property>

  <child>
    <widget class="GtkFixed" id="fixed1">
      <property name="visible">True</property>

      <child>
    <widget class="GtkEntry" id="entry1">
      <property name="width_request">160</property>
      <property name="height_request">27</property>
      <property name="visible">True</property>
      <property name="can_focus">True</property>
      <property name="editable">True</property>
      <property name="visibility">True</property>
      <property name="max_length">0</property>
      <property name="text" translatable="yes"></property>
      <property name="has_frame">True</property>
      <property name="invisible_char">•</property>
      <property name="activates_default">False</property>
    </widget>
    <packing>
      <property name="x">105</property>
      <property name="y">7</property>
    </packing>
      </child>

      <child>
    <widget class="GtkButton" id="button1">
      <property name="width_request">55</property>
      <property name="height_request">29</property>
      <property name="visible">True</property>
      <property name="can_focus">True</property>
      <property name="label" translatable="yes">OK</property>
      <property name="use_underline">True</property>
      <property name="relief">GTK_RELIEF_NORMAL</property>
      <property name="focus_on_click">True</property>
    </widget>
    <packing>
      <property name="x">104</property>
      <property name="y">48</property>
    </packing>
      </child>

      <child>
    <widget class="GtkLabel" id="label1">
      <property name="width_request">96</property>
      <property name="height_request">17</property>
      <property name="visible">True</property>
      <property name="label" translatable="yes">Máscara Padrão</property>
      <property name="use_underline">False</property>
      <property name="use_markup">False</property>
      <property name="justify">GTK_JUSTIFY_LEFT</property>
      <property name="wrap">False</property>
      <property name="selectable">False</property>
      <property name="xalign">0.5</property>
      <property name="yalign">0.5</property>
      <property name="xpad">0</property>
      <property name="ypad">0</property>
      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
      <property name="width_chars">-1</property>
      <property name="single_line_mode">False</property>
      <property name="angle">0</property>
    </widget>
    <packing>
      <property name="x">5</property>
      <property name="y">11</property>
    </packing>
      </child>
    </widget>
  </child>
</widget>

</glade-interface>
---------------------------------------------------------

PHP QUE MONTA A TELA
---------------------------------------------------------
<?php

require_once('EntryMask.class.php');

class 
janela {
    
    public function 
__construct() {
        
        
//Glade
        
$this->glade = new GladeXML('masks.glade');

        
//EntryMask
        
$this->EntryMask = new EntryMask();
        
        
//Window
        
$this->win = $this->glade->get_widget('window1');
        
$this->win->connect('destroy',array($this,'close'));
        
        
//Entry1
        
$this->entry1 = $this->glade->get_widget('entry1');
        
$this->EntryMask->setMask($this->entry1, '999.999.999-99');

        
//Button
        
$this->button = $this->glade->get_widget('button1');
        
$this->button->connect('clicked', array($this, 'close'));
        
        
//Show_all
        
$this->win->show_all();
    }
    
    public function 
close() {
        echo 
$this->entry1->get_text() . "\n";
        
gtk::main_quit();
    }
    
}

new 
janela();
GTK::Main();

?>
---------------------------------------------------------

A CLASSE PROPRIAMENTE DITA
---------------------------------------------------------
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */

/**
* GtkEntry with mask validation
*
* @category   Gtk2
* @package    Gtk2_EntryMask
* @author     Pablo Dall'Oglio <pablo@php.net>
* @author      Leonardo Castilhos Thibes <leonardothibes@yahoo.com.br>
* @license    LGPL
* @version    $Id: EntryMask.class.php,v 1.0 2007/01/30 11:37:43 leonardo Exp $
*/
class EntryMask {

    
/**
     * Characters used to format mask
     * @var array
     */
    
private $chars;
    
    
/**
     * The Mask applied to the GtkEntry
     * @var string
     */
    
private $mask;
    
    
/**
     * The GtkEntry object
     * @var $object
     */
    
private $object;

    
/**
     * The Signal handler that is fired when the user types something
     * @var integer
     */
    
private $handler;
    
    
/**
     * constructor.
     */
    
public function __construct() {}

    
/**
     * Setando máscara.
     * 
     * @param string $mask the allowed mask
     * @param object $object GtkEntry Object
     */
    
public function setMask($object, $mask) {
        
        
/** Obtebdo objeto GtkEntry **/
        
$this->obj = $object;
        
        
/** Obtendo máscara **/
        
$this->mask = $mask;
        
        
/** Setando tamanho máximo do campo **/
        
$this->obj->set_max_length(strlen(trim($mask)));

        
/** Array de separadores **/
        
$this->chars = array('-', '_', '.', ',', '/', '\\', ':', '|', '(', ')', '[', ']', '{', '}');
        
        
/** Conectando o sinal "changed" ao metodo onChange **/
        
$this->handler = $this->obj->connect('changed', array($this, 'onChange'));        
    }

    
/**
     * whenever the user types something the content is validated according to
     * the mask.
     */
    
public function onChange() {
     
        
/** Setando o texto **/
        
$text = $this->obj->get_text();
     
        
/** Removendo separadores **/
        
$text = $this->unMask($text);
        
        
/** Obtendo o tamanho do texto **/
        
$len = strlen(trim($text));
        
        
/** Aplicando a máscara **/
        
$new = $this->Mask($this->mask, $text);
        
        
/** Agendando novo conteúdo **/
        
Gtk::timeout_add(1, array($this, 'Set'), $new);
        
Gtk::timeout_add(1, array($this, 'Validate'));
    }

    
/**
     * changes the Entry contents without fire "changed" signal
     * @param string $text the new text
     */
    
public function Set($text) {
        
        
/** Desconectando o sinal "changed" do metodo "onChange" **/
        
$this->obj->disconnect($this->handler);
        
        
/** Setando o texto do entry **/
        
$this->obj->set_text($text);
        
        
/** Posicionando o cursor no final do texto **/
        
$this->obj->select_region(-1,-1);
        
        
/** Conectando novamente o sinal "changed" no metodo "onChange" **/
        
$this->handler = $this->obj->connect_after('changed', array($this, 'onChange'));
    }

    
/**
     * Validate the content of GtkEntry
     */
    
public function Validate() {
        
        
/** Obtendo texto do objeto **/
        
$text = $this->obj->get_text();
        
        
/** Obtendo máscara **/
        
$mask = $this->mask;
        
        
/** Obtendo tamanho do texto **/
        
$len = strlen($text);
        
        
$text_char = substr($text, $len-1, 1);
        
$mask_char = substr($mask, $len-1, 1);
        
        
/** Comparando os caracteres digitados com a máscara **/
        
if ($mask_char == '9')
            
$valid = ereg('([0-9])', $text_char);
        elseif (
$mask_char == 'a')
            
$valid = ereg('([a-z])', $text_char);
        elseif (
$mask_char == 'A')
            
$valid = ereg('([A-Z])', $text_char);
        elseif (
$mask_char == 'X')
            
$valid = (ereg('([a-z])', $text_char) or
                     
ereg('([A-Z])', $text_char) or
                     
ereg('([0-9])', $text_char));
        
/** Comparando os caracteres digitados com a máscara **/
        
        /** Caracteres que não se aplicam no escopo da máscara são removidos **/
        
if (!$valid) {
            
$this->Set(substr($text, 0, -1));
        }
    }

    
/**
     * put the typed content in the mask format
     * @param string $mask the mask
     * @param string $text the content
     */
    
public function Mask($mask, $text) {
        
        
/** Run through the mask chars **/
        
$z = 0;
        for (
$n=0; $n < strlen($mask); $n++) {
            
$mask_char = substr($mask, $n, 1);
            
$text_char = substr($text, $z, 1);
            
            
/** Check when has to concatenate with the separator **/
            
if(in_array($mask_char, $this->chars)) {
                if(
$z < strlen($text)) {
                    
$result .= $mask_char;
                }
            } else {
                
$result .= $text_char;
                
$z++;
            }
        }
        
        return 
$result;
    }
    
    
/**
     * removes the mask from text
     * @param string $text the content
     */
    
public function unMask($text) {
        
        
/** Run through the content **/
        
for ($n=0; $n <= strlen($text); $n++) {
            
$char = substr($text, $n, 1);
            
            
/** Check if it's a separator **/
            
if (!in_array($char, $this->chars)) {
                
$result .= $char;
            }
        }
        
        return 
$result;
    }
    
}

?>
---------------------------------------------------------




Comentários

  :) 

Só falta agora uma classe pra formatar moedas e outra pra permitir só números, independente do tamanho do texto. Tipo assim, eu defino como "0" o parâmetro e ele só permite inserir números, ao invés de eu ter que digitar "00000", pois pode ser que o usuário precise digitar um número de 6 algarismos.
Mas já é um começo.

  Enviado por Klawdyus em 2008-03-21  

  Muito bom! 

Gostei muito! Só fiz uma pequena modificação no separador para incluir o espaço (' '). Eu por exemplo formato campo de telefone da seguinte maneira:
(99) 9999-9999, e o espaço nao estava entrando! :-)
No resto, funcionou muito bem, só meio chato pra formatar vários campos, tive que declarar um a um!
ex.:
$this->EntryMask10 = new EntryMask();
$this->EntryMask10->setMask($this->get_widget('cep'), '99.999-999');
$this->EntryMask11 = new EntryMask();
$this->EntryMask11->setMask($this->get_widget('cpf'), '999.999.999-99');

Alguma sugestão?

Um abraço!

  Enviado por Antonio Carlos Dias Junior em 2008-02-20  

  Otimo 

Ficou otimo, não sabia dessa tecnica, vou procurar desenvolver novos componentes baseado nesta tecnica de poo

  Enviado por Edivan carneiro em 2007-05-01  

  Show 

Parabéns,Cara!!!
Isso que eu estava querendo para fazer a minha aplicação...

  Enviado por Fernando Henrique Correa em 2007-01-30  

 Adicionar Comentário
 login
 Senha
 Título
 Comentário

Livros


  • Artigos

    • DOM XML com cara de PHP5 no PHP4
    • PHP-GTK é destaque em Notícia

    Projetos

    • pSheet!
    • Agata
    • Escalonador de CPU
    • Sistema de Controle de Agendas
  • Google

    Parceiros

 
Designed by Wolfgang Bartelme Designed by Wolfgang Bartelme

© 2006 Wordpress Themes | Theme (Not so) Fresh
XHTML CSS

PHP-GTK Brasil