Image Image Image Image Image
Scroll to Top

Topo

javascript

13

abr
2012

Sem Comentários

Em Blog
Código

Por Allison

JavaScript: aviso de dados não salvos

Em 13, abr 2012 | Sem Comentários | Em Blog, Código | Por Allison

Fonte: Igor Escobar/IMasters

Sabe quando você está escrevendo um e-mail e, quando tenta sair da tela, o browser te dá um aviso, comunicando a possível perda de dados? Pois é sobre isso que vamos falar! O Gmail faz isso e o Rally também, mas muita gente ainda não sabe como isso é feito de fato.

Esse tipo de recurso é muito interessante e pode evitar muita dor de cabeça para quem estiver utilizando o seu sistema. No meu caso, esse recurso foi aplicado a um CMS. A finalidade da implantação era para que os jornalistas fossem avisados quando algum dado no formulário fosse alterado, porém, se o usuário intencionalmente (ou não) tentasse mudar de página, esse dado seria perdido. Tratando-se de um CMS focado para jornalistas, no qual o conteúdo digitado é extremamente importante, todos os recursos que forem desenvolvidos para evitar a perda de conteúdo são extremamente bem-vindos.

onBeforeUnload Event

O evento onbeforeunload não tem uma finalidade exclusiva para ele. É um evento como outro qualquer, que ele é invocado sempre que o usuário tenta sair da página atual, mas, quando ele não está setado, simplesmente nada acontece. O evento responsável por pedir para que o usuário confirme ou não a mudança de página é o onbeforeunload. Sempre que ele for setado, você vai ver um confirm dialog igual ao da imagem abaixo:

O problema

Se fosse só setar o efeito e ele fizesse todo o resto seria fácil, não é? Bom, mas não é bem assim. Temos que fazer com que um script peça a intervenção do usuário nas seguinte situações:

  1. Ao fechar aba/navegador;
  2. Ao clicar em qualquer outro link, senão o submit do formulário;
  3. O alerta deve aparecer somente se algo for alterado no formulário.

A solução

$(function(){
  var formObject = $('.new_materia, .edit_materia');
  formObject.data('original_serialized_form', formObject.serialize());
 
  $(':submit').click(function() {
    window.onbeforeunload = null;
  });
 
  window.onbeforeunload = function() {
    if (formObject.data('original_serialized_form') !== formObject.serialize()) {
      return "As mudanças deste formulário não foram salvas. Saindo desta página, todas as mudanças serão perdidas.";
    }
  };
});

Como funciona?

  1. Utilizei o $.data() do jQuery porque eu não gosto de utilizar o var para declarar variáveis globais;
  2. Utilizei o $.serialize() do jQuery para serializar o formulário para comparar o estado do formulário no futuro. E foi a forma mais inteligente que encontrei para identificar se algo realmente foi mudado no formulário;
  3. Por default, eu seto o evento onbeforeunload e dentro dele eu verifico se algo foi mudado no formulário;
  4. O único caso em que eu tenho que remover o evento onbeforeunload é quando existe a intenção de salvar o dado, no caso utilizei o :submit com evento $.click() para remover o evento e cancelar o alerta, caso haja a intenção de salvar o formulário.

Tags | , , ,

10

abr
2012

Sem Comentários

Em Blog
JavaScript
JSON

Por Allison

Como obter e tratar um retorno em JSON com o Wrapper .Net

Em 10, abr 2012 | Sem Comentários | Em Blog, JavaScript, JSON | Por Allison

Fonte: Buscapé Developer/IMasters

Veremos, neste artigo, uma das formas que temos de tratar os dados de um retorno em JSON utilizando o wrapper .Net.

Para começar, faça o download do Wrapper .Net direto do nosso perfil no GitHub e inclua seus arquivos em seu projeto para utilizar a classe Apiki_Buscape_API.

Com os arquivos do Wrapper .Net devidamente inseridos no projeto, vamos instanciar um objeto da classe, que servirá como nosso objeto de negócio principal. Como já estamos acostumados, devemos informar ao construtor da classe o nosso ApplicationId, para identificar a aplicação na requisição ao Buscapé. Pórem, neste exemplo também devemos sobreescrever o formato padrão de retorno dos dados para o JSON. Portanto, temos que informar valores default para os outros parâmetros do construtor da classe e informar o formato como JSON.

Apiki_Buscape_API.Apiki_Buscape_API apiBuscape = new Apiki_Buscape_API.Apiki_Buscape_API("564771466d477a4458664d3d", string.Empty, "BR", "json");

Para este artigo, vamos utilizar o método FindCategoryList, porque ele tem uma estrutura de retorno menos complexa. Consulte a documentação desse serviço na API do Buscapé, se desejar mais informações sobre os campos de resposta.

Vamos, então, invocar o método FindCategoryList com a palavra-chave LG e salvar o seu retorno em uma string.

string categoryList = apiBuscape.FindCategoryList(null, "LG", string.Empty);
Response.Write(categoryList);

Exibindo a resposta na tela, podemos ver o objeto JSON que foi retornado pelo método:

{"details":{"message":"success","elapsedtime":31,"status":"success","code":0,"applicationversion":"1.0.0.0","date":{"minute":2,"valid":true,"timezone":-120,"second":30,"millisecond":770,"month":2,"year":2012,"hour":10,"day":13,"xmlschematype":{"namespaceuri":"http://www.w3.org/2001/XMLSchema","prefix":"","localpart":"dateTime"},"eonandyear":{"lowestsetbit":2}},"applicationpath":"http://bws-apps.buscape.com/mobile/update","applicationid":"564771466d477a4458664d3d"},"schk":true,"subcategory":[{"subcategory":{"id":2852,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/2852.jpg"},"hasoffer":false,"name":"TV","parentcategoryid":1,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/tv.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=2852&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":77,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/77.jpg"},"hasoffer":false,"name":"Celular e Smartphone","parentcategoryid":6420,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/celular-e-smartphone.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=77&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":3661,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/3661.jpg"},"hasoffer":false,"name":"Ar Condicionado","parentcategoryid":116,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/ar-condicionado.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=3661&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":6424,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/6424.jpg"},"hasoffer":false,"name":"Notebook","parentcategoryid":2,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/notebook.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=6424&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":36,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/36.jpg"},"hasoffer":false,"name":"Monitor","parentcategoryid":2,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/monitor.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=36&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":3673,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/3673.jpg"},"hasoffer":false,"name":"Geladeira / Refrigerador","parentcategoryid":116,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/geladeira-refrigerador.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=3673&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":3643,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/3643.jpg"},"hasoffer":false,"name":"Home Theater","parentcategoryid":1,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/home-theater.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=3643&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":3601,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/3601.jpg"},"hasoffer":false,"name":"Micro System / Mini System","parentcategoryid":1,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/micro-system-mini-system.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=3601&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":5,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/5.jpg"},"hasoffer":false,"name":"DVD Player","parentcategoryid":1,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/dvd-player.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=5&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":3671,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/3671.jpg"},"hasoffer":false,"name":"Máquina de Lavar Roupas","parentcategoryid":116,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/maquina-de-lavar-roupas.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=3671&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":6168,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/6168.jpg"},"hasoffer":false,"name":"Gravador","parentcategoryid":2,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/gravador.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=6168&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":9754,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/9754.jpg"},"hasoffer":false,"name":"Blu-Ray Player / HD-DVD Player","parentcategoryid":1,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/blu-ray-player-hd-dvd-player.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=9754&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":126,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/126.jpg"},"hasoffer":false,"name":"Microondas","parentcategoryid":116,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/microondas.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=126&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":37,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/37.jpg"},"hasoffer":false,"name":"Projetor Multimídia","parentcategoryid":2,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/projetor-multimidia.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=37&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":5839,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/5839.jpg"},"hasoffer":false,"name":"Auto-Rádio CD Player","parentcategoryid":1,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/auto-radio-cd-player.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=5839&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":119,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/119.jpg"},"hasoffer":false,"name":"Aspirador de Pó / Água","parentcategoryid":116,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/aspirador-de-po-agua.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=119&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":145,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/145.jpg"},"hasoffer":false,"name":"Forno Elétrico","parentcategoryid":116,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/forno-eletrico.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=145&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":6507,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/6507.jpg"},"hasoffer":false,"name":"Adega Climatizada","parentcategoryid":116,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/adega-climatizada.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=6507&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":3737,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/3737.jpg"},"hasoffer":false,"name":"HD","parentcategoryid":2,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/hd.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=3737&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":8727,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/8727.jpg"},"hasoffer":false,"name":"Pen Drive","parentcategoryid":2,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/pen-drive.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=8727&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":3429,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/3429.jpg"},"hasoffer":false,"name":"Mouse","parentcategoryid":2,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/mouse.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=3429&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":22,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/22.jpg"},"hasoffer":false,"name":"PC","parentcategoryid":2,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/pc.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=22&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":3482,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/3482.jpg"},"hasoffer":false,"name":"Livros","parentcategoryid":3482,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/livros.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=3482&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":80,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/80.jpg"},"hasoffer":true,"name":"Outros Acessórios para Celular e Smartphone","parentcategoryid":6420,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/outros-acessorios-para-celular-e-smartphone.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=80&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":4699,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/4699.jpg"},"hasoffer":true,"name":"Carregador para Celular e Smartphone","parentcategoryid":6420,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/carregador-para-celular-e-smartphone.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=4699&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":9937,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/9937.jpg"},"hasoffer":true,"name":"Fonte para Notebook","parentcategoryid":2,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/fonte-para-notebook.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=9937&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":6359,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/6359.jpg"},"hasoffer":true,"name":"Jaqueta Feminina","parentcategoryid":2468,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/jaqueta-feminina.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=6359&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":4666,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/4666.jpg"},"hasoffer":true,"name":"Bateria para Celular e Smartphone","parentcategoryid":6420,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/bateria-para-celular-e-smartphone.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=4666&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":2921,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/2921.jpg"},"hasoffer":true,"name":"CDs","parentcategoryid":2921,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/cds.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=2921&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":9938,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/9938.jpg"},"hasoffer":true,"name":"Bateria para Notebook","parentcategoryid":2,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/bateria-para-notebook.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=9938&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":9941,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/9941.jpg"},"hasoffer":true,"name":"Outros Acessórios para Notebook","parentcategoryid":2,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/outros-acessorios-para-notebook.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=9941&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":4671,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/4671.jpg"},"hasoffer":true,"name":"Fone de Ouvido para Celular e Smartphone","parentcategoryid":6420,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/fone-de-ouvido-para-celular-e-smartphone.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=4671&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":4667,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/4667.jpg"},"hasoffer":true,"name":"Capa para Celular e Smartphone","parentcategoryid":6420,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/capa-para-celular-e-smartphone.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=4667&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":9469,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/9469.jpg"},"hasoffer":true,"name":"Cabo de Dados para Celular e Smartphone","parentcategoryid":6420,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/cabo-de-dados-para-celular-e-smartphone.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=9469&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":7918,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/7918.jpg"},"hasoffer":true,"name":"Câmera de Segurança","parentcategoryid":2701,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/camera-de-seguranca.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=7918&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":10800,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/10800.jpg"},"hasoffer":true,"name":"Óculos 3D","parentcategoryid":1,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/oculos-3d.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=10800&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":18,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/18.jpg"},"hasoffer":false,"name":"MP3 Player / MP4 Player","parentcategoryid":1,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/mp3-player-mp4-player.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=18&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":8241,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/8241.jpg"},"hasoffer":true,"name":"Outros Serviços em Construção Civil","parentcategoryid":5845,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/outros-servicos-em-construcao-civil.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=8241&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":16,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/16.jpg"},"hasoffer":false,"name":"Fone de Ouvido / Headset","parentcategoryid":1,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/fone-de-ouvido-headset.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=16&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":103,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/103.jpg"},"hasoffer":false,"name":"WebCam","parentcategoryid":2,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/webcam.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=103&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":4669,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/4669.jpg"},"hasoffer":true,"name":"Kit Viva Voz para Celular e Smartphone","parentcategoryid":6420,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/kit-viva-voz-para-celular-e-smartphone.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=4669&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":2947,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/2947.jpg"},"hasoffer":false,"name":"Mochila","parentcategoryid":1328,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/mochila.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=2947&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":4632,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/4632.jpg"},"hasoffer":true,"name":"Outros Acessórios para Áudio / Vídeo","parentcategoryid":1,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/outros-acessorios-para-audio-video.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=4632&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":75,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/75.jpg"},"hasoffer":false,"name":"Roteador","parentcategoryid":2,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/roteador.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=75&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":7356,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/7356.jpg"},"hasoffer":true,"name":"Assistência Técnica de Equipamentos de Informática","parentcategoryid":5845,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/assistencia-tecnica-de-equipamentos-de-informatica.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=7356&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":6399,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/6399.jpg"},"hasoffer":false,"name":"Auto-DVD Player","parentcategoryid":1,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/auto-dvd-player.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=6399&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":3772,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/3772.jpg"},"hasoffer":false,"name":"Aparelho Telefônico","parentcategoryid":6420,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/aparelho-telefonico.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=3772&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":172,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/172.jpg"},"hasoffer":true,"name":"Leitor de Cartão de Memória","parentcategoryid":2,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/leitor-de-cartao-de-memoria.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=172&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":9532,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/9532.jpg"},"hasoffer":true,"name":"Imóveis Residenciais","parentcategoryid":9549,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/imoveis-residenciais.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=9532&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":7985,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/7985.jpg"},"hasoffer":true,"name":"Serviços em Pisos","parentcategoryid":5845,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/servicos-em-pisos.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=7985&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":7349,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/7349.jpg"},"hasoffer":true,"name":"Assessoria Contábil","parentcategoryid":5845,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/assessoria-contabil.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=7349&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":7334,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/7334.jpg"},"hasoffer":true,"name":"Aluguel de Automóvel","parentcategoryid":5845,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/aluguel-de-automovel.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=7334&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":52,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/52.jpg"},"hasoffer":false,"name":"Cartão de Memória","parentcategoryid":2,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/cartao-de-memoria.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=52&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":62,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/62.jpg"},"hasoffer":false,"name":"Caixa de Som para PC","parentcategoryid":2,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/caixa-de-som-para-pc.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=62&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":111,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/111.jpg"},"hasoffer":false,"name":"Vídeo Cassete","parentcategoryid":1,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/video-cassete.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=111&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":2782,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/2782.jpg"},"hasoffer":true,"name":"Controle Remoto","parentcategoryid":1,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/controle-remoto.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=2782&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":4029,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/4029.jpg"},"hasoffer":true,"name":"Suplementos Nutricionais Esportivos","parentcategoryid":1328,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/suplementos-nutricionais-esportivos.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=4029&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":2794,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/2794.jpg"},"hasoffer":true,"name":"Massageador Elétrico","parentcategoryid":249,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/massageador-eletrico.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=2794&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":7606,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/7606.jpg"},"hasoffer":true,"name":"Música Digital","parentcategoryid":7606,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/musica-digital.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=7606&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":7157,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/7157.jpg"},"hasoffer":true,"name":"Apostila para Concursos / Cursos","parentcategoryid":6108,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/apostila-para-concursos-cursos.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=7157&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":6976,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/6976.jpg"},"hasoffer":false,"name":"Mala","parentcategoryid":2468,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/mala.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=6976&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":10369,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/10369.jpg"},"hasoffer":true,"name":"Lâmpada para Projetor","parentcategoryid":2,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/lampada-para-projetor.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=10369&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":9825,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/9825.jpg"},"hasoffer":false,"name":"Carros","parentcategoryid":3841,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/carros.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findProductList/564771466d477a4458664d3d/br/?categoryId=9825&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":10586,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/10586.jpg"},"hasoffer":true,"name":"Outros Acessórios para Aparelhos Telefônicos","parentcategoryid":6420,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/outros-acessorios-para-aparelhos-telefonicos.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=10586&keyword=lg&format=json"}}],"isfinal":true}},{"subcategory":{"id":7444,"thumbnail":{"url":"http://imagem.buscape.com.br/bp5/categorias/7444.jpg"},"hasoffer":true,"name":"Tela de Projeção","parentcategoryid":1,"links":[{"link":{"type":"category","url":"http://compare.buscape.com.br/tela-de-projecao.html?mdapp=100&mddtn=69672797"}},{"link":{"type":"xml","url":"http://sandbox.buscape.com/service/findOfferList/564771466d477a4458664d3d/br/?categoryId=7444&keyword=lg&format=json"}}],"isfinal":true}}],"totalresultsavailable":65,"totalresultsreturned":65}

Para converter os dados do retorno, vamos utilizar a classe JavaScriptSerializer presente no namespace System.Web.Script.Serialization do .NET, portanto não esqueçam de utilizar a diretiva using com esse namespace antes de iniciar.

Após instanciar um objeto da classe JavaScriptSerializer, vamos utilizar o método Deserialize<T>() para transformar o objeto JSON principal em um objeto do tipo Dictionary<string, object>. Depois vamos pegar o nó subcategory do JSON, indexando o objeto Dictionary criado.

JavaScriptSerializer deserializer = new JavaScriptSerializer();
Dictionary<string, object> data = deserializer.Deserialize<Dictionary<string, object>>(categoryList);
ArrayList subcategories = (ArrayList)data["subcategory"];

Como temos vários objetos JSON dentro de subcategory, ele nos retorna um tipo ArrayList com todas as categorias retornadas. Devemos, então, percorrer esse objeto para tratar cada atributo das categorias.

foreach (Dictionary<string, object> sub in subcategories)
{
// Aqui pegamos cada um dos atributos
}

A primeira coisa que vamos fazer é instanciar um objeto do tipo Dictionary<string, object> para receber os dados da categoria.

Dictionary<string, object> subData = (Dictionary<string, object>)sub["subcategory"];

A forma que acessamos os atributos do objeto convertido é indexanda ao objeto com o nome do atributo que desejamos – por exemplo para recuperar o nome da categoria usamos subData[“name”]. Simples, não?

Para não dizer que é tão simples assim, temos dois atributos que vamos ter um pouco mais de trabalho para recuperar seu valor: o thumbnail e a url. Para o thumbnail, com apenas mais um índice conseguimos seu valor. Já para a URL teremos algumas linhas a mais para conseguir:

// Recuperando o link para imagem da categoria
Dictionary<string, object> thumbnail = (Dictionary<string, object>)subData["thumbnail"];

// Recuperando a URL para os produtos da categoria
ArrayList links = (ArrayList)subData["links"];
Dictionary<string, object> productLink = (Dictionary<string, object>)links[1];
Dictionary<string, object> link = (Dictionary<string, object>)productLink["link"];

Pronto, com esses dois últimos atributos setados, podemos exibir os dados de retorno:

Response.Write(string.Format("<img src=\"{0}\" alt=\"{1}\" /> <br />", thumbnail["url"], subData["name"]));
Response.Write(string.Format("Categoria: {0} - {1} <br />", subData["id"], subData["name"]));
Response.Write(string.Format("Link para os produtos: <a href=\"{0}\">{0}</a> <br />", link["url"]));
Response.Write(string.Format("Tem Oferta: {0} - ID categoria pai: {1} - é final? {2} <br />", subData["hasoffer"], subData["parentcategoryid"], subData["isfinal"]));
Response.Write("<hr />");

É isso aí pessoal! Dessa forma, conseguimos trabalhar com o retorno em JSON da API do Buscapé utilizando somente as classes padrões do framework .NET, sem a necessidade de um componente extra. Abaixo, deixo o código completo utilizado neste artigo para não ficar nenhuma dúvida.

// Recuperando os dados em JSON
Apiki_Buscape_API.Apiki_Buscape_API apiBuscape = new Apiki_Buscape_API.Apiki_Buscape_API("564771466d477a4458664d3d", string.Empty, "BR", "json");
string categoryList = apiBuscape.FindCategoryList(null, "LG", string.Empty);

// Convert o JSON em uma coleção do tipo Dictionary e separa somente o nó subcategory em um array list
JavaScriptSerializer deserializer = new JavaScriptSerializer();
Dictionary<string, object> data = deserializer.Deserialize<Dictionary<string, object>>(categoryList);
ArrayList subcategories = (ArrayList)data["subcategory"];

foreach (Dictionary<string, object> sub in subcategories)
{
Dictionary<string, object> subData = (Dictionary<string, object>)sub["subcategory"];

// Recuperando o link para imagem da categoria
Dictionary<string, object> thumbnail = (Dictionary<string, object>)subData["thumbnail"];

// Recuperando a URL para os produtos da categoria
ArrayList links = (ArrayList)subData["links"];
Dictionary<string, object> productLink = (Dictionary<string, object>)links[1];
Dictionary<string, object> link = (Dictionary<string, object>)productLink["link"];

Response.Write(string.Format("<img src=\"{0}\" alt=\"{1}\" /> <br />", thumbnail["url"], subData["name"]));
Response.Write(string.Format("Categoria: {0} - {1} <br />", subData["id"], subData["name"]));
Response.Write(string.Format("Link para os produtos: <a href=\"{0}\">{0}</a> <br />", link["url"]));
Response.Write(string.Format("Tem Oferta: {0} - ID categoria pai: {1} - é final? {2}

Tags | , , , ,

08

fev
2012

Sem Comentários

Em Blog
PHP

Por Allison

Criando aplicativos móveis com PHP

Em 08, fev 2012 | Sem Comentários | Em Blog, PHP | Por Allison

Texto original: http://phpadvent.org/2010

Fonte: BlogdoExpert

Há um bom tempo, o PHP era a escolha óbvia para as necessidades de todo programador. Ele estava disponível em todos os servidores web virtuais, tinha excelente documentação, e conseguia lidar com todas as necessidades dos programadores. Essas coisas são ainda mais verdadeiras hoje, e o PHP ainda é o middleware de escolha da maioria dos profissionais da área. No entanto, o uso do PHP mudou nos último anos.

Durante uma solicitação típica de página, o PHP fazia coisas como começar uma sessão, consultar um banco de dados, processar alguns dados, e, finalmente, gerar uma tonelada de métricas de HTML que seriam retornadas para o browser do usuário. Em outras palavras, toda a interface do usuário era gerada no lado do servidor pelo PHP. Ocasionalmente, era possivel incluir o prototype.js ou jQuery para fazer um pouco de validação de formulário, ou uma lista dropdown com um campo para “auto-completar”.

Mas então veio o iPhone…

Em 2007, o iPhone deu início a uma onda de interesse em computação móvel. Como milhares de desenvolvedores maravilhado por aquele pequeno dispositivo mágico que colocou a web no bolso de muita gente. Sempre conectado, navegadores excelentes, interação de toque intuitiva – é de fato incrível, e todos queriam entrar nessa de cabeça.

Quando o iPhone foi anunciado pela primeira vez, Steve Jobs pediu ao desenvolvedores terceirizados que construíssem aplicativos web se eles quisessem programar para o iPhone.

Claro que Jobs acabou voltando atrás menos de um mês depois, com o anúncio do Cocoa Touch e a iTunes App Store. E a guerra santa entre “web apps” e “apps nativos” nasceu.

E o que isso tem a ver com PHP?

Felizmente, agora temos a convergência de novas tecnologias que tornam a construção de web apps – móveis e outros – muito mais fácil.jQTouch, Sencha Touch, e mais recentemente, jQuery Mobile tornaram a vida mais fácil para escrever JavaScript para browsers móveis. O CSS3 nós dá transformações, transições e animações que nos permitem facilmente adicionar efeitos visuais sofisticados. E, mais drasticamente, o HTML5 define uma enorme quantidade de novos recursos  —  geolocalização, canvas, sockets, workers, armazenamento de dados do lado do cliente, suporte a cache offline da aplicação, cross-origin resource sharing, e por aí em diante.

Como resultado,muitas pessoas podem criar suas próprias UI com HTML estático, CSS e documentos JavaScript que conversam com uma API do lado do servidor construída com PHP. Esta abordagem baseada em API pode minimizar, de fato, a quantidade de dados enviados através do fio, porque é possível esconder os arquivos estáticos localmente, e somente requisitar atualizações de dados relativamente pequenos do PHP (normalmente na forma de JSON). Isso também tem grandes vantagens secundárias. Aqui estão as três maiores:

1. Divisão de trabalho:

Uma vez que você tem configurado uma API do lado do servidor, você pode facilmente ter seu trabalho de design do aplicativo no front end sem saber o mínimo de PHP, linguagens de templates, ou qualquer outra tecnologia do lado do servidor. Você não tem nem que dar acesso ao servidor para o designer – ele pode codificar contra a API com os arquivos no seu desktop.

2. Clientes múltiplos

O cenário da informática está sob massivo crescimento e transformação. Estamos vendo telas tão pequenas quanto cartões de credito, e tão grandes quanto um outdoor. E está acontecendo também uma grande separação entre dispositivos que suportam entrada de toque, de mouse e, em menor número, de voz.

Diferenças no tamanho físico, modos de interação e capacidades do dispositivo exigem que forneçamos experiências otimizadas ao usuário para o terminal em questão. Expor uma API do lado do servidor, construída em PHP, possibilita o suporte a clientes front end, sejam eles clientes menores, construídos em HTML, CSS, e JavaScript, ou maiores, construídos com frameworks nativos.

Os benefícios dessa abordagem têm sido demonstrados pelo Google, Yahoo, e, talvez, mais dramaticamente pelo Twitter, que documentou e lançou uma API simples para a comunidade de desenvolvedores. Graças a isso, todos os clientes do Twitter encontraram seu caminho no mundo digital. Começando com uma API que permite esse tipo de flexibilidade, que parece infinita, certamente ela contribuiu imensamente para a aceitação do Twitter.

3. À prova do futuro

O cenário da informática está evoluindo e é muito difícil prever o que vem a seguir. Muitas pessoas inteligentes estão trabalhando em novas tecnologias que irão mudar a maneira com que interagimos com computadores, e mais importante, um com o outro. Tudo, desde projeções holográficas de eventos de esporte ao vivo, até entradas das ondas cerebrais dos usuários estão em jogo. A melhor maneira de se manter flexível à vista de novos desenvolvimento é fornecer uma API robusta para lidar com o máximo do levantamento do back end possível.

Comece com sua API

Para trabalho web front end, você vai querer se familiarizar com a nova maravilha que é o HTML5 e o CSS3, e mais importante, aprender JavaScript! É uma sintaxe muito parecida com PHP e ela deveria parecer bem familiar para você (existe até um artigo do PHP Advent sobre isso). No entanto, existem muitas diferenças importantes entre PHP e JavaScript que você realmente precisa entender antes de se auto intitular um especialista. O livro JavaScript: The Good Parts, de Douglas Crockford é recomendado. Se você programa para a web, deve lê-lo.

Para finalizar, nunca houve um momento melhor para ser um desenvolvedor web. A convergência de uma conectividade ubíqua, serviços de cloud e telas de toque interativa estão criando um ambiente onde qualquer um pode construir experiências do usuário convincentes que tenham um alcance massivo com uma barreira de entrada muito pequena. Então volte para seu editor de texto e comece a codificar.

Tags | , , , , , ,

30

jan
2012

Sem Comentários

Em Blog
JavaScript

Por Allison

JavaScript e linguagens de pré-compilação

Em 30, jan 2012 | Sem Comentários | Em Blog, JavaScript | Por Allison

Texto em resposta ao artigo Criar aplicativos web não precisa ser uma tarefa cansativa e irritante

Fonte: Leo Balter/IMasters

Eu sei que JavaScript não é uma linguagem que vai agradar a todo mundo, mas é a linguagem que roda nativamente em qualquer navegador com uma performance que não deixa nada a desejar. O que poderiam reclamar do JavaScript seria no máximo a sintaxe. Particularmente é questão de gosto.

Problemas? Todas as linguagens têm. Porém, como todas que têm uma boa comunidade ativa, ganham melhorias e novas características bem interessantes, assim como as APIs do HTML5 que já estão por aí e o ECMAScript 6 que vai trazer ótimas novidades.

Mesmo considerando toda a questão de gostos pessoais – e respeito muito isso – ainda acho que não podemos fugir da busca pela qualidade para atender uma vontade individual.

Ou seja, assim como para fazermos o melhor não deixamos de escrever em Java para apps de Android, em Objective-C para apps de iPhone, em Ruby para apps em Rails, utilizar qualquer outra pré-linguagem que compile para JavaScript para execução em navegador é algo que não parece ser a melhor opção.

A melhor linguagem que pode ser compilada para JavaScript é o próprio JavaScript. Tenho certeza das minhas interações pelo código e da qualidade do mesmo, assim como posso encontrar outro profissional bom na linguagem para entender o que está acontecendo. Estaríamos falando da mesma linguagem e a qualidade no código seria um facilitador para essa colaboração.

Outro ponto que acredito ser crucial: não somos únicos. Quando um programador sai da empresa, morre ou esteja em qualquer situação em que não escreva mais o código de determinada aplicação ele simplesmente não leva o código junto com ele, a menos que aquilo seja intencional.

O legado de um código é ensinar para uma pessoa nova aquilo o que está acontecendo. Se eu preciso de um novo profissional quando tenho um aplicativo em CoffeScript, qual linguagem eu devo exigir dele? CoffeScript, Javascript ou as duas?

O dia que encontrar um profissional que saiba apenas CoffeScript, vou acreditar que ele é totalmente incompleto e que teria o mesmo nível de quem somente aprendeu pseudo-código, sem me importar com o tempo que ele possui de experiência.

Como ele vai entender a real situação do meu aplicativo e todos os pontos que poderíamos melhorar? Como ele vai saber se tem ali um JavaScript bem escrito e funcional?

Em outras palavras, usar linguagens de pré-compilação me parece um verdadeiro “eXtreme Go Horse”, do tipo que se funcionar, tudo bem, não se importando com o que estiver no meio do caminho.

Tags | , , ,

09

jan
2012

Sem Comentários

Em Blog
Java

Por Allison

Java 8 e módulos: o estado atual do projeto Jigsaw

Em 09, jan 2012 | Sem Comentários | Em Blog, Java | Por Allison

Mark Reinhold, arquiteto-chefe da plataforma Java na Oracle, publicou uma nota detalhando a situação atual do projeto Jigsaw e apontando novidades nessa área para o Java 8. O projeto Jigsaw tem como objetivo permitir a criação de módulos de sistemas (coleções de classes e interfaces) dentro da Plataforma Java.

Para obter a modularidade foram seguidos alguns princípios:

  • A linguagem Java em si precisa ter suporte à criação de módulos;
  • Os módulos devem controlar quais classes podem ser acessadas externamente a eles;
  • Deve haver uma identificação de versão, caso ocorra a necessidade de os módulos serem adicionados ou removidos durante a execução do programa.

A seguir, são mostrados exemplos de como será o uso de módulos.

O exemplo abaixo cria um módulo, informando a sua versão, e define qual o pacote de classes públicas será compartilhado com outros módulos:

module br.infoq.foo @ 1.0 {
/* Permite que os outros módulos tenham acesso às classes públicas deste pacote. */
exports br.infoq;
}

O exemplo a seguir cria um módulo que possui uma dependência com outro módulo (podendo ser especificada a versão):

module zoo {
requires br.infoq.foo @ 1.0;
}

Note que é informada uma dependência do módulo br.infoq.foo na versão 1.0. Pode-se também especificar uma condição, por exemplo @ >= 2.0, que nesse caso informa a necessidade de uma versão maior ou igual à versão 2.0 do módulo.

O exemplo a seguir cria um módulo que possui uma dependência e aproveita para compartilhar essa dependência com outros módulos. Também demonstra como definir quais módulos podem acessar o módulo em questão:

module bar {
/* Permite que os módulos dependentes de bar, também acessem o módulo zoo. */
requires public zoo;
/* Somente o módulo baz pode acessar este módulo. */
permits baz;
}

Mark Reinhold também descreveu tarefas pendentes, além de revisões que serão realizadas no projeto, e futuras implementações que ocorrerão na parte de compilação, empacotamento, bibliotecas, repositórios, API de modularização de sistemas e modularização do JDK. No site do Jigsaw há mais informações sobre o histórico do projeto, além de sua documentação.

Fonte: Rafael Sakurai/InfoQ

Tags | , , ,

05

jan
2012

Sem Comentários

Em Blog

Por Allison

Como começar nesse mundo louco da Web?

Em 05, jan 2012 | Sem Comentários | Em Blog | Por Allison

Eu sempre recebo perguntas no forum do mxmasters ou mesmo por e-mail, de pessoas que devem estudar para começar a desenvolver seus sites ou mesmo algumas dicas e/ou também qual referência de blog/site que seria interessante. Acho o que a pessoa tem que aprender, de forma sólida é html e css. É impressionante os “analfabetos” de html e css, devido a utilização de programas como Dreamweaver. Mas tudo pode ser revertido. Muitos defendem que desenvolver os códigos é um retrocesso, conhecido “reinventar a roda”, mas não se trata de reinventar, e sim saber o que é mais produtivo, e sem sombra de duvidas, desenvolver o seus próprio código é a melhor solução. Mas por quê? Não podemos pensar na concepção imediata do site, temos que pensar nas mudanças que irão ocorrer, e você pode ter certeza que irão ocorrer.

Então vamos colocar alguns pontos que seriam interessantes ser estudado e algumas dicas:

  • Aprender html e css, isso é de vital importância. Não depender de programas, se em algum momento você tiver apenas o bloco de notas, você resolve.
  • Aprender a utilizar um editor de imagem, como photoshop, ou fireworks, ou outros programas. Não tenha medo de testá-los até encontrar um que te agrade mais.
  • Aprenda Javascript, ou aprenda a utilizar um framework, uma boa pedida é o jquery, é de fácil aprendizado e muito produtivo.
  • Aprenda alguma linguagem server-side, indico o php, por ser uma linguagem de fácil aprendizado, e por ter muito material na web.
  • Adquira livros. Na maioria dos casos vão te ensinar coisas que tutoriais não ensinam de uma maneira mais sólida.
  • Aprenda a utilizar o Google. Sabendo pesquisar, e não tendo preguiça você consegue arrumar soluções rápidas;
  • Não desista na primeira dificuldade. Esse é mau de muitas pessoas, quando esbarram no primeiro desafio, não tentam resolver. Lembre-se da sugestão anterior.
  • Participe dos fóruns. Você vai encontrar muitas soluções de duvidas que você tem.
  • Aprenda a ajudar. Quando você tentar ensinar algo, você aprender muito mais.
  • Não seja arrogante. Acredite, dizer que sabe tudo de determinado assunto, é comprovadamente mentira, existe sempre algo a aprender.
  • Aprenda a filtrar as informações. Nem tudo que escrito nos blog é uma verdade absoluta(inclusive no meu);
  • E não utilize o IE. Parece brincadeira, e até um pouco. Mas outros navegadores, como firefox não são simples navegadores, e sim ferramentas de desenvolvimento. Na sua caminhada, com certeza você vai odiar o IE6.
  • Não tenha medo de outros idiomas, nada que o Google tradutor não possa te ajudar.

Espero que essas dicas sejam válidas, isso não é uma regra, ou mantra que deve ser dito, mas são alguns passos que te ajudarão nessa nova jornada.

Fonte: DavidCHC

Tags | , , , , , , , ,

21

dez
2011

Sem Comentários

Em Blog
JavaScript

Por Allison

CoffeeScript 1.2.0 é disponibilizado

Em 21, dez 2011 | Sem Comentários | Em Blog, JavaScript | Por Allison

A versão 1.2.0 do CofeeScript, linguagem que converte arquivos CoffeeScript em JavaScript, foi disponibilizada. Ela traz uma sintaxe melhorada do JavaScript, inspirada em outras linguagens dinâmicas, mas o código do CoffeeScript é então compilado “one-to-one” para JavaScript para portabilidade. O resultado é um fragmento legível do JavaScript.

A atualização melhora os switches –watch ( que monitora arquivos para mudanças quando executa um comando como recompilação) e o –join (que pega o resultado do javaScript a partir da compilação e o transforma em um único arquivo) no comando coffee no coração do CoffeeScript.

Usuários agora podem adicionar e remover diretórios de uma pasta watched e usar os dois switches juntos. Outras mudanças incluem a habilidade de jogar uma exceção como parte de uma expressão, melhorias ao lidar com comentários, e correções para várias regressões encontradas na versão anterior, a 1.1.3.

O CoffeeScript está disponível para download a partir do site do CoffeeScript no GitHub, na qual os usuários podem encontrar uma introdução e documentação de referência para a linguagem, instruções de instalação, um guia para recursos e o change log. O CoffeeScript requer o Node.js para rodar o compilador e é publicado sob a licença MIT.

Com informações de The H

Fonte: IMasters

Tags | , , ,

20

dez
2011

Sem Comentários

Em Blog
CSS
JavaScript

Por Allison

Javascript para fazer degrade/gradiente

Em 20, dez 2011 | Sem Comentários | Em Blog, CSS, JavaScript | Por Allison

Cada vez que eu vejo um layout com algum tipo de degrade chega a me dar coceira, me vejo recordando um png em milhares de pequenos pedacinhos para poder fazer os gradientes pq os navegadores ainda não implementaram o código de gradiente do css3, como a minha vida seria mais fácil.

Se funcionasse via css seria somente fazer algo assim:

.div_qualquer {
background: -webkit-gradient(linear, left top, left bottom, from(#dfdfdf), to(#f3f3f3));
background: -moz-linear-gradient(top,  #dfdfdf,  #f3f3f3);
}

Mas isto exclui o IE, e é bem difícil explicar aos clientes.

Outra forma é recortar uma imagem em 1px de largura ou altura, deixar ela bem comprida ou larga e usar ela como bg e replicar ela um montão de vezes, assim:

.div_qualquer {
background: url(images/background.png) top repeat-x;
}

Então pesquisando um pouco me surgiu uma opção usando jQuery muito simples que faz isto extremamente bem. Escrito pelo grande Brandon Aaron (contribuidor do jQuery) e fez o jquery-gradient, que de uma forma bem simples pode criar os gradientes para vc, mas ou menos desta forma:

<script type="text/javascript">
// <![CDATA[
    $(document).ready(function(){
         $('.div_qualquer').gradient({ from: 'dfdfdf', to: 'f3f3f3' });
    });
// ]]>
</script>

O que o script faz é criar um bando de divs de 1px diminuindo as cores aos pouquinhos para fazer o degrade linear. Realmente funciona bem para pequenos objetos, mas para objetos muito grandes pode ficar muito pesado e até travar o browser.

Fonte: Rafael Cirolini/NerdHead

Tags | , , , , ,

23

nov
2011

Sem Comentários

Em Blog
NodeJs

Por Allison

NodeJS – análise e processamento de grandes documentos XML

Em 23, nov 2011 | Sem Comentários | Em Blog, NodeJs | Por Allison

Se você está trabalhando com dados legados, muitas vezes deve ter problemas com o tamanho dos dados. Um tempo atrás, eu tive que analisar grandes arquivos XML, extrair alguns dados, convertê-los, adicionar manualmente os dados gerados e então salvar o output em um arquivo JSON. (Precisamos disso porque mais tarde esse arquivo será usado como input para nosso componente ExtJS/Sencha).

Na minha máquina de desenvolvimento, o NodeJS já está instalado. Dê uma olhada no guia de instalação NodeJS, se você quiser instalá-lo. Agora você pode escrever programas executáveis em JavaScript baseados no mecanismo V8 do Google.

Eu fiz o download da SAX XML parser library para o NodeJS (escrita por isaacs). É bastante fácil incluí-la no meu espaço de trabalho, apenas adicione uma linha simples para incluir “sax.js”. O segundo componente de que preciso é o arquivo do sistema para ler o conteúdo do arquivo XML.

var fs = require('fs');
var sax = require('./sax');

A primeira coisa que você tem que fazer é criar uma nova instância do parser.

parser = sax.parser(strict);

O parser sozinho está trabalhando orientado a eventos, como quase tudo no NodeJS. Quando você está usando um parser orientado a eventos XML, é bastante útil usar um diagrama de estados – pois é mais fácil compreender o tipo de nó que você está visitando atualmente.

Agora existem alguns ganchos pré-definidos que você pode usar para escutar eventos como open tag, close tag etc…

parser.ontext = function(t) {
   console.log('This is the text in that node: ' + t);
};

parser.onopentag = function(node) {
   //on new tag opened
};

No final, a única coisa que você tem que fazer é iniciar o processo do parser. Apenas leia o conteúdo do arquivo em um String buffer (chamado file_buf) e então o coloque na biblioteca do parser.

try {
    var file_buf = fs.readFileSync('./demistified.xml');
    parser.write(file_buf.toString('utf8')).close();
} catch(ex) {
    // keep 'em silent
}

Nos ganchos do evento, você pode começar a escrever sua própria estrutura de dados, o NodeJS é construído para analisar e segurar muitos dados complexos. No meu caso, eu tinha um arquivo de 20 MB de dados XML, e eu extraí 180 nós de dados dessa imensa quantidade em apenas 2 segundos.

No final, se você precisar que sua estrutura interna de dados (provavelmente você usará array e combinações de objetos) seja salva em um arquivo, você pode facilmente utilizar o comando:

fs.writeFileSync('test.json', JSON.stringify(DataNodeSpace));

Ele escreve o array DataNodeSpace no formato JSON no arquivo test.json.

Para modificar, atravessar, adicionar propriedades a um array ou objeto no JavaScript ou no NodeJS, é bastante fácil e rápido. Eu fiquei maravilhado com a rapidez com que você pode construir um parser XML (10 linhas de código) e depois da (mais ou menos complexos *g*) execução dos algoritmos de análise você pode transformar os elementos de dados fácil e confortavelmente.

Espero que você tenha tido uma pequena visão geral sobre como analisar arquivos XML no NodeJS.

Texto original disponível em http://blog.lagentz.com/nodejs/nodejs-parsing-and-transforming-large-xml-documents/

Fonte: IMasters

Tags | , , ,

23

nov
2011

Sem Comentários

Em Blog
Código
Java

Por Allison

Criando uma Tag Library para carregar a imagem de um perfil do Gravatar

Em 23, nov 2011 | Sem Comentários | Em Blog, Código, Java | Por Allison

Há alguns dias eu estava querendo um tempo para estudar um pouco a API do Gravatar, que por sinal funciona muito bem aqui no WordPress. Lendo a documentação de uso, percebi que muito fácil de você obter a imagem de um perfil do Gravatar usando um hash do e-mail do usuário com criptografia MD5.

Primeiramente, como sou um usuário fanático do jQuery, tentei resolver a bronca direto por Javascript, mas acabei empacando na geração do hash MD5, não sei porque, mais aqui nenhuma implementação Javascript para MD5 funcionou, assim parti para o plano B, usando a API Java para gerar o hash MD5, perfeito, funcionou corretamente, tá bom, mas agora eu tenho a implementação lá em uma classe Java, como que eu ligo isto com a minha view HTML/JSP ?

Usando o VRaptor 3.4, fiz uma requisição AJAX/JSON e retornava o hash e fazia o carregamento da imagem via jQuery, assim:

01	$(document).ready(function(){
02	   $('#button').bind('click', function(){
03	      var email = $('#email').attr('value');
04
05	      var url = "<c:url value='/gravatar/get-md5/'/>";
06	      $.post(url, {email: email}, function(data){
07	         var url = "http://www.gravatar.com/avatar/" + data.string + "?s=200";
08	         $('#result').html($("<img/>").attr('src', url)).append('<br/><i>' + data.string + "</i>");
09	      });
10	   });
11	});

Na minha aplicação Java eu tinha duas classes, uma que implementava o hash MD5 e a outra que era o meu controller da requisição AJAX/JSON:

01	package com.wp.carlos4web.cpropriedades.md5;
02
03	import java.io.UnsupportedEncodingException;
04	import java.security.MessageDigest;
05	import java.security.NoSuchAlgorithmException;
06
07	public class MD5 {
08	    public static String hex(byte[] array) {
09	        StringBuffer sb = new StringBuffer();
10	        for (int i = 0; i < array.length; ++i) {
11	            sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(
12	                    1, 3));
13	        }
14	        return sb.toString();
15	    }
16
17	    public static String md5Hex(String message) {
18	        try {
19	            MessageDigest md = MessageDigest.getInstance("MD5");
20	            return hex(md.digest(message.getBytes("CP1252")));
21	        } catch (NoSuchAlgorithmException e) {
22	        } catch (UnsupportedEncodingException e) {
23	        }
24	        return null;
25	    }
26	}
27	// Controller.
28	package com.wp.carlos4web.cpropriedades.controllers;
29
30	import com.wp.carlos4web.cpropriedades.md5.MD5;
31
32	import br.com.caelum.vraptor.Get;
33	import br.com.caelum.vraptor.Post;
34	import br.com.caelum.vraptor.Resource;
35	import br.com.caelum.vraptor.Result;
36	import br.com.caelum.vraptor.view.Results;
37
38	@Resource
39	public class HomeController
40	{
41	    private Result result;
42
43	    public HomeController(Result result) {
44	        super();
45	        this.result = result;
46	    }
47
48	    @Get("/")
49	    public void index ()
50	    {
51
52	    }
53
54	    @Post("/gravatar/get-md5/")
55	    public void generateMD5Hash(String email)
56	    {
57	        String hash = MD5.md5Hex(email);
58
59	        this.result.use(Results.json()).from(hash).serialize();
60	    }
61	}

O código é bem simples, e funcionou, atendendo o que eu precisava, só que daí pensei em ‘componentizar’ essa solução, daí acabei refletindo e vi que seria inviável inicialmente, logo então pensei em uma solução alternativa à uma interação/codificação Javascript/AJAX, logo a única saída seria escrever uma tag própria para isso, pronto, encapsula a lógica em uma classe Java e vincula a mesma em uma tag acessível pelo HTML/JSP.

As tag libraries, ou tag support do Java são bem simples de serem utilizadas e implementadas, não sou um grande conhecedor, mas com algumas pesquisas na documentação consegui desenvolver a solução sem muitos problemas. Bom primeiramente precisamos criar a nossa classe que contém a implementação necessária, mais qual implementação ?

A implementação/ligação com a classe que gera o hash e que cria o elemento IMG para ser inserido no corpo da página HTML/JSP, o código da classe está na listagem abaixo e é bem simples, repare que os atributos ‘email’ e ‘imageSize’ são os parâmetros da nossa tag na página HTML/JSP.

01	package com.wp.carlos4web.gravatar;
02
03	import java.io.IOException;
04
05	import javax.servlet.jsp.JspException;
06	import javax.servlet.jsp.tagext.TagSupport;
07
08	import com.wp.carlos4web.cpropriedades.md5.MD5;
09
10	public class GravatarTag extends TagSupport
11	{
12	    private static final long serialVersionUID = 1066237315711135837L;
13
14	    protected String    email;
15
16	    protected int       imageSize = 200;
17
18	    @Override
19	    public int doEndTag() throws JspException
20	    {
21	        if(email != null && !email.isEmpty())
22	        {
23	            try
24	            {
25	                // Gera o hash MD5.
26	                String hash = MD5.md5Hex(email);
27
28	                // Monta a URL para a imagem remota.
29	                String url = "http://www.gravatar.com/avatar/" + hash + "?s=" + imageSize;
30
31	                // Monta a tag HTML IMG com a URL remota.
32	                String img = "<img src='" + url + "'/>";
33
34	                // Insere no corpo da página onde a tag está sendo chamada.
35	                this.pageContext.getOut().write(img);
36	            } catch (IOException e) {
37	                e.printStackTrace();
38	            }
39	        }
40	        return super.doEndTag();
41	    }
42
43	    public String getEmail() {
44	        return email;
45	    }
46
47	    public void setEmail(String email) {
48	        this.email = email;
49	    }
50	    public void setImageSize(int imageSize) {
51	        this.imageSize = imageSize;
52	    }
53
54	    public int getImageSize() {
55	        return imageSize;
56	    }
57	}

Como vocês viram o código é bem simples. Não existe regra sobre qual pacote deve ficar a sua classe, somente no arquivo TLD de descrição você deverá informar o caminho dela, exemplo: ‘br.pacote.pacote.SuaClasse’. Não esqueça:

  • Criar os métodos setters para os seus atributos, caso falte algum será gerada uma exception na sua aplicação.

Caso contrário não irá funcionar.

O próximo passo e a estruturação da nossa tag, para isso eu segui o padrão do desenvolvimento de tags, no meu diretório WEB-INF, eu criei um diretório tags e dentro dele um diretório com um nome significativo, neste caso ‘gravatar’. Dentro dele, seguindo a convenção, criei um arquivo .TLD com o nome da minha classe, logo ‘gravatar.tld’. Abaixo segue a codificação do mesmo, que também é bem simples e segue um padrão.

01	<?xml version="1.0" encoding="ISO-8859-1" ?>
02	<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
03
04	<taglib>
05	    <tlibversion>1.0</tlibversion>
06	    <jspversion>1.1</jspversion>
07	    <shortname>gravatar</shortname>
08	    <uri>http://carlos4web.wordpress.com/</uri>
09	    <info>Insere uma tag IMG com o gravatar de um usuário a partir do seu E-mail.</info>
10
11	    <tag>
12	        <name>gravatar</name>
13	        <tagclass>com.wp.carlos4web.gravatar.GravatarTag</tagclass>
14	        <bodycontent>JSP</bodycontent>
15	        <info>Say Hi</info>
16
17	        <attribute>
18	            <name>email</name>
19	            <required>true</required>
20	            <rtexprvalue>true</rtexprvalue>
21	        </attribute>
22	        <attribute>
23	            <name>imageSize</name>
24	            <required>false</required>
25	            <rtexprvalue>true</rtexprvalue>
26	        </attribute>
27	    </tag>
28	</taglib>

O próximo passo é usar a nossa tag, esta é a parte mais fácil da brincadeira, primeiramente, declare o import da nossa tag library:

1	<%@ taglib prefix="carlos" uri="/WEB-INF/tags/gravatar/gravatar.tld" %>

Agora é só chamar quando você precisar:

01	<table>
02	    <tr>
03	        <td valign="top">
04	            <carlos:gravatar email="carlosjrcabello@gmail.com" imageSize="30"/>
05	        </td>
06	        <td valign="top">
07	            <carlos:gravatar email="carlosjrcabello@gmail.com" imageSize="50"/>
08	        </td>
09	        <td valign="top">
10	            <carlos:gravatar email="carlosjrcabello@gmail.com" imageSize="100"/>
11	        </td>
12	        <td valign="top">
13	            <carlos:gravatar email="carlosjrcabello@gmail.com" imageSize="300"/>
14	        </td>
15	    </tr>
16	</table>

Lembrando pessoal, que segundo a API do Gravatar, quando a imagem do perfil não é encontrada, é retornado uma imagem padrão com a logo do gravatar. Caso você queira, existem mais parâmetros na API para customizar isso.

Conclusão

Bom pessoal, essa é uma solução do ‘mundo real‘ no desenvolvimento de aplicações WEB, porque? Com esse código, você investe um tempo X para fazê-lo, depois você ganha muito tempo somente reusando ele, lembrem-se dos princípios de agilidade e reusabilidade de código.

Este é um exemplo didático, está bem simples, quem quiser enriquecer esta solução com os outros recursos da API do Gravatar fique a vontade, no final será uma solução muito bacana e utilizável.

Download

Para quem quiser baixar o exemplo da tag, estou deixando disponível lá no Github o código junto da estrutura do projeto, segue o endereço abaixo:

https://github.com/carlosjrcabello/gravatar-tag-support

Referências


http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/JSPTags6.html – contém exemplos bem claros de como utilizar.


http://stackoverflow.com/questions/224748/jsp-custom-tag-library-unable-to-find-setter-method-for-the-attribute – contém a solução para um problema que uma hora ou outra você irá passar, que é a ordem da declaração dos elementos no arquivo TLD.


http://java.sun.com/developer/technicalArticles/xml/WebAppDev3/ – Mais exemplos de como trabalhar com o arquivo TLD.

http://en.gravatar.com/site/implement/ – informações sobre a API e implementações.

Por enquanto é só pessoal, um abraço e até a próxima.

Dúvidas e comentário usem o espaço de comentários abaixo.

Fonte: Carlos4web

Tags | , , , , , , , , ,

23

nov
2011

Sem Comentários

Em Blog
Design
HTML

Por Allison

Grayscale Images Hover com HTML5 Cross Browser

Em 23, nov 2011 | Sem Comentários | Em Blog, Design, HTML | Por Allison

A um tempo atrás o blog Web Designer Wall fez mais um de seus interessantes posts mostrando como é possível criar imagens em escala cinza com JavaScript, mas especificamente com a utilização de HTML5 (Canvas). Só que como todos sabem, o Internet Explorer não tem suporte a esse tipo de feature, mas você pode contornar isso facilmente com um código prorietário da Microsoft.

Basicamente, o código é o seguinte:

1.element.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(grayScale=1)

Com isso basta você fazer uma verificação e se o user agent no momento for o IE, use esse código, caso contrário, use HTML5.

  1. Exemplos
  2. Downloads

Fonte: Pedro Rogério/PinceladasnaWeb

Tags | , , ,

13

nov
2011

Sem Comentários

Em Blog

Por Allison

Usando Ajax com jQuery

Em 13, nov 2011 | Sem Comentários | Em Blog | Por Allison

Realmente eu achava chato programar em javascript, algo complicado, cheio de lerolero, mas então eu encontrei o jQuery, e programar em javascript se tornou algo fácil e muito divertido. Realmente eu fiquei muito feliz a descobrir este framework (se é que pode ser chamado assim). Hoje vou falar de uma das funcionalidades mais uteis e mais requisitadas que podemos usar para sistemas web, o ajax.

Tirando da Wikipedia: AJAX (acrônimo em língua inglesa de Asynchronous Javascript And XML) é o uso metodológico de tecnologias como Javascript e XML, providas por navegadores, para tornar páginas Web mais interativas com o usuário, utilizando-se de solicitações assíncronas de informações. Mas na linguagem mais simples, conseguimos fazer uma requisição a um arquivo (pagina) sem precisar fazer reload de tela. Sim, isto torna muito mais rápido a execução do seu código, e muito mais bonito e elegante tbm.

Uma coisa que vamos aprender como jQuery é que vamos separar totalmente o nosso código javascript do nosso html. Gosto de pensar a programação web em camadas, sendo elas: conteúdo (html), estilo (css) e ação (javascript). Ainda temos a tomada de decisão (php), mas acho que falar sobre isto é coisa para outro tutorial. Vamos ao que interessa.

Primeiro, precisamos baixar o jQuery direto da fonte: http://docs.jquery.com/Downloading_jQuery

Vamos entender como funciona a estrutura básica:

<!doctype html>
<html>
  <head>
    <!-- aqui vamos fazer o nosso include da biblioteca do jQuery -->
    <script type="text/javascript" src="jquery.js"></script>
 
    <script type="text/javascript">
      <!-- aqui vamos escrever nosso código javascript -->
    </script>
  </head>
  <body>
    <a href="http://jquery.com/">jQuery</a>
  </body>
</html>

Muito simples, fizemos a requisição do nosso arquivo jQuery, e logo em seguida escrevemos nosso código entre as tags .

Mas vamos agora ao nosso código:

<!doctype html>
<html>
  <head>
 
    <script type="text/javascript" src="jquery.js"></script>
 
    <script type="text/javascript">
    $(document).ready(function(){
      $("#button_busca").click(function () {
        $("form").submit(function () { return false; });
        var busca = $("#busca").val();
        $.ajax({
            type: "POST",
            url: "busca.php",
            data: "busca="+busca,
            success: function(html){
                $("#resposta").html(html);
            }
        });
    });
    });
    </script>
  </head>
  <body>
    <div id="resposta"> </div>
    <form>
    <fieldset>
        <legend>Busca</legend>
        <dl>
            <dt><label for="busca">Palavra Chave:</label></dt>
            <dd><input type="text" name="busca" id="busca" /></dd>
        <dd class="botao"><button id="button_busca">Busca</button></textarea></dd>
            </dl>
    </fieldset>
    </form>
  </body>
</html>

Primeiro fazemos o include da biblioteca jQuery. Depois temos a linha: “$(document).ready(function(){” isto faz com que assim que a pagina termine de ser carregada ele aplique as rotinas que vamos escrever abaixo dele. Abaixo temos “$(“#button_busca”).click(function () {” que vai associar ao id button_busca uma ação quando ele for clicado.

Usamos a função “$(“form”).submit(function () { return false; });” para que quando o botão for clicado ele não faça um reload de tela enviando para a action do form.

Criamos uma variável e atribuímos a ela o valor que estiver no campo de input com o id busca (“var busca = $(“#busca”).val();”).

A nossa chamada ajax ocorre na linha 13, onde chamamos a função e passamos os parâmetros:

  • type: tipo de encoding que vai ser enviado para o arquivo.
  • url: caminho completo do arquivo que vai ser requisitado.
  • data: os valores que serão passados, no nosso exemplo estão passando a variável busca, com o valor que pegamos do input com o id busca.
  • success: dizemos que caso tudo funcione ok, execute isto, no nosso caso estamos pegando o retorno da requisição e jogando o mesmo como html na div de id resposta.

Segue ainda o código php:

<?php
       echo "Resultado da Consulta aqui: $_POST[busca]";
?>

Fonte: Rafael Cirolini/NerdHead

Tags | , , , , , ,