Segunda-feira, Janeiro 30, 2012

como fazer mascara em campos - passo a passo

De

Flavio Lichtenstein flalix@gmail.com para a lista web2py users brasil:
 

Ola pessoal, consegui fazer as máscaras de CEP, Telefone, etc dentro do Web2Py. A seguir vai a "receita de bolo":

1) adicionar código em web2py_ajax.html
response.files.insert(3,URL(r=request,c='static',f='js/jquery.maskedinput-1.3.min.js'))

cuidado! o número três é porque já havia as referencias 0,1 e2 - cuiado para sequenciar corretamente
2) no final da(s) página(s) onde está seu código - normalmente default\minha_pagina.html, adicionar os filtros necessários como vistos abaixo - adeque à sua realidade:

 
         

   a) "pessoa" é nome da sua tabela
   b) maskMoney() não é necessário só para quem usar $$$

3) adicionar o JS de mascara em static\js - ver no final deste email 

4) em _utils (ou rotina inicial que adotar) colocar a classe que Bruno enviou --> repare que alterei  para funcionar "no meu código" (Bruno, obrigado por ter enviado e alertado)

# do Bruno Rocha em 23/01/2012
class REMOVE_MASK(object):
    def __init__(self, symbols=["_",".","-","/",")","("," "]):
        # print 'symbols', symbols
        self.symbols = symbols

    def __call__(self, value):
            for symbol in self.symbols:
                value = value.replace(symbol, "")
                # print 'value',value
                # print 'symbol', symbol
            return (value, None)

5) nas definições do(s) campo(s) da(s) tabela(s) onde ocorrerem a máscara deve-se adicionar  "REMOVE_MASK" (como alertou Bruno) de forma que os caracteres sejem removidos "antes do post"

exemplo:

SQLField('cpf','string', length=11, unique=True, label="CPF", \
                comment="cadastro de pessoa física", requires=REMOVE_MASK([".", "-"])),

---------------------------------------------------------------------------------------------------------
--- JS - em static\js --> adicionar:  jquery.maskedinput-1.3.min.js --> js da digitalbush
como enviado pela Relsi, veja o email anterior dela, onde pode-se ver um exemplo com html puro - não em Web2py (obrigado Relsi).

---------------------------------------------------------------------------------------------------------
/*
    Masked Input plugin for jQuery
    Copyright (c) 2007-2011 Josh Bush (digitalbush.com)
    Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license
    Version: 1.3
*/
(function(a){var b=(a.browser.msie?"paste":"input")+".mask",c=window.orientation!=undefined;a.mask={definitions:{9:"[0-9]",a:"[A-Za-z]","*":"[A-Za-z0-9]"},dataName:"rawMaskFn"},a.fn.extend({caret:function(a,b){if(this.length!=0){if(typeof a=="number"){b=typeof b=="number"?b:a;return this.each(function(){if(this.setSelectionRange)this.setSelectionRange(a,b);else if(this.createTextRange){var c=this.createTextRange();c.collapse(!0),c.moveEnd("character",b),c.moveStart("character",a),c.select()}})}if(this[0].setSelectionRange)a=this[0].selectionStart,b=this[0].selectionEnd;else if(document.selection&&document.selection.createRange){var c=document.selection.createRange();a=0-c.duplicate().moveStart("character",-1e5),b=a+c.text.length}return{begin:a,end:b}}},unmask:function(){return this.trigger("unmask")},mask:function(d,e){if(!d&&this.length>0){var f=a(this[0]);return f.data(a.mask.dataName)()}e=a.extend({placeholder:"_",completed:null},e);var g=a.mask.definitions,h=[],i=d.length,j=null,k=d.length;a.each(d.split(""),function(a,b){b=="?"?(k--,i=a):g[b]?(h.push(new RegExp(g[b])),j==null&&(j=h.length-1)):h.push(null)});return this.trigger("unmask").each(function(){function v(a){var b=f.val(),c=-1;for(var d=0,g=0;de.placeholder;while(g++length){var m=b.charAt(g-1);if(h[d].test(m)){l[d]=m,c=d;break}}if(g>b.length)break}else l[d]==b.charAt(g)&&d!=i&&(g++,c=d);if(!a&&c+10,k);else if(a||c+1>=i)u(),a||f.val(f.val().substring(0,c+1));return i?d:j}function u(){return f.val(l.join("")).val()}function t(a,b){for(var c=a;ce.placeholder)}function s(a){var b=a.which,c=f.caret();if(a.ctrlKey||a.altKey||a.metaKey||b<32)return!0;if(b){c.end-c.begin!=0&&(t(c.begin,c.end),p(c.begin,c.end-1));var d=n(c.begin-1);if(dd].test(g)){q(d),l[d]=g,u();var i=n(d);f.caret(i),e.completed&&i>=k&&e.completed.call(f)}}return!1}}function r(a){var b=a.which;if(b==8||b==46||c&&b==127){var d=f.caret(),e=d.begin,g=d.end;g-e==0&&(e=b!=46?o(e):g=n(e-1),g=b==46?n(g):g),t(e,g),p(e,g-1);return!1}if(b==27){f.val(m),f.caret(0,v());return!1}}function q(a){for(var b=a,c=e.placeholder;bif(h[b]){var d=n(b),f=l[b];l[b]=c;if(dh[d].test(f))c=f;else break}}function p(a,b){if(!(a<0)){for(var c=a,d=n(b);cif(dl[d],l[d]=e.placeholder;else break;d=n(d)}u(),f.caret(Math.max(j,a))}}function o(a){while(--a>=0&&!h[a]);return a}function n(a){while(++a<=k&&!h[a]);return a}var f=a(this),l=a.map(d.split(""),function(a,b){if(a!="?")return g[a]?e.placeholder:a}),m=f.val();f.data(a.mask.dataName,function(){return a.map(l,function(a,b){return h[b]&&a!=e.placeholder?a:null}).join("")}),f.attr("readonly")||f.one("unmask",function(){f.unbind(".mask").removeData(a.mask.dataName)}).bind("focus.mask",function(){m=f.val();var b=v();u();var c=function(){b==d.length?f.caret(0,b):f.caret(b)};(a.browser.msie?c:function(){setTimeout(c,0)})()}).bind("blur.mask",function(){v(),f.val()!=m&&f.change()}).bind("keydown.mask",r).bind("keypress.mask",s).bind(b,function(){setTimeout(function(){f.caret(v(!0))},0)}),v()})}})})(jQuery)

Terça-feira, Maio 03, 2011

sistemas para gerenciamento de projetos opensource



Collabtive http://collabtive.o-dyn.de/ (php)
ProjectPier http://www.projectpier.org/ (php)
Redmine http://www.redmine.org/ (ruby)
DotProject http://www.dotproject.net/ (php)



Domingo, Abril 24, 2011

Otimizando Postgresql Shared_buffers

Para isso, antes, é necessário alterar o limite de shared_memory do sistema

(retirado de http://developer.postgresql.org/pgdocs/postgres/kernel-resources.html e http://www.sqlmagazine.com.br/Artigos/Postgre/02_Otimizacao.asp)

sysctl -w kernel.shmmax=879869184 #aproximadamente 800MB
 sysctl -w kernel.shmall=4194304 #4kb

ou 

echo 8179869184 > /proc/sys/kernel/shmmax
echo 4194304 > /proc/sys/kernel/shmall
--
Atenciosamente


Alexandre Andrade
Hipercenter.com Classificados Gratuitos

Sexta-feira, Janeiro 07, 2011

Migrando tipo de campo no web2py em 6 passos


1. crie um segundo campo com tipo de dado desejado na mesma tabela

Field('valor2','decimal(20,2)'),

2. Crie uma rotina de transformação no dado desejado
for row in db(db.execucao_orcamentaria.id>0).select():
    row.update_record(valor2=to_decimal(row.valor))
    
3. Exclua a linha original
    Field('ano_referencia','integer',default=ANO,writable=False),
>deveria estar aquiv
    Field('valor2','decimal(20,2)'),
    Field('data_execucao', 'date',label='Data de Execução da Despesa',requires=data,represent= lambda field: make_data(field))
   
4. insira a nova linha, com o tipo de dado desejado

    Field('ano_referencia','integer',default=ANO,writable=False),
    Field('valor','decimal(20,2)',requires=E_DINHEIRO()),
    Field('valor2','decimal(20,2)'),
    Field('data_execucao', 'date',label='Data de Execução da Despesa',requires=data,represent= lambda field: make_data(field))
   
5. atualize o novo campo com os valores do anterior.

for row in db(db.execucao_orcamentaria.id>0).select():
    row.update_record(valor=row.valor2)
    
6. Exclua o campo 2
--
Atenciosamente


Alexandre Andrade
Hipercenter.com Classificados Gratuitos e Inteligentes

Quarta-feira, Janeiro 05, 2011

Hipercenter Classificados Grátis e Inteligentes

Estou mudando meu site hipercenter.com para um portal de classificados. A idéia é fazer um site de classificados em que a busca avançada facilite encontrar rapidamente o item desejado.

O endereço é http://hipercenter.com ou http://hipercenter.com/classificados


Anunciem à vontade!

Segunda-feira, Novembro 29, 2010

E_DINHEIRO Validador para web2py

Criei um validator para web2py, mas ao nomear, fugi do padrão IS_SOMETHING, já que o formato é específico do Brasil.

Assim, usei E_DINHEIRO, apenas para facilitar a formatação. O tipo de campo para armazenamento deve ser decimal, mas é necessário excluir a linha que possui a palavra 'double' em web2py_ajax.html, pois ele impede a digitação de vírgulas:
-------------------------------------------------------------------------------------------------------------------------------
jQuery('input.double,input.decimal').live('keyup', function(){this.value=this.value.reverse().replace(/[^0-9\-\.]|[\-](?=.)|[\.](?=[0-9]*[\.])/g,'').reverse();});
------------------------------------------------------------------------------------------------------------------------------
Parece que pode ser possível adaptar a linha acima para aceitar vírgulas, quem souber como fazer deixe um comentário.



class E_DINHEIRO(object):
    def __init__(self, format=True, error_message='Digite o valor!'):
        self.format = format
        self.error_message = error_message
    def __call__(self, value):
            

            d=str(value)
            
            d = d.replace('.','')
            
            d = d.replace(',','.')
            
            #return (value, valor[-3:-2])
            try:
                return (d, None)
            except:
                return (d,str(d)+'o valor digitado não é um número válido')
 
    def formatter(self, value):
            value  = str(value)
            c = []
            for d in value:
               if d.isdigit():
                   c.append(d)
            value = str(''.join(c))
            l = len(value) #10 = 1000000000 = 10.000.000,00
            i = l - 2 #8
            p = i / 3 #2
            r = (l % 3) #2
            #p = 3
            pf = i-1
            if l == 1:
                formatado = '0,0'+value
            
            elif l == 2:
                formatado = '0,'+value
            elif l > 2:
                d = ','+value[-2:]
                s = ''
                n = r+1
                s += value[0:r+1]
                if i > 3:
                    while n < i:
                        pt = n + 3
                        s += '.'+ value[n:pt] 
                        n = pt
                                
                formatado = s+d        
            else:
                formatado = value
            return formatado

Use o validator como um validator comum do web2py:

Field('preco','decimal(20,2)',requires=E_DINHEIRO(),represent=lambda field:currency(field), label='Preço'),

Para permitir apresentar o formato quando não está usando formulário,  use:


def currency(value):
  

    import locale
    locale.setlocale( locale.LC_ALL, 'pt_BR.UTF-8' )
    value = locale.currency(value,grouping=True)
    return value

em uma view:

{{=currency(row.preco)}}



--
Atenciosamente

--
=========================
Alexandre Andrade
Hipercenter.com

Quinta-feira, Novembro 25, 2010

Validator IS_CPF_OR_CNPJ para web2py

class IS_CPF_OR_CNPJ(object):

    def __init__(self, format=True, error_message='Digite apenas os números!'):
        self.format = format
        self.error_message = error_message
    def __call__(self, value):
        try:
            #return (value, 'cpf incorreto'+str(value))
            #return (value, 'cpf incorreto'+str(cl))
            c = []
            for d in value:
               if d.isdigit():
                   c.append(d)
            cl = str(''.join(c))
            #return (value, 'cpf incorreto'+str(cl))
            if  len(cl) == 11:
                cpf = cl
                cnpj = None
            elif  len(cl) == 14:
                cpf = None
                cnpj = cl
            else:
                return (value, 'Número de dígitos incorreto para CPF ou CNPJ')

            #return(cpf,'aquiok'+str(len(cpf)==11))
            if cpf:
              
                def valida(value):
                  
                    def calcdv(numb):
                      
                        result = int()
                        seq = reversed(((range(9, id_type[1], -1)*2)[:len(numb)]))
                        #return (value,'to fundo1')
                        for digit, base in zip(numb, seq):
                            result += int(digit)*int(base)
              
                        dv = result % 11
                        #return (value,'to fundo1'+str(dv))
                        return (dv-10) and dv or 0
                  
                    id_type = ['CPF', -1]
                  
                  
                    numb, xdv = value[:-2], value[-2:]
                  
                    dv1 = calcdv(numb)
                    #return (value,'entrei'+str(dv1))
                    dv2 = calcdv(numb + str(dv1))
                    return (('%d%d' % (dv1, dv2) == xdv and True or False), id_type[0])  
          
          
                try:
                    cpf=str(value)
                    #return(cpf,'aquiok'+str(len(cpf)==11))
                    if len(cpf)>=11:
                      
                        #return (value, 'cpf acima de 11')
                        c = []
                        for d in cpf:
                           if d.isdigit():
                               c.append(d)
                        cl = str(''.join(c))
                        #return (value, 'cpf incorreto'+str(cl))
                        if  len(cl) == 11:
                            if valida(cl)[0] == True:
                                return(value,None)
                            else:
                                return (value, 'cpf inválido')
                        elif  len(cl) < 11:
                            return (value, 'cpf incompleto')
                        else:
                            return (value, 'cpf tem mais de 11 dígitos')
                        if cpf[3] != '.' or cpf[7] != '.' or cpf[11] != '-' :
                            return (value, 'cpf deve estar no formato 000.000.000-00'+cpf[11])
                    else:
                        return (value, 'cpf deve estar no formato 000.000.000-00')
                    #return(cpf,'aquiok'+str(len(cpf)==11))
                except:
                    return (value, 'algum erro'+str(value))
            elif cnpj:

                   """ Pega apenas os 12 primeiros dígitos do CNPJ e gera os 2 dígitos que faltam """
                   inteiros = map(int, cnpj)
                   novoCnpj = inteiros[:12]

                   prod = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
                   while len(novoCnpj) < 14:
                      r = sum([x*y for (x, y) in zip(novoCnpj, prod)]) % 11
                      if r > 1:
                         f = 11 - r
                      else:
                         f = 0
                      novoCnpj.append(f)
                      prod.insert(0, 6)
                   #return(str(novoCnpj),'aquiok')
                   """ Se o número gerado coincidir com o número original, é válido """
                   if novoCnpj == inteiros:
                      #cnpj = ''.join(novoCnpj)
                    
                      return(str(cnpj),None)

                   else:
                      return (value, 'CNPJ não é válido')
              


        except:
            return (value, 'algum erro'+str(value))
    def formatter(self, value):
            if len(value)==11:
                formatado = value[0:3]+'.'+value[3:6]+'.'+value[6:9]+'-'+value[9:11]
            elif len(value)==14:
                formatado = value[0:2]+'.'+value[2:5]+'.'+value[5:8]+'/'+value[8:12]+'-'+value[12:14]
            else:
                formatado = value
            return formatado

Validator TELEFONE para web2py: IS_TELEFONE

Também tive que criar um validator para telefone, com ddd


class IS_TELEFONE(object):
    def __init__(self, format=True, error_message='Digite apenas os números!'):
        self.format = format
        self.error_message = error_message
    def __call__(self, value):
        try:
            telefone=str(value)
            #return(cpf,'aquiok'+str(len(cpf)==11))
            if len(telefone)>=10:
                #return (value, 'cpf acima de 11')
                c = []
                for d in telefone:
                   if d.isdigit():
                       c.append(d)
                cl = str(''.join(c))
                #return (value, 'cpf incorreto'+str(cl))
                if  len(cl) == 10:
                    return(str(cl),None)
                elif  len(cl) < 10:
                    return (value, 'telefone incompleto')
                else:
                    return (value, 'o telefone tem mais de 10 dígitos')
                if cpf[2] != '-' or cpf[7] != '-':
                    return (value, 'o telefone deve estar no formato 00-0000-0000')
            else:
                return (value, 'O telefone deve estar no formato 00-0000-0000')
            #return(cpf,'aquiok'+str(len(cpf)==11))
        except:
            return (value, 'algum erro'+str(value))
    def formatter(self, value):
            if len(value) == 10:
                formatado = value[0:2]+'-'+value[2:6]+'-'+value[6:10]
            else:
                formatado = value      
            return formatado


--
Atenciosamente

--
=========================
Alexandre Andrade
Hipercenter.com

Validator CPF para web2py: IS_CPF

Por necessidade, criei um validator para ser usado no Web2py:


class IS_CPF(object):
    def __init__(self, format=True, error_message='Digite apenas os números!'):
        self.format = format
        self.error_message = error_message
    def __call__(self, value):

        def valida(value):
          
            def calcdv(numb):
              
                result = int()
                seq = reversed(((range(9, id_type[1], -1)*2)[:len(numb)]))
                #return (value,'to fundo1')
                for digit, base in zip(numb, seq):
                    result += int(digit)*int(base)
      
                dv = result % 11
                #return (value,'to fundo1'+str(dv))
                return (dv-10) and dv or 0
          
            id_type = ['CPF', -1]
          
          
            numb, xdv = value[:-2], value[-2:]
          
            dv1 = calcdv(numb)
            #return (value,'entrei'+str(dv1))
            dv2 = calcdv(numb + str(dv1))
            return (('%d%d' % (dv1, dv2) == xdv and True or False), id_type[0])  
  
  
        try:
            cpf=str(value)
            #return(cpf,'aquiok'+str(len(cpf)==11))
            if len(cpf)>=11:
              
                #return (value, 'cpf acima de 11')
                c = []
                for d in cpf:
                   if d.isdigit():
                       c.append(d)
                cl = str(''.join(c))
                #return (value, 'cpf incorreto'+str(cl))
                if  len(cl) == 11:
                    if valida(cl)[0] == True:
                        return(value,None)
                    else:
                        return (value, 'cpf inválido')
                elif  len(cl) < 11:
                    return (value, 'cpf incompleto')
                else:
                    return (value, 'cpf tem mais de 11 dígitos')
                if cpf[3] != '.' or cpf[7] != '.' or cpf[11] != '-' :
                    return (value, 'cpf deve estar no formato 000.000.000-00'+cpf[11])
            else:
                return (value, 'cpf deve estar no formato 000.000.000-00')
            #return(cpf,'aquiok'+str(len(cpf)==11))


        except:
            return (value, 'algum erro'+str(value))
    def formatter(self, value):
          
            formatado = value[0:3]+'.'+value[3:6]+'.'+value[6:9]+'-'+value[9:11]
            #formatado = value
            return formatado

--
Atenciosamente

--
=========================
Alexandre Andrade
Hipercenter.com