DGmike

DGmike

Calma! não entre em pânico! Amanhã (talvez) tem novo post…

  • Alice Andrade
  • Rafael Zamana
Você está aqui: dgmike » cases

  • Home
  • Guia Rápido jQuery
  • Códigos prontos
    • PHP: Função __auloload()
    • Classe sqlsimples e sql – PHP
    • Bancos, bancos e mais bancos…
  • PagSeguro
  • Artigos
    • JavaScript (parte 1)
  • Quem é dgmike?

PagSimples: faça combranças facilmente com o PagSeguro

Posted in Cotidiano, Dia-a-dia, cases, html, icephp, pagseguro by DGmike
Jan 17 2010
TrackBack Address.

Você, assim como eu, já deve ter se deparado com o problema de gerar uma cobrança para alguém através da internet e não queria entrar no painel de controle do PagSeguro e mandar aquele e-mail padrão que eles enviam quando fazem uma cobrança.

Ao invés disso você quer que ele acesse uma url única (bit.ly e tinyurl.com, por exemplo) para que ele possa fazer o pagamento via PagSeguro. Assim você pode fazer o e-mail formatado como você desejar. Talvez você considere essa mesma formula para mandar scraps via Orkut/FaceBook/Twitter/Skype/etc com cobranças ou pagamentos sem que você tenha a necessidade de escrever um formulário nos padrões do PagSeguro.

Mande um e-mail com a sua cobrança de forma simples

Existem inúmeras possibilidades para o PagSimples, use com moderação

Acontece que nem sempre você pode inserir HTML onde você gostaria que as pessoas lhe dessem dinheiro, como um link do youtube. Então faça uma cobrança no PagSimples e mande para quem você quiser.

Veja como é simples: http://pagsimples.dgmike.com.br/p/4b537c4bb8aed

O PagSimples é mais um projeto de uma madrugada (como diria o Marco Gomes) escrito com o Ice-Baby que foi desenvolvido a partir de uma conversa que tive com o Elcio dentro de um taxi.

3 Comments »

[PagSeguro] O campo status

Posted in Programação, cases, pagseguro, sql by DGmike
Sep 15 2009
TrackBack Address.

Uma coisa que sempre me tirou o sono durante a noite era o campo status do PagSeguro. Quando a compra está pronta, quando eu posso confiar em enviar o meu produto. O que significa completo, o que significa aprovado. Quando vem cada um.

Estou há uma semana no UOL junto com o pessoal do PagSeguro e eles tinham uma visão diferente da minha, eles devem saber disso melhor do que eu. Acontece que a regra básica é: “Aprovado” quando o boleto, cartão de crédito, débito ou TCP (transferência entre contas PagSeguro) foi efetivada e aprovada. “Completo” vem um POST após 14 dias informando que aquele valor não tem mais volta, o cliente gostou do serviço/produto e você pode retirar seu dinheiro junto ao PagSeguro.

Bom, resolvi tirar a prova dos sete. Na Visie, nos ajudamos o cliente a implementar o PagSeguro com o retorno automático em sua loja. Então peguei o banco de dados de um cliente aleatório (com as devidas autorizações) para fazer essa pesquisa. Isso foi importante porque assim temos um cliente comum como você ou eu mesmo.

Organizei o log (ainda bem que nós sempre guardamos o log de tudo o que é feito) de informações e joguei no banco de dados com a data de recebimento do POST para ficar mais fácil de visualizar. Organizei os resultados pelo código do pedido e em seguida pela data. Pedi para exibir também o tipo de transação e o status de cada linha. Assim podemos ver o que aconteceu aonde e quando.

Este foi o resultado obtido (os códigos de transação foram cortados para protejer os clientes):

Mas e ae?! Que conclusões podemos tirar disto?

Perceba que, sempre você terá um post de “Aprovado” e um de “Completo”, os que não tem “Completo” é porque ainda não chegou sua data.

Nota: O cliente recebeu alguns POSTs de “Completo” sozinhos porque ele ainda não havia implantado o retorno automático corretamente (era feito na mão). E por isso os POSTs de “Aprovado”/”Em Analise”/”Aguardando Pagto” não foram logados.

O status “Completo” sempre chega 14 dias após o primeiro POST recebido referente à aquela transação. Ou seja, se um boleto foi emitido no dia 1, e aprovado no dia 3 você receberá um “Completo” no dia 15 (quatorze dias após o dia primeiro).

Para boleto, o tempo de “Em Análise” para “Aprovado” pode levar de um a dois dias dependendo do caso. Para boleto, o tempo depende do cliente, isso quer dizer que ele tem três dias para pagar o boleto. Mas você receberá o “Completo” quatorze dias após o “Aguardando Pagto” se no meio existir um “Aprovado”. Ao invés de “Aprovado” o você pode receber um POST de “Cancelado” e aí, não há mais interação.

Nota: Alguns POSTs aparecem repetidos devido a testes realizados durante a implantação.

Bom, isso tira todas as minhas dúvidas. Se você tiver alguma dúvida com relação ao retorno automático do PagSeguro, não exite em perguntar. Não cansarei até descobrir a resposta à sua pergunta :D

2 Comments »
Tagged as: aprovado, campo status, completo, dinheiro, ecommerce, loja, loja online, pagamento digital, pagseguro, retorno automático

Função clone da jQuery e atributo name para IE

Posted in Internet Explorer, Windows, cases, html, jQuery, javascript, plugin, xHTML by DGmike
May 25 2009
TrackBack Address.

Aqui na ACSP, onde estamos desenvolvendo um mega-hiper-ultra-plus-and-is-the-maximun-software-of-the-solar-system sistema ultra-secreto nos deparamos com um problema cabuloso no Browser azul até a versão 7. A idéia é a seguinte: quando um usuário clicar em um determinado botão “adicionar uma cópia” do formulário ele deve copiar o fieldset anterior e colá-lo abaixo do mesmo. Obviamente, devemos alterar o name dos campos para conseguir tratá-los no PHP no server-side. Atente a este ponto, todas as ações aplicadas aos campos devem continuar funcionando, ou seja, se você aplicou um “click”, “change” “blur” ou seja lá o que for, deve continuar funcionando normalmente. Ah sim, vamos utilizar a biblioteca “coisinha bonitinha do papai” jQuery[bb].

JavaScript - Mais uma dica para você

JavaScript - Mais uma dica para você

A melhor forma de resolver esse problema é pensar antes de escrever o código. Mas algumas vezes não conseguimos prever coisas que nem a Microsoft[bb] explica. Então o ideal é fazer uma função que aplique as ações ao formulário assim, podemos usar um template para fazer o clone.

1
2
3
4
5
6
7
8
9
10
11
12
13
$(function(){
  aplica_acoes();
  $('button.duplicar').click('duplica_fieldset');
});
 
function duplica_fieldset() {
  $('fieldset:last').after ('------------ cole aqui o template -----------');
  aplica_acoes();
}
 
function aplica_acoes() {
  $('.campo').click(function (){alert("Hey! Ho!");});
}

O problema disso é ao alterarmos qualquer campo teriamos que alterar o javascript para que o template fique exatamente igual. Outro problema é que ao chamarmos a função aplica_funcoes ele adicionará duas vezes a ação click no campo.

Mas vamos por partes, primeiro o problema do click duplicado. Podemos resolver isso sem problema algum. Basta usar o unbind e bind.

11
12
13
14
15
16
17
18
19
function aplica_funcoes() {
  $('.campo')
    .unbind('click', heyho)
    .bind('click', heyho);
}
 
function heyho() {
  alert("Hey! Ho!");
}

Legal, o que isso faz é remover os eventos click e recoloca-os. Muito bem, também poderiamos usar o live, adicionado na jQuery desde a versão 1.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$(function(){
  aplica_acoes();
  $('button.duplicar').click('duplica_fieldset');
});
 
function duplica_fieldset() {
  $('fieldset:last').after ('------------ cole aqui o template -----------');
}
 
function aplica_funcoes() {
  $('.campo').live('click', heyho);
}
 
function heyho() {
  alert("Hey! Ho!");
}

Assim, todos os campos que forem criados após essa chamada do live, todas as vezes que um elemento com a classe .campo for criado ele já nascerá com a ação click.

Muy biem, compañeros! Vamos ao próximo problema. O template que não deve ficar aqui no javascript e sim clonar o dito cujo. Para isso vamos usar o método clone da jQuery, assim ele copiará o código escrito no próprio html, assim não precisamos dar manutenção no código duas vezes. Veja como é simples usar o clone.

6
7
8
9
function duplica_fieldset() {
  var fls = $('fieldset:last').clone();
  $('fieldset:last').after (fls);
}

Ok, com isso já podemos copiar um fieldset e colar logo abaixo do outro fieldset. Uma coisa muito interessante é que podemos passar o parametro true dentro do clone, assim ele já copia os eventos, fazendo essa alteração nosso script ficará mais ou menos assim (perceba como diminui a quantidade de código).

1
2
3
4
5
6
7
8
9
10
11
12
13
$(function(){
  aplica_acoes();
  $('button.duplicar').click('duplica_fieldset');
});
 
function duplica_fieldset() {
  var fls = $('fieldset:last').clone(true);
  $('fieldset:last').after (fls);
}
 
function aplica_funcoes() {
  $('.campo').click(function(){alert("Hey! Ho!");});
}

E o name?

Agora, vamos ao problema maior, vamos alterar o name para podermos trabalhar no server-side. Tomemos o seguinte template de html:

1
2
3
4
5
<fieldset>
   <label for="nome_123">Nome <input type="text" name="nome_123" id="nome_123" /></label>
   <label for="campo_123">Nome <input type="text" name="campo_123" id="campo_123" class="campo" /></label>
</fieldset>
<button class="duplicar">Nova Assinatura</button>

Perceba que usamos o padrão “123″ em todos os campos, seria o nosso ID temporário para podermos tratar sem problemas no server-side. Então, para alterar o campo deveriamos criar um número aleatório único e alterar via comando attr da jQuery. Algo como isto:

6
7
8
9
10
11
12
13
14
15
16
function duplica_fieldset() {
  var num = ''+(new Date().getTime())+(parseInt(Math.random()*100));
  var fls = $('fieldset:last').clone(true);
  $('[name]', fls).each(function(){
    var lastName = this.name;
    var base = lastName.split('_')[0];
    var newName = base+'_'+num;
    this.name=newName;
  });
  $('fieldset:last').after (fls);
}

Veja, para criar um número aleatório único usei o getTime do objeto Date, assim pegamos os microsegundos que aconteceram naquele momento, um momento único que não se repetirá. E então adicionamos a um número aleatório qualquer. O Math.random() gera um número aleatório entre zero e um, então é necessário multiplicá-lo com um valor multiplo de dez para termos o inteiro desejado. Então usamos o parseInt para converter esse float maluco para inteiro e obtermos apenas o desejado. Perceba que no inicio dessa linha adicionamos uma string vazia, isso para que os dois valores não sejam somados e sim concatenados.

Veja, que logo após chamamos todos os campos que tenham o campo name, isso apenas no nosso fls, clonado anteriormente. Podemos fazer isso com todos os atributos (id, for, class, etc). Aconselho a fazer um each só para não deixar sua aplicação lenta.

Tá, mas qual é o problema com o Internet Explorer?

Tudo bem? Tudo funcionando perfeitamente? Tudo tranquilo? Sim, com apenas um problema. No Internet Explorer. Até a versão sete esse problema existia, mas na versão oito o problema foi corrigido. O problema é o seguinte: EM RADIO BUTTONS E CHECKBOXES O NAME NÃO PODE SER ALTERADO DINAMICAMENTE VIA JAVSCRIPT! Aí já viu, né? Eles (os desenvolvedores do Internet Explorer) devem ter feito isso por que se alterar o name destes tipos de campos acabará com o grupo já instituido.

Então, o nosso código funciona perfeitamente em browsers. Então aquela história de escrever o template no JavaScript[bb] é a forma de resolver. Sim, é uma forma, o problema é que algumas vezes só nos deparamos com problemas quando a tela já está cheia de detalhes. Então o que temos que fazer é tentar resolver de outra forma, mais simples.

Vendo o código-fonte da jQuery, percebi que a função clone já faz um hack para IE, devido à forma como o dito cujo faz cópia com o comando cloneNode. Usando o método cloneNode do DOM, o Browser da Microsoft faz um clone dos eventos, então, se você remover o evento de um, ele remove o evento de todos ao mesmo tempo. Veja o trecho onde o clone é definido na jQuery.

301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
	clone: function( events ) {
		// Do the clone
		var ret = this.map(function(){
			if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
				// IE copies events bound via attachEvent when
				// using cloneNode. Calling detachEvent on the
				// clone will also remove the events from the orignal
				// In order to get around this, we use innerHTML.
				// Unfortunately, this means some modifications to
				// attributes in IE that are actually only stored
				// as properties will not be copied (such as the
				// the name attribute on an input).
				var html = this.outerHTML;
				if ( !html ) {
					var div = this.ownerDocument.createElement("div");
					div.appendChild( this.cloneNode(true) );
					html = div.innerHTML;
				}
 
				return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
			} else
				return this.cloneNode(true);
		});
		// Copy the events from the original to the clone
		if ( events === true ) {
			var orig = this.find("*").andSelf(), i = 0;
 
			ret.find("*").andSelf().each(function(){
				if ( this.nodeName !== orig[i].nodeName )
					return;
 
				var events = jQuery.data( orig[i], "events" );
 
				for ( var type in events ) {
					for ( var handler in events[ type ] ) {
						jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
					}
				}
 
				i++;
			});
		}
 
		// Return the cloned set
		return ret;
          },

Bom, já que ele já hackeia, decidi fazer um plugin que seja igual ao clone só que interferindo nesse hack. Eis o código final.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
 * Extensão para jQuery clonar um elemento para corrigir o BUG do IE
 */
 
$.fn.clonar = function( events , manipulateForIE) {
// Do the clone
var ret = this.map(function(){
  if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
    var html = this.outerHTML;
    if ( !html ) {
      var div = this.ownerDocument.createElement("div");
      div.appendChild( this.cloneNode(true) );
      html = div.innerHTML;
    }
    // Isto foi adicionado à função de clonar
    if (manipulateForIE != undefined && $.isFunction(manipulateForIE))
      html=manipulateForIE(html)
 
    return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
  } else
    return this.cloneNode(true);
});
// Copy the events from the original to the clone
if ( events === true ) {
  var orig = this.find("*").andSelf(), i = 0;
  ret.find("*").andSelf().each(function(){
    if ( this.nodeName !== orig[i].nodeName ) return;
    var events = jQuery.data( orig[i], "events" );
    for ( var type in events )
      for ( var handler in events[ type ] )
        jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
    i++;
  });
}
// Return the cloned set
return ret;
}

Daí, basta passar uma função que interfirirá no meio do clone da jQuery clonar. O código deve ficar assim:

8
9
10
var fls=$('fieldset.'+classe+':last').clonar(true, function(html){
  return html.replace(/name="?(\w+)_\d+/ig, 'name="$1_'+r+'" ');
});

E este é o nosso código final, já com o plugin e tudo o que tem direito:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
$(function(){
  aplica_acoes();
  $('button.duplicar').click('duplica_fieldset');
});
 
function duplica_fieldset() {
  var fls = $('fieldset.'+classe+':last').clonar(true, function(html){
    return html.replace(/name="?(\w+)_\d+/ig, 'name="$1_'+r+'" ');
  });
  $('fieldset:last').after (fls);
}
 
function aplica_funcoes() {
  $('.campo').click(function(){alert("Hey! Ho!");});
}
 
/**
 * Extensão para jQuery clonar um elemento para corrigir o BUG do IE
 */
 
$.fn.clonar = function( events , manipulateForIE) {
// Do the clone
var ret = this.map(function(){
  if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
    var html = this.outerHTML;
    if ( !html ) {
      var div = this.ownerDocument.createElement("div");
      div.appendChild( this.cloneNode(true) );
      html = div.innerHTML;
    }
    // Isto foi adicionado à função de clonar
    if (manipulateForIE != undefined && $.isFunction(manipulateForIE))
      html=manipulateForIE(html)
 
    return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
  } else
    return this.cloneNode(true);
});
// Copy the events from the original to the clone
if ( events === true ) {
  var orig = this.find("*").andSelf(), i = 0;
  ret.find("*").andSelf().each(function(){
    if ( this.nodeName !== orig[i].nodeName ) return;
    var events = jQuery.data( orig[i], "events" );
    for ( var type in events )
      for ( var handler in events[ type ] )
        jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
    i++;
  });
}
// Return the cloned set
return ret;
}

Uma vez o professor me disse: “Não tenha medo do código.” E isso eu passo para todo mundo que eu converso. Como você pode ver, o código da jQuery é bem escrito e bem documentado, pare e leia alguma coisa para você aprender cada vez mais. Ah, e caso você precise de um lugar de consulta para o dia-a-dia você pode usar o JavaScript Cheat Sheet.

JavaScript Cheat Sheet

JavaScript Cheat Sheet

7 Comments »
Tagged as: browser, BUG internet explorer, campo, checkbox, DOM, Firefox, input, Internet Explorer, javascript, jQuery, Microsoft, plugin, radio

Telescopic Text

Posted in Dia-a-dia, cases, javascript by DGmike
Sep 11 2008
TrackBack Address.

Eu adoro idéias novas e inovadoras. Principalmente quando essas idéias usam o que nós usamos no nosso dia-a-dia e não nos damos conta de como isso pode ser utilizado de forma a deixar a gente de queixo caído. Quando me deparei com o telescopic text percebi que para fazer um site interessante não é necessário megabytes de imagens feitas em photoshop para prender o usuário.

 

Clicando nas partes do texto elas se abrem e formam novas frases

Clicando nas partes do texto elas se abrem e formam novas frases

A idéia é ridículamente simples: o cara usou o bom e velho document.getElementById() do javascript para “abrir” as abas que os textos escondem apenas alterando a propriedade display delas. Muito interessante mesmo, mas o site é em inglês, então eu recomendo um dicionário do lado para desfrutar melhor do site.

No Comments yet »
Tagged as: case, Dia-a-dia, display, idéia, inovadora, javascript, sem photoshop, site

Categorias

  • Amigos  (16)
  • cases  (4)
  • Cotidiano  (73)
  • CSS  (20)
  • Design  (2)
  • Dia-a-dia  (33)
  • Diversão  (18)
  • eventos  (10)
  • extensions  (11)
  • flash  (4)
  • Games  (1)
  • html  (7)
  • icephp  (4)
  • Ilustração  (6)
  • Imagem  (8)
  • Inspiração  (5)
  • javascript  (36)
    • jQuery  (7)
    • yui  (2)
  • Não categorizado  (26)
  • Navegadores  (19)
    • Chrome  (6)
    • Firefox  (18)
    • Internet Explorer  (6)
  • pagseguro  (12)
  • php  (43)
    • PHP Conference  (3)
  • plugin  (3)
  • Programação  (46)
  • python  (5)
  • Semântica  (16)
  • sql  (9)
  • tableless  (18)
  • Tecnologia  (48)
  • Trabalho  (28)
  • Tutorial  (25)
  • Vetorial  (5)
  • video  (8)
  • video-tutorial  (5)
  • Windows  (4)
  • wordpress  (2)
  • xHTML  (23)

Tags

ajax artigo banco de dados biblioteca blog browser classe CSS data Design Dia-a-dia dinheiro evento eventos Firefox framework google html icephp internet Internet Explorer javascript jQuery loja mysql online opera pagseguro palestra php plugin Programação python retorno automático simples site solução sql tableless Tecnologia Tutorial twitter visie web wordpress

Arquivo

SlideSare

Últimos Posts

  • Vírgula em html5 e css3
  • Youtube e HTML5, agora ficou mais fácil
  • Novo emprego!
  • Até mais e obrigado pela salada
  • Api de teste do meadiciona.com

Tags

ajax artigo banco de dados biblioteca blog browser classe CSS data Design Dia-a-dia dinheiro evento eventos Firefox framework google html icephp internet Internet Explorer javascript jQuery loja mysql online opera pagseguro palestra php plugin Programação python retorno automático simples site solução sql tableless Tecnologia Tutorial twitter visie web wordpress

Conteúdo

  • Artigos
    • JavaScript (parte 1)
  • Códigos prontos
    • Bancos, bancos e mais bancos…
    • Classe sqlsimples e sql – PHP
    • PHP: Função __auloload()
  • Guia Rápido jQuery
  • PagSeguro
  • Quem é dgmike?
PagSeguro Powered by WordPress | “Blend” from Spectacu.la WP Themes Club