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:
JavaScript:
-
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:
HTML:
-
<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:
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:
JavaScript:
-
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 ver tudo funcionando acesse o exemplo.
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. Estou com o tempo curto e se você descobrir como resolver, poste um comentário.