Como eu disse que iria fazer, e fui cobrado no último rails podcads brasil, segue um post sobre o lowpro.
Isto não vai ser exatamente um tutorial, apenas uma coleção de dicas sobre esta excelente extensão para o prototype
, o Lowpro.
O Lowpro ja foi até transformado em um plugin para o rails, o UJS Rails Plugin, mas sinceramente, eu prefiro adicionar a meia duzia de linhas de javascript no meu application.js mesmo do que usar outro plugin só pra isto
Mas seguindo o baile, tudo o que vou escrever neste post, vocês podem usar com ou sem o rails, só sera necessário o prototype e o lowpro, inclusive o lowpro ja tem até uma versão que funciona junto com o jQuery
para os que não gostam do prototype
Mas seguindo com o assunto deste post, o que vocês acham de adicionar alguns recursos Javascript e até mesmo AJAX
em uma página pronta sem mexer no HTML gerado? nem para adicionar Javascript nos onclick, onblur, onXXX …
Na verdade, sera necessário adicionar pelo menos 3 linhas:
1
2
3
| <script src="prototype.js" type="text/javascript" charset="utf-8"></script>
<script src="lowpro.js" type="text/javascript" charset="utf-8"></script>
<script src="meuarquivodescripts.js" type="text/javascript" charset="utf-8"></script> |
A última linha, ou seja o “meuarquivodescripts.js” define o arquivo onde vamos trabalhar
Um dos recursos que eu acho mais espetaculares no lowpro, é o suporte a comportamentos …
Como assim?
imagine a seguinte situação:
Tenho uma página pronta, é uma página de listagem, e no final da tabela tem um link para a criação de um novo item, hoje toda a página é atualizada quando clico neste link, mas eu quero que apenas a parte da tablea seja substituida pelo formulário, em vez de recarregar a tela toda …
Bom isto é muito fácil de fazer 
E não vamos precisar de praticamente nenhum código …
Claro, precisamos de alguma forma de identificar o link de adicionar novo objeto na tabela, então, consideremos que este e todos os links que quisermos que sejam abertos por ajax no lugar da tabela, tenham a classe “my_ajax_link”, e consideremos que a tabela esta dentro de uma DIV com ID ‘minha_tabela’…
Se isto for verdade, podemos fazer o seguinte:
1
| Event.addBehavior({ 'a.my_ajax_link' : Remote.Link({update:'minha_tabela'}) }); |
Com isto, todos os links que tenham a classe “my_ajax_link” quando clicados vão ser executados via ajax, e vão substituir o conteúdo do elemento de id “minha_tabela” …
OK, mas é só isto que eu posso fazer com o tal de lowpro? E estes tais de comportamentos?
Na verdade o negócio é bem mais flexivel que isto 
Vamos ver mais alguns exemplos …
Se você quiser executar algum código no momento em que a página aparecer para o usuário (não é no onload, o onload só é executado depois de toda a página carregada
)
Basta fazer algo assim:
1
2
3
| Event.onReady(function() {
$$('h1').first().innerHTML += ' (Version ' + LowPro.Version + ')';
}); |
Isto vai mostrar a versão do Lowpro dentro da primeira tag H1 da página 
O Event.onReady executa um código qualquer no momento em que o DOM da página estiver carregado, o que é bem antes de carregas as imagens, por exemplo, e o onload só sera executado depois de tudo carregado …
Outro exemplo bem simples:
Eu quero que quando o usuário colocar o mouse sobre um link ele fique verde, quando tirar o mouse ele volte a cor padrão, e quando clicar o link incremente um contador dizendo quantas vezes ele ja foi clicado …
Para isto precisamos criar um comportamento …
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| var LinkBehavior = Behavior.create({
initialize : function() {
this.count = 0;
},
onmouseover : function() {
this.element.addClassName('goo');
},
onmouseout : function() {
this.element.removeClassName('goo');
},
onclick : function() {
this.element.innerHTML = 'Clicks: ' + ++this.count;
return false;
}
}); |
O que vai fazer os nossos links mudarem de cor é a classe “goo”, por tanto para que as cores mudem como eu disse antes, é preciso criar a classe “goo” em algum arquivo css carregado pela página.
Mas só este código apenas cria uma classe “comportamento” que define que o objeto que tiver este comportamento vai receber a classe “goo” no evento onmouseover, tera esta classe removida no evento onmouseout e vai ter o conteúdo alterado quando clicado.
Para que isto funcione com todos os links da página, precisamos adicionar este comportamento aos links da página …
1
| Event.addBehavior({ 'a' : LinkBehavior }); |
Pronto, agora todos os links vão ter o comportamento especificado pela classe.
Claro que alterar assim todos os links de uma página não é a coisa mais útil do mundo, mas se compararmos este último exemplo com o anterior, podemos ver que o lowpro, utiliza css selectors para identificar onde os behaviors devem ser aplicados …
Como assim?
- a - todas as tags a
- a.meulink - todas as tags a que tenham a classe “meulink”
- a#link - a tag a com ID link
- #qualquerid - qualquer tag mas que tenha o ID “qualquerid”
- .qualquerclasse - qualquer tag que tenha a classe “qualquerclasse”
Tudo bem, esta melhorando, mas eu não curti esta idéia de ter que criar uma classe para definir o que eu quero que aconteça quando o usuário clicar em um link, não tem como fazer tudo isto com uma linha de código só?
Na verdade tem
1
| Event.addBehavior({'a#bung:click' : function () {alert('Você Clicou no link');return false;}}) |
O que estamos fazendo agora é ligar uma função javascript ao evento onclick da tag a com ID bung.
E como é possível ver (talver não tão fácil por que a letra do código aqui no blog é meio pequena, o parâmetro apra a função addBehavior é um objeto, esta sendo utilizada a sintaxe de objetos JSON para passar os parâmetros, por tanto, isto quer dizer que podemos fazer algo parecido com isto:
1
2
3
4
5
| Event.addBehavior({
'a#bung:click' : function () {alert('Você Clicou no link');return false;},
'a.ajax_link' : Remote.Link({update:'qualquerid'}),
'.mudacoreconta': LinkBehavior
}) |
Ou seja, passar diversos itens a cada chamada do Event.addBehavior.
Outra coisa interessante, é que novas chamadas, vão empilhar métodos na fila se chamada, ou seja, este código:
1
2
3
| Event.addBehavior({'a#bung:click' : function () {alert('Você Clicou no link');return false;}})
Event.addBehavior({'a#bung:click' : function () {alert('Você Clicou no link novamente');return false;}})
Event.addBehavior({'a#bung:click' : function () {alert('Você Clicou no link');return false;}}) |
Vai mostrar 3 mensagens quando o link for clicado.
Uma outra coisa interessante do lowpro é que ele pode aplicar os comportamentos em objetos que forem carregados por uma chamada ajax também, para isto precisamos de mais uma linha de código (pode ser executada no inicio da aplicação)
1
| Event.addBehavior.reassignAfterAjax = true; |
Isto configura o lowpro para reaplicar os eventos após cada chamada AJAX.
Claro que podemos misturar isto com outras bibliotecas Javascript, por exemplo no meu pet project de planejamento doméstico, eu tenho o seguinte código no application.js:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| var WindowedForm = Behavior.create({
onclick : function() {
if (remote_window){
remote_window.destroy();
}
remote_window = new UI.Window({ theme: 'leopard', width: 600, height: 300, focus : true, minimize : false });
remote_window.setAjaxContent(this.element.href, {method: 'get'});
remote_window.center();
remote_window.activate();
remote_window.show(true);
return false;
}
});
remote_window = false;
Event.addBehavior({ 'a.action_form' : WindowedForm }); |
Isto faz com que todos os links que tenham a classe action_form sejam abertos em uma janela modal criada pela biblioteca “prototype-ui”.
Ahh, e para finalizar com chave de ouro, uma dica para quem usa rails e will_paginate para a paginação, o código que vou mostrar agora utiliza a lowpro para fazer com que a paginação da will_paginate passe a funcionar via AJAX
1
2
3
| Event.addBehavior({
'div.pagination a' : Remote.Link({update:'nomedadiv'})
}) |
Pronto, só isto, agora é só fazer a action correspondente retornar apenas a tabela e não a página toda quando for uma requisição AJAX, e colocar uma div com ID “nomedadiv” na volta da tabela
E por último mas não menos importante, não esqueça de alterar o código no servidor para retornar ou Javascript para ser executado, ou a parte do HTML desejado, mas sem as tags html,head,body, …
O lowpro facilita muito o trabalho no client, mas as respostas as chamadas AJAX continuam necessitando ser implementadas adequadamente.
Bom, espero que este post ajude alguem 
Quaisquer dúvidas podem perguntar por aqui mesmo 
Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!