Posted by admin at Março 12th, 2007
Olá povo, conforme prometido, tô postando aqui uma função pra você fazer upload bem parecido com ajax (não é ajax!!). Função simples e fácil de usar.
Ela faz um upload assíncrono, ou seja, não recarrega a página toda (assim como o AJAX).
Quem usa alguns serviços do google como o GMail ou o GooglePages já conhece este recurso muito bem.
Upload usando apenas AJAX não é viável no ambiente da Internet pois, por motivos de segurança, os navegadores por padrão não dão acesso ao sistema de arquivos para o JavaScript (se quiser descobrir como ativar esta característica não padrão, leia aqui, mas acredito não ser muito útil ajax upload dessa forma).
Esta minha função utiliza técnicas que envolvem iframes, mas não vou dar explicações aqui não. Explicações sobre como desenvolvi a função serão dadas em um novo post. Este post aqui é só para o código.
Ah, sim, no próximo post mostrarei também uma função um pouco mais customizável já pra quem entende melhor de JavaScript.
Testado no Firefox 2.0, Internet Explorer 6.0 e Opera 9.1. Pelamordedeus, quem puder testar em outros navegadores aí e quiser citar a experiência, faça este favor à humanidade e cite a experiência nos comentários. Obrigado.
1) Coloque o código abaixo em um arquivo chamado micoxUpload.js
/* funçõezinhas padrão pra facilitar */
function $m(quem){
//apelido só pra não ficar repetindo o document.getElementById
return document.getElementById(quem)
}
function remove(quem){
quem.parentNode.removeChild(quem);
}
function addEvent(obj, evType, fn){
//o velho do elcio.com.br/crossbrowser
if (obj.addEventListener)
obj.addEventListener(evType, fn, true)
if (obj.attachEvent)
obj.attachEvent("on"+evType, fn)
}
function removeEvent( obj, type, fn ) {
if ( obj.detachEvent ) {
obj.detachEvent( 'on'+type, fn );
} else {
obj.removeEventListener( type, fn, false ); }
}
/* a que faz o serviço pesado */
function micoxUpload(form,url_action,id_elemento_retorno,html_exibe_carregando,html_erro_http){
/******
* micoxUpload - Submete um form para um iframe oculto e pega o resultado. Consequentemente pode
* ser usado pra fazer upload de arquivos de forma assíncrona.
* Use a vontade mas coloque meu nome nos créditos. Licença Creative Commons.
* Versão: 1.0 - 03/03/2007 - Testado no FF2.0 IE6.0 e OP9.1
* Autor: Micox - Náiron JCG - elmicox.blogspot.com - micoxjcg@yahoo.com.br
* Parametros:
* form - o form a ser submetido ou seu ID
* url_action - url pra onde deve ser submetido o form
* id_elemento_retorno - id do elemento que irá receber a informação de retorno
* html_exibe_carregando - Texto (ou imagem) que será exibido enquanto se carrega o upload
* html_erro_http - texto (ou imagem) que será exibido se der erro HTTP.
*******/
//testando se passou o ID ou o objeto mesmo
form = typeof(form)=="string"?$m(form):form;
var erro="";
if(form==null || typeof(form)=="undefined"){ erro += "O form passado no 1o parâmetro não existe na página.\n";}
else if(form.nodeName!="FORM"){ erro += "O form passado no 1o parâmetro da função não é um form.\n";}
if($m(id_elemento_retorno)==null){ erro += "O elemento passado no 3o parâmetro não existe na página.\n";}
if(erro.length>0) {
alert("Erro ao chamar a função micoxUpload:\n" + erro);
return;
}
//criando o iframe
var iframe = document.createElement("iframe");
iframe.setAttribute("id","micox-temp");
iframe.setAttribute("name","micox-temp");
iframe.setAttribute("width","0");
iframe.setAttribute("height","0");
iframe.setAttribute("border","0");
iframe.setAttribute("style","width: 0; height: 0; border: none;");
/* Não usei display:none pra esconder o iframe
pois tem uma lenda que diz que o NS6 ignora
iframes que tenham o display:none */
//adicionando ao documento
form.parentNode.appendChild(iframe);
window.frames['micox-temp'].name="micox-temp"; //ie sucks
//adicionando o evento ao carregar
var carregou = function() {
removeEvent( $m('micox-temp'),"load", carregou);
var cross = "javascript: ";
cross += "window.parent.$m('" + id_elemento_retorno + "').innerHTML = document.body.innerHTML; void(0); ";
$m(id_elemento_retorno).innerHTML = html_erro_http;
$m('micox-temp').src = cross;
//deleta o iframe
setTimeout(function(){ remove($m('micox-temp'))}, 250);
}
addEvent( $m('micox-temp'),"load", carregou)
//setando propriedades do form
form.setAttribute("target","micox-temp");
form.setAttribute("action",url_action);
form.setAttribute("method","post");
form.setAttribute("enctype","multipart/form-data");
form.setAttribute("encoding","multipart/form-data");
//submetendo
form.submit();
//se for pra exibir alguma imagem ou texto enquanto carrega
if(html_exibe_carregando.length > 0){
$m(id_elemento_retorno ).innerHTML = html_exibe_carregando;
}
}
2) Inclua (chame) este arquivo no seu HTML
<script type="text/javascript" src="micoxUpload.js"></script>
3) Os parâmetros na hora de chamar a função são:
- form - o form a ser submetido ou o ID de algum form que queira submeter.
- url_action - url pra onde deve ser submetido o form. Tem a mesma função do parâmetro "action" de um form.
- id_elemento_retorno - id do elemento que irá receber a informação de retorno.
- html_exibe_carregando - Texto (ou imagem) que será exibido enquanto se carrega o upload
- html_erro_http - Texto (ou imagem) que será exibido se der erro HTTP.
4) Pronto. Agora você várias formas de ativar o upload assíncrono. Vou exemplificar aqui 3 formas dentre as várias possíveis:
4.1) Uso básico. Você chama o upload a partir de um button (ou um input-type-button) em um form qualquer:
<legend>Uso básico</legend>
<form>
<input type="file" name="nome_qualquer" />
<div id="recebe_up_basico" class="recebe"> </div>
<button onClick="micoxUpload(this.form,'upa.php','recebe_up_basico','Carregando...','Erro ao carregar'); return false;" type="button">testa</button>
</form>
</fieldset>
4.2) Ativando o upload quando o campo file perde o foco (onblur):
<fieldset>
<legend>Uso no blur do input</legend>
<form>
<input type="file" name="nome_qualquer" onblur="micoxUpload(this.form,'upa.php','recebe_up_onblur','Carregando...','Erro ao carregar')" />
<div id="recebe_up_onblur" class="recebe"> </div>
</form>
</fieldset>
4.3) Agora uma forma que deixará seu form/upload acessível mesmo que o javascript esteja desabilitado:
<fieldset>
<legend>Uso não intrusivo</legend>
<form action="upa.php" target="_blank">
<input type="file" name="nome_qualquer" onblur="micoxUpload(this.form,'upa.php','recebe_up_3','Carregando...','Erro ao carregar')" />
<div id="recebe_up_3" class="recebe"> </div>
</form>
</fieldset>
Pronto. Customize aí agora e bora "uploadar". Bugs, erros, comenta ae.
Por favor, DÚVIDAS SOMENTE NO FÓRUM !!
No próximo post, a explicação e uma versão mais customizável pra quem já entende de JavaScript.