Archive for the 'javascript' Category

18th abr 2010

Upload de arquivos do file system direto pela interface web

Certa vez, anos atrás, pesquisei como seria possível fazer upload de arquivos do desktop direto para uma aplicação web, arrastando-e-colando. Não era.
A única coisa que achei seria implementando um java applet ou alguma solução proprietária – a Microsoft tem um lance desses no Sharepoint, o CMS deles. Desencanei.

Ai, semana passada saiu uma notícia que era possível fazer isso pelo Gmail. Acredito que a solução a qual eles chegaram não é a mesma que eu encontrei na web, mas acredito que seja algo do gênero. Basicamente, dá pra fazer isso com HTML5 se você estiver usando um browser adequado. Adequado, nesse contexto, é o Chrome 2.0+ ou Firefox 3.6

Não vou me dar ao trabalho de fazer uma explicação muito didática; se você chegou até aqui, acredito que tenha experiência em desenvolvimento de interfaces web e vai entender o que estou falando. Se não, dê alguns passos para trás antes de continuar.

Com o HTML5, muita coisa diferente em javascript foi implementada. Para o usuário poder arrastar-e-colar arquivos do file system para uma interface web, são usadas 2 funcionalidades (desculpem o nome, não achei um mais adequado):

  • File API
  • XMLHttpRequest 2

Com o primeiro (File API), você consegue manipular arquivos que são “arrastados-e-colados” para uma certa área da sua página. Manipular, nesse caso, pode ser muita coisa, mas você consegue saber o nome, file syze, content type, conteúdo do mesmo (em binário, por exemplo), etc…
Com o XMLHttpRequest versão 2 é possível fazer o envio de dados nas suas requisições em formato binário. E bacana é que existem métodos nativos para saber o status e a porcentagem da mesma – ou seja, você consegue criar uma progress bar, por exemplo.

Vou colar logo abaixo o conteúdo da página de teste, que possui comentários. Sei que o post ficou meio superficial, mas ele serve mais como referência para vocês saberem mais uma coisa do que é possível ser feito com HTML5!

Url de teste: http://www.chrisb.com.br/teste.html
*no caso, arraste arquivos do file system para a caixa com bordas pretas.

<html>
<head>
<script>

function dodrop(event) {
//retorna os arquivos que estão sendo transferidos
var dt = event.dataTransfer;
var files = dt.files;
//percorre os arquivos
var count = files.length;
output(“File Count: ” + count + “\n”);
for (var i = 0; i < files.length; i++) {
//escreve infotmações do arquivos
output(” File ” + i + “:\n(” + (typeof files[i]) + “) : <” + files[i] + ” > ” +
files[i].name + ” ” + files[i].size + “\n”);
new FileUpload(files[i]); //instancia objeto dessa classe, passando o arquivo para o construtor

}
}

function output(text) {
document.getElementById(“output”).textContent += text;
dump(text);
}

function FileUpload(file) {

//cria objeto para requisições assíncronas
var xhr = new XMLHttpRequest();

//cria listeners para o upload (que é quando o xmlhttprequest está enviando o arquivo):

//para o durante o processo
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
var percentage = Math.round((e.loaded * 100) / e.total);
document.getElementById(“p”).innerHTML = percentage;
}
}

//caso ocorra algum erro
xhr.upload.onerror = function(e){
alert(“Erro”);
}

//quando finalizar o upload
xhr.upload.onload = function(event){
document.getElementById(“p”).innerHTML = 100;
}

//abre a conexão; o segundo parâmetro é da url a ser requisitada, que recebe o arquovo
xhr.open(“POST”, “http://www.chrisb.com.br/up.php”);
xhr.overrideMimeType(‘text/plain; charset=x-user-defined-binary’);

//cria objeto FileReader para ler o arquivo
var reader = new FileReader();
//quando acabar de ler o arquivo…
reader.onload = function(e) {
//pega o retorno da função, que é um dado binário
var bin = e.target.result;
//e faz o xmlhttprequest enviar como binário
xhr.sendAsBinary(bin);
};
reader.readAsBinaryString(file); //lê o arquivo como binário

}

window.onload = function() {
var output = document.getElementById(“output”);
output.ondragenter = function(event) {
document.getElementById(‘output’).textContent = ”; event.stopPropagation(); event.preventDefault();
}
output.ondragover = function(event) {
event.stopPropagation(); event.preventDefault();
}
output.ondrop = function(event) {
event.stopPropagation(); event.preventDefault();
dodrop(event);
}
}

</script>
</head>
<body>

<div id=”output” style=”min-height: 100px; white-space: pre; border: 1px solid black;”></div>
<span id=”p”></span>
</body>
</html>

Posted by Posted by Chris under Filed under javascript Comments 3 Comments »

16th nov 2009

Plugin para estilizar selects com jQuery

Uma grande dificuldade que se tem em termos de interfaces para web é estilizar os selects (também conhecidos como combo boxes, desde a época do desenvolvimento de aplicativos com VB, Delphi e afins) nas páginas. Eles devem ser, até onde me lembro, os que menos possuem formas de ter o look & feel alterados.

Se você usa a jQuery UI no seu projeto, pode tentar esse plugin:

http://www.filamentgroup.com/lab/jquery_ui_selectmenu_an_aria_accessible_plugin_for_styling_a_html_select/

Ele foi disponibilizado na área do jQuery UI Labs, que é uma área experimental, para a qual qualquer pessoa pode enviar sua contribuição e, quem sabe, tê-la incorporada ao projeto. O bacana desse plugin?
Você consegue estilizar os selects, colocando cores, fundo, ícones, hierarquia. Tudo de uma forma muito simples:

$(‘select’).selectmenu();

O bacana é que ele já foi desenhado dentro dos temas pré-definidos da jQuery UI, então você pode aproveitar muito do look & feel criado, e ter alguns selects com essa cara abaixo!

Posted by Posted by Chris under Filed under javascript Comments 2 Comments »

12th nov 2009

O POG nosso de cada dia #17

Mais um POG que só o IE 6 nos faz conceber…

O problema

Comecei a usar a jQuery UI em uma implementação, mais precisamente para ter elementos (divs) de três colunas podendo ser rearranjados (dentro das colunas e entre elas) por drag’n drop. Tudo indo bem, suave, com o Sortable da UI. Nenhum bug, impressionante. Mas aí, o cliente reporta um erro: dentro de uma div, tem uns campos input checkbox que perdem a seleção quando a div é arrastada.

Na hora, já quase comecei a chorar, pois me parecia ser um daqueles bugs sem sentido solução, do IE.

O POG

Nada que o Google não resolva… uma pequena busca, e me deparo com esses posts:

O que eles falam? Que você só precisa colocar um atributo mágico chamado defaultChecked com valor defaultChecked nos inputs para ele não perder a seleção. Segue exemplo abaixo:

$(“input”).attr({checked: “checked”, defaultChecked:”defaultChecked”});

Em mais de 5 anos trabalhando – muito – com web, nunca tinha visto esse atributo, nem precisado usar. O porque setar ele? Nem fui atrás de saber, mas certamente não faz sentido! Muito bom, IE6, contribuindo para os blogs que falam sobre gambiarras!

Posted by Posted by Chris under Filed under POG, javascript Comments 4 Comments »

04th nov 2009

Plugin jQuery para criar janela modal

Passando rapidinho aqui para fazer um jabá do plugin para fazer janelas modais com jQuery que o Tidbits disponibilizou.
O plugin foi feito pelo Danilo e mais alguns colegas, depois de terem procurado alguns plugins desse tipo e não terem encontrado nenhum que se adequasse ao que eles precisavam.

O jabá é porque ese plugin acabou me salvando em dois projetos na última semana.

O uso é simples: qualquer elemento ganha um método modal(). Se for um link, automaticamente é usado o href dele – mas você pode passar qualquer url como parâmetro. Será feito um request assíncrono e o resultado dele, jogado no modal.

O bom desse plugin é que ele é leve e muito fácil de usar, e precisa de muito pouca coisa – vê lá os exemplos de uso!

Uma coisa que eu acho que falta – e espero conseguir ter um tempo pra dedicar a fazer essa funcionalidade – é poder passar uma função de callback como parâmetro para ser executada assim que o request terminar. Isso pode ser contornado colocando javascript dentro do conteúdo do retorno, o que não é algo tão ruim se for um projeto pequeno – mas pode gerar uma bagunça em projetos maiores.

Então, o que falta? Você ir visitar a página do plugin: http://www.tidbits.com.br/click-modal-plugin-de-jquery-para-fazer-modal-lightbox

Posted by Posted by Chris under Filed under javascript Comments 2 Comments »

16th out 2009

Novo release da Prototype e atualização da Scriptaculous – agora scripty2

Passou meio que batido – infelizmente – o lançamento de uma nova versão da Prototype, a 1.6.1, no começo de Setembro.

Faça download aqui!

Preciso fazer a minha mea culpa: tenho utilizado em praticamente 100% dos meus projetos a jQuery, e tem sobrado pouco tempo para no mínimo ler as atualizações no blog e fórum da Prototype.

Mas, vamos ao que interessa: as novidades.
Além de ganho de performance – algo que sempre foi criticado na Prototype – agora há compatibilidade com o Google Chrome 1 e o IE8, além de novos eventos de mouse suportados e uma forma de associar chaves/valores a elementos do DOM.
Ao mesmo tempo, foram feitas modificações na forma de distribuicão da biblioteca (com o uso do Sprockets) e a documentação segue o formato PDoc.

Para quem vê apenas essas alterações, pode achar que é pouca coisa, mas a Prototype sempre foi uma biblioteca bem madura, com uma clareza que poucas outras têm. Me parece que o time de desenvolvedores tentou se ater mais a ganhos de performance e documentação para esse release.

Além do que, a Prototype, como já disse outras vezes, é ideal para se construir outras coisas em cima dela – se você quer fazer componentes ricos javascript, eu indico a Prototype como base. E é isso que a antiga script.aculo.us era: um framework com efeitos e manipulação de elementos DOM por javascript, com interações do usuário. Usei o verbo no passado pois o framework está passando por uma bela reformulação, inclusive mudando de nome, para scripty2.

Ainda está em versão alpha, mas muito me agradou o que eu vi, e a forma como o código pode ser escrito. Pouco foi mostrado, mas eu acho que finalmente pode haver uma chance da Prototype voltar a respirar caso o scripty2 venha a conseguir bater de frente com a jQuery UI ou os inúmeros plugins de efeitos escritos para a jQuery (deixando claro novamente que não quero fomentar nenhuma briga entre fanboys de bibliotecas javascript!).

Para aqueles que já usaram, fica a dica. Para aqueles que nunca viram a Prototype, fica a sugestão: faça download e veja o que ela tem de bom, e como ela tem um enfoque diferente de outras bibliotecas.

Posted by Posted by Chris under Filed under javascript Comments 2 Comments »

11th set 2009

Plugin para criar elementos DOM com a jQuery

Algo que sempre senti falta no core da jQuery foi a possibilidade de criar elementos DOM de uma forma mais simples – até porque estava acostumado a fazer isso com o Element() da Prototype, e não queria voltar a usar todos aqueles document.createElement() novamente.

Dei uma procurada e encontrei a jQuery DOM Elements Creator (Domec). Testei e funcionou bem, no IE6, 7 e Firefox. A sintaxe é bem simples, e  para criar uma div, por exemplo, é:

$.create(‘div’, {‘id’: ‘myId’}, ‘myText’)

Vou colocar abaixo uma implementação completa que fiz, criando vários elementos e adicionando-os uns aos outros:

var div = $.create("div",{id: this.htmlId, className: this.htmlClass}, "");
$.create("input",{type: "hidden", className: "widget_type", value: this.type}).appendTo(div);
var divHandler = $.create("div",{className: "widget_handler"});
$.create("h3").appendTo(divHandler);
$.create("a", {href:"#", className: "widget_edit"}, "edit").appendTo(divHandler);
$.create("a", {href:"#", className: "widget_delete"}, "X").appendTo(divHandler);
$.create("br").css({clear: "both"}).appendTo(divHandler);
divHandler.appendTo(div);
$.create("div",{className: "widget_edit_area"}).appendTo(div);
$.create("div",{className: "widget_container"}).appendTo(div);

Veja a documentação do plugin para ver todas as possibilidades.

Observação: testei a performance e foi mais lento, quase o dobro do tempo, para criar elementos do que com document.createElement(). Imagino que num projeto muito grande, isso possa ser um problema, mas em projetos menores não deve ter tanto impacto.

Posted by Posted by Chris under Filed under Tecnologia, javascript Comments No Comments »