Enviando vários arquivos sem exibir input file
Dia 06/07/2007 na lista Webstandards-br foi questionado como o gmail fazia, para que sem o input file, fosse enviado arquivo. Porém isso só acontecia no IE, no Firefox era um input normal.O pessoal deu uma olhada no código e concluiu que no IE funcionava algo como:
document.getElementById('InputFile').click();
Porém no Firefox isso não funciona. Não querendo entrar no mérito de qual navegador está certo, pensei em um modo de driblar isso e o resultando acabou resultando neste artigo.
Como fazer
Minha idéia para contornar isso é utilizar um input que fique transparente e colocar uma imagem no fundo do elemento onde esse input está! Veja que não podemos esconder o input, pois ele precisa ser clicado, mas sem que o usuário perceba. Então vamos ao HTML básico:
<form method="post" enctype="multipart/form-data" id="UploadForm">
<p id="uploadButton"> <input id="inputFile" name="inputFile" size="1" type="file" /></p>
</form>
Temos um div chamado uploadButton, que conterá a imagem de fundo e o input que fará a coisa acontecer.
Adicionamos um pouco de CSS:
#inputFile {
float: right;
opacity: 0;
filter: alpha(opacity=0);
}
#uploadButton {
width:88px;
height:20px;
background:url("adicionar.jpg") no-repeat;
float:left;
margin: 0 20px 0 0;
}
#files {
clear:both;
}
Veja que no #inputFile definimos opacity, para funciona no Firefox e um filter para ficar transparente no IE. O #files veremos pra que serve daqui a pouco.
Fazendo a mágica acontecer com javascript
Utilizei a jQuery por pura comodidade, mas poderia facilmente ser feito na mão. Na verdade para enviar um arquivo precisariamos do javascript apenas para exibir o nome do arquivo em algum lugar. Mas como queremos fazer o upload de vários arquivos:
var InputCount = 1;
$(function() {
$("#UploadForm").append("<ul id='files'></ul>");
$("#inputFile").change(function () { newFile() });
});
function newFile() {
$("#files").append("<li>" + $("#inputFile").val() + "</li>");
$("#inputFile").hide();
$("#inputFile").clone().appendTo("#uploadButton");
$("#inputFile").attr("id", "inputFile" + InputCount);
$("#inputFile" + InputCount).attr("name", "inputFile" + InputCount);
InputCount++;
$("#inputFile").change( function() { newFile(); } );
$("#inputFile").val("");
$("#inputFile").show();
}
Para finalizar ainda seria necessário adicionar um botão de submit e tratar o retorno no servidor. Porém isso não será tratado aqui!
Após escrever todo o exemplo e o artigo, resolvi testar no IE6 (o que devia ter sido feito antes) e percebi que não funcionava o filtro da opacidade, apesar de tudo dar certo no IE 5 e no IE 7.