• Artigos
  • Projetos
  • Download
  • Docs
  • Enviar Artigo
  • Sobre

Máscara de formatação

30/01/2007  Leonardo Castilhos Thibes 

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



  1. XML DO GLADE
  2. ---------------------------------------------------------
  3. <?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
  4. <!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
  5. <glade-interface>
  6. <widget class="GtkWindow" id="window1">
  7.   <property name="width_request">278</property>
  8.   <property name="height_request">100</property>
  9.   <property name="title" translatable="yes">Máscara de Formatação</property>
  10.   <property name="type">GTK_WINDOW_TOPLEVEL</property>
  11.   <property name="window_position">GTK_WIN_POS_NONE</property>
  12.   <property name="modal">False</property>
  13.   <property name="resizable">True</property>
  14.   <property name="destroy_with_parent">False</property>
  15.   <property name="decorated">True</property>
  16.   <property name="skip_taskbar_hint">False</property>
  17.   <property name="skip_pager_hint">False</property>
  18.   <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
  19.   <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
  20.   <property name="focus_on_map">True</property>
  21.   <property name="urgency_hint">False</property>
  22.   <child>
  23.     <widget class="GtkFixed" id="fixed1">
  24.       <property name="visible">True</property>
  25.       <child>
  26.     <widget class="GtkEntry" id="entry1">
  27.       <property name="width_request">160</property>
  28.       <property name="height_request">27</property>
  29.       <property name="visible">True</property>
  30.       <property name="can_focus">True</property>
  31.       <property name="editable">True</property>
  32.       <property name="visibility">True</property>
  33.       <property name="max_length">0</property>
  34.       <property name="text" translatable="yes"></property>
  35.       <property name="has_frame">True</property>
  36.       <property name="invisible_char">•</property>
  37.       <property name="activates_default">False</property>
  38.     </widget>
  39.     <packing>
  40.       <property name="x">105</property>
  41.       <property name="y">7</property>
  42.     </packing>
  43.       </child>
  44.       <child>
  45.     <widget class="GtkButton" id="button1">
  46.       <property name="width_request">55</property>
  47.       <property name="height_request">29</property>
  48.       <property name="visible">True</property>
  49.       <property name="can_focus">True</property>
  50.       <property name="label" translatable="yes">OK</property>
  51.       <property name="use_underline">True</property>
  52.       <property name="relief">GTK_RELIEF_NORMAL</property>
  53.       <property name="focus_on_click">True</property>
  54.     </widget>
  55.     <packing>
  56.       <property name="x">104</property>
  57.       <property name="y">48</property>
  58.     </packing>
  59.       </child>
  60.       <child>
  61.     <widget class="GtkLabel" id="label1">
  62.       <property name="width_request">96</property>
  63.       <property name="height_request">17</property>
  64.       <property name="visible">True</property>
  65.       <property name="label" translatable="yes">Máscara Padrão</property>
  66.       <property name="use_underline">False</property>
  67.       <property name="use_markup">False</property>
  68.       <property name="justify">GTK_JUSTIFY_LEFT</property>
  69.       <property name="wrap">False</property>
  70.       <property name="selectable">False</property>
  71.       <property name="xalign">0.5</property>
  72.       <property name="yalign">0.5</property>
  73.       <property name="xpad">0</property>
  74.       <property name="ypad">0</property>
  75.       <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
  76.       <property name="width_chars">-1</property>
  77.       <property name="single_line_mode">False</property>
  78.       <property name="angle">0</property>
  79.     </widget>
  80.     <packing>
  81.       <property name="x">5</property>
  82.       <property name="y">11</property>
  83.     </packing>
  84.       </child>
  85.     </widget>
  86.   </child>
  87. </widget>
  88. </glade-interface>
  89. ---------------------------------------------------------
  90. PHP QUE MONTA A TELA
  91. ---------------------------------------------------------
  92. <?php
  93. require_once('EntryMask.class.php');
  94. class janela {
  95.     
  96.     public function __construct() {
  97.         
  98.         //Glade
  99.         $this->glade = new GladeXML('masks.glade');
  100.         //EntryMask
  101.         $this->EntryMask = new EntryMask();
  102.         
  103.         //Window
  104.         $this->win = $this->glade->get_widget('window1');
  105.         $this->win->connect('destroy',array($this,'close'));
  106.         
  107.         //Entry1
  108.         $this->entry1 = $this->glade->get_widget('entry1');
  109.         $this->EntryMask->setMask($this->entry1, '999.999.999-99');
  110.         //Button
  111.         $this->button = $this->glade->get_widget('button1');
  112.         $this->button->connect('clicked', array($this, 'close'));
  113.         
  114.         //Show_all
  115.         $this->win->show_all();
  116.     }
  117.     
  118.     public function close() {
  119.         echo $this->entry1->get_text() . "\n";
  120.         gtk::main_quit();
  121.     }
  122.     
  123. }
  124. new janela();
  125. GTK::Main();
  126. ?>
  127. ---------------------------------------------------------
  128. A CLASSE PROPRIAMENTE DITA
  129. ---------------------------------------------------------
  130. <?php
  131. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  132. /**
  133. * GtkEntry with mask validation
  134. *
  135. * @category   Gtk2
  136. * @package    Gtk2_EntryMask
  137. * @author     Pablo Dall'Oglio <pablo@php.net>
  138. * @author      Leonardo Castilhos Thibes <leonardothibes@yahoo.com.br>
  139. * @license    LGPL
  140. * @version    $Id: EntryMask.class.php,v 1.0 2007/01/30 11:37:43 leonardo Exp $
  141. */
  142. class EntryMask {
  143.     /**
  144.      * Characters used to format mask
  145.      * @var array
  146.      */
  147.     private $chars;
  148.     
  149.     /**
  150.      * The Mask applied to the GtkEntry
  151.      * @var string
  152.      */
  153.     private $mask;
  154.     
  155.     /**
  156.      * The GtkEntry object
  157.      * @var $object
  158.      */
  159.     private $object;
  160.     /**
  161.      * The Signal handler that is fired when the user types something
  162.      * @var integer
  163.      */
  164.     private $handler;
  165.     
  166.     /**
  167.      * constructor.
  168.      */
  169.     public function __construct() {}
  170.     /**
  171.      * Setando máscara.
  172.      * 
  173.      * @param string $mask the allowed mask
  174.      * @param object $object GtkEntry Object
  175.      */
  176.     public function setMask($object, $mask) {
  177.         
  178.         /** Obtebdo objeto GtkEntry **/
  179.         $this->obj = $object;
  180.         
  181.         /** Obtendo máscara **/
  182.         $this->mask = $mask;
  183.         
  184.         /** Setando tamanho máximo do campo **/
  185.         $this->obj->set_max_length(strlen(trim($mask)));
  186.         /** Array de separadores **/
  187.         $this->chars = array('-', '_', '.', ',', '/', '\\', ':', '|', '(', ')', '[', ']', '{', '}');
  188.         
  189.         /** Conectando o sinal "changed" ao metodo onChange **/
  190.         $this->handler = $this->obj->connect('changed', array($this, 'onChange'));        
  191.     }
  192.     /**
  193.      * whenever the user types something the content is validated according to
  194.      * the mask.
  195.      */
  196.     public function onChange() {
  197.      
  198.         /** Setando o texto **/
  199.         $text = $this->obj->get_text();
  200.      
  201.         /** Removendo separadores **/
  202.         $text = $this->unMask($text);
  203.         
  204.         /** Obtendo o tamanho do texto **/
  205.         $len = strlen(trim($text));
  206.         
  207.         /** Aplicando a máscara **/
  208.         $new = $this->Mask($this->mask, $text);
  209.         
  210.         /** Agendando novo conteúdo **/
  211.         Gtk::timeout_add(1, array($this, 'Set'), $new);
  212.         Gtk::timeout_add(1, array($this, 'Validate'));
  213.     }
  214.     /**
  215.      * changes the Entry contents without fire "changed" signal
  216.      * @param string $text the new text
  217.      */
  218.     public function Set($text) {
  219.         
  220.         /** Desconectando o sinal "changed" do metodo "onChange" **/
  221.         $this->obj->disconnect($this->handler);
  222.         
  223.         /** Setando o texto do entry **/
  224.         $this->obj->set_text($text);
  225.         
  226.         /** Posicionando o cursor no final do texto **/
  227.         $this->obj->select_region(-1,-1);
  228.         
  229.         /** Conectando novamente o sinal "changed" no metodo "onChange" **/
  230.         $this->handler = $this->obj->connect_after('changed', array($this, 'onChange'));
  231.     }
  232.     /**
  233.      * Validate the content of GtkEntry
  234.      */
  235.     public function Validate() {
  236.         
  237.         /** Obtendo texto do objeto **/
  238.         $text = $this->obj->get_text();
  239.         
  240.         /** Obtendo máscara **/
  241.         $mask = $this->mask;
  242.         
  243.         /** Obtendo tamanho do texto **/
  244.         $len = strlen($text);
  245.         
  246.         $text_char = substr($text, $len-1, 1);
  247.         $mask_char = substr($mask, $len-1, 1);
  248.         
  249.         /** Comparando os caracteres digitados com a máscara **/
  250.         if ($mask_char == '9')
  251.             $valid = ereg('([0-9])', $text_char);
  252.         elseif ($mask_char == 'a')
  253.             $valid = ereg('([a-z])', $text_char);
  254.         elseif ($mask_char == 'A')
  255.             $valid = ereg('([A-Z])', $text_char);
  256.         elseif ($mask_char == 'X')
  257.             $valid = (ereg('([a-z])', $text_char) or
  258.                      ereg('([A-Z])', $text_char) or
  259.                      ereg('([0-9])', $text_char));
  260.         /** Comparando os caracteres digitados com a máscara **/
  261.         
  262.         /** Caracteres que não se aplicam no escopo da máscara são removidos **/
  263.         if (!$valid) {
  264.             $this->Set(substr($text, 0, -1));
  265.         }
  266.     }
  267.     /**
  268.      * put the typed content in the mask format
  269.      * @param string $mask the mask
  270.      * @param string $text the content
  271.      */
  272.     public function Mask($mask, $text) {
  273.         
  274.         /** Run through the mask chars **/
  275.         $z = 0;
  276.         for ($n=0; $n < strlen($mask); $n++) {
  277.             $mask_char = substr($mask, $n, 1);
  278.             $text_char = substr($text, $z, 1);
  279.             
  280.             /** Check when has to concatenate with the separator **/
  281.             if(in_array($mask_char, $this->chars)) {
  282.                 if($z < strlen($text)) {
  283.                     $result .= $mask_char;
  284.                 }
  285.             } else {
  286.                 $result .= $text_char;
  287.                 $z++;
  288.             }
  289.         }
  290.         
  291.         return $result;
  292.     }
  293.     
  294.     /**
  295.      * removes the mask from text
  296.      * @param string $text the content
  297.      */
  298.     public function unMask($text) {
  299.         
  300.         /** Run through the content **/
  301.         for ($n=0; $n <= strlen($text); $n++) {
  302.             $char = substr($text, $n, 1);
  303.             
  304.             /** Check if it's a separator **/
  305.             if (!in_array($char, $this->chars)) {
  306.                 $result .= $char;
  307.             }
  308.         }
  309.         
  310.         return $result;
  311.     }
  312.     
  313. }
  314. ?>
  315. ---------------------------------------------------------




Crie sistemas de maneira ágil com PHP-GTK:

Adianti Framework para PHP

  • Instalação e configuração;
  • Modelos e persistência;
  • Componentes de apresentação;
  • Organização e controle;
  • Desenvolvimento ágil com Studio Pro.
Ver detalhes...

Tenha mais produtividade com o PHP-GTK:

Adianti Studio: IDE para PHP
  • Leve e rápido;
  • Syntax highlight;
  • Gerência de projetos;
  • Navegação em banco de dados;
  • Autocomplete e plugins.
Mais informações...

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  
  Efetuar Cadastro
  Esqueci a Senha

Livros sobre PHP

Orientação a
objetos
Criando
relatórios
Aplicações
gráficas com Gtk

Comunidade

Busque conteúdo no site
Participe de nosso grupo no google

[Página do grupo]  [Arquivo do grupo]

Ferramentas de desenvolvimento PHP

Conheça o Adianti Framework para PHP:

  • Desenvolvimento com componentes;
  • Formulários e datagrids.
  • Versão Web e Desktop (Gtk);
  • Multiplataforma;
  • Desenhe as interfaces;
  • IDE própria (Adianti Studio).
Ver detalhes...

Tenha mais produtividade com:

Adianti Studio: IDE para PHP

  • Leve e rápido;
  • Syntax highlight;
  • Gerência de projetos;
  • Navegação em banco de dados;
  • Autocomplete e plugins.
Mais informações...

Google

Parceiros

 
Designed by Wolfgang Bartelme Designed by Wolfgang Bartelme

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