Como posso limpar uma entrada de arquivo HTML com JavaScript?

154

Quero limpar a entrada do arquivo no meu formulário.

Eu sei sobre como definir as fontes para o mesmo método ... Mas esse método não apaga o caminho do arquivo selecionado.

Nota : Gostaria de evitar a necessidade de recarregar a página, redefinir o formulário ou realizar uma chamada AJAX.

Isso é possível?

thomaux
fonte

Respostas:

-10

Que tal remover esse nó, criar um novo com o mesmo nome?

DFectuoso
fonte
46
Como assim, me dê um exemplo, por favor.
1
você perderá seus manipuladores, como este: var inputPhoto = document.getElementById ('photoInput'); inputPhoto.addEventListener ('change', handler_file, false);
Rui Martins
Votado por falta de explicação!
Jason
211

Existem três maneiras de limpar a entrada de arquivo com javascript:

  1. defina a propriedade value como vazia ou nula.

    Funciona para o IE11 + e outros navegadores modernos.

  2. Crie um novo elemento de entrada de arquivo e substitua o antigo.

    A desvantagem é que você perderá ouvintes de eventos e propriedades de expando.

  3. Redefina o formulário do proprietário pelo método form.reset ().

    Para evitar afetar outros elementos de entrada no mesmo formulário do proprietário, podemos criar um novo formulário vazio e anexar o elemento de entrada do arquivo a esse novo formulário e redefini-lo. Dessa forma, funciona para todos os navegadores.

Eu escrevi uma função javascript. demo: http://jsbin.com/muhipoye/1/

function clearInputFile(f){
    if(f.value){
        try{
            f.value = ''; //for IE11, latest Chrome/Firefox/Opera...
        }catch(err){ }
        if(f.value){ //for IE5 ~ IE10
            var form = document.createElement('form'),
                parentNode = f.parentNode, ref = f.nextSibling;
            form.appendChild(f);
            form.reset();
            parentNode.insertBefore(f,ref);
        }
    }
}
cuixiping
fonte
1
Não devemos remover também o formulário criado posteriormente?
Andrey
1
Não, você não precisa. o elemento do formulário não foi anexado à árvore de documentos da página.
cuixiping
5
Apenas uma palavra de aviso, o uso das abordagens 2. ou 3. pode ter implicações para você, se você deseja preservar eventos e outros atributos que foram adicionados a um elemento programaticamente. No meu caso, adicionei um evento onclick a um elemento do formulário que desapareceu após a redefinição do formulário. Nesse caso, a abordagem 1. é melhor. (Isso foi observado para 2., mas também pode acontecer por 3.)
Wolfie Inu
85

tl; dr : para navegadores modernos, basta usar

input.value = '';

Resposta antiga:

E se:

input.type = "text";
input.type = "file";

Ainda preciso entender por que isso não funciona com o webkit .

De qualquer forma, isso funciona com o IE9>, Firefox e Opera.
A situação com o webkit é que parece que não consigo alterá-lo novamente para o arquivo.
Com o IE8, a situação é que ele lança uma exceção de segurança.

Edit: Para webkit, Opera e firefox, isso funciona, no entanto:

input.value = '';

(verifique a resposta acima com esta proposta)

Vou ver se consigo encontrar uma maneira mais limpa de fazer esse navegador cruzado sem a necessidade do GC.

Edit2:

try{
    inputs[i].value = '';
    if(inputs[i].value){
        inputs[i].type = "text";
        inputs[i].type = "file";
    }
}catch(e){}

Funciona com a maioria dos navegadores. Não funciona com o IE <9, isso é tudo.
Testado no firefox 20, chrome 24, opera 12, IE7, IE8, IE9 e IE10.

brunoais
fonte
35

Definir o valor para ''não funciona em todos os navegadores.

Em vez disso, tente definir o valor da seguinte nullforma:

document.getElementById('your_input_id').value= null;

EDIT: Eu recebo os motivos de segurança muito válidos para não permitir que o JS defina a entrada do arquivo, no entanto, parece razoável fornecer um mecanismo simples para limpar a seleção de saída já selecionada. Tentei usar uma string vazia, mas ela não funcionou em todos os navegadores, NULLfuncionou em todos os navegadores que experimentei (Opera, Chrome, FF, IE11 + e Safari).

EDIT: Observe que a configuração para NULLfunciona em todos os navegadores enquanto a configuração para uma string vazia não.

BigMac66
fonte
6
Infelizmente não estou vendo isso em all browsers... ele não funciona no IE8, IE9 ou IE10 (mas funciona no IE11).
freefaller
Bem, caramba. Não testei versões mais antigas do navegador IE. Desculpe.
BigMac66
31

Infelizmente, nenhuma das respostas acima parece cobrir todas as bases - pelo menos não nos meus testes com javascript vanilla.

  • .value = nullparece funcionar no FireFox, Chome, Opera e IE11 (mas não no IE8 / 9/10)

  • .cloneNode(e .clone()no jQuery) no FireFox parece copiar o .valueexcesso, tornando o clone inútil.

Então, aqui está a função javascript vanilla que eu escrevi que funciona no FireFox (27 e 28), Chrome (33), IE (8, 9, 10, 11), Opera (17) ... esses são os únicos navegadores disponíveis atualmente para eu testar.

function clearFileInput(ctrl) {
  try {
    ctrl.value = null;
  } catch(ex) { }
  if (ctrl.value) {
    ctrl.parentNode.replaceChild(ctrl.cloneNode(true), ctrl);
  }
}

O ctrlparâmetro é a própria entrada do arquivo, portanto a função seria chamada como ...

clearFileInput(document.getElementById("myFileInput"));
caçador
fonte
1
Essa é a resposta. Um dos problemas com tantas respostas para esta pergunta - não apenas nesta página, mas também em outros fóruns, é que você pode limpar o texto "3 arquivos selecionados", mas na verdade não limpa os arquivos http fila. O que acontece é que na próxima vez que você tentar fazer o upload, você poderá selecionar apenas um arquivo e, pior ainda, ele será salvo na pasta anterior. Essa resposta limpará os dois, e você poderá retomar o upload do próximo conjunto de arquivos com a mesma facilidade com que carregou o primeiro conjunto de arquivos.
TARKUS 28/04
A ifdeclaração não deve ser colocada dentro do catchbloco?
Fahmi
@Fahmi - não, não deveria
freefaller
Ah, eu pensei que o IE8 / 9/10 lançaria uma exceção ao tentar definir o valor para null. Importa-se de explicar qual é o sentido de colocar ctrl.value = null;dentro de um try...catchbloco então? Desculpe pela nova pergunta.
Fahmi
1
ctrl.parentNode.replaceChild(ctrl.cloneNode(true), ctrl);- em que ponto, na verdade, limpamos o valor, já que cloneNodetambém o copia?
Fahmi
11

Você precisa substituí-lo por uma nova entrada de arquivo. Aqui está como isso pode ser feito com o jQuery:

var inputFile = $('input[type=field]');
inputFile.wrap('<div />');

e use esta linha quando precisar limpar o campo de entrada (em algum evento, por exemplo):

inputFile.parent().html( inputFile.parent().html() );
Jamland
fonte
Para substituir o elemento original, este parece melhor: stackoverflow.com/questions/1043957/...
Mengdi Gao
9
document.getElementById('your_input_id').value=''

Edit:
Este não funciona no IE e na ópera, mas parece funcionar para o Firefox, Safari e Chrome.

Soufiane Hassou
fonte
7
Isso funciona para mim, embora eu sempre me pergunte por quanto tempo.
586 Pekka
isso não funcionará, apenas em alguns navegadores, e também definir o valor de uma entrada de arquivo é uma violação de segurança ... não é uma boa escolha.
5

Eu estava tendo o mesmo problema e eu vim com isso.

var file = document.querySelector('input');
var emptyFile = document.createElement('input');
emptyFile.type = 'file';

document.querySelector('button').onclick = function(){
  file.files = emptyFile.files;
}
<input type='file'>
<button>clear</button>

ajit kumar
fonte
4

Isso é realmente muito fácil.

document.querySelector('#input-field').value = '';
anonimato
fonte
3

Eu tenho procurado uma maneira simples e limpa de limpar a entrada de arquivos HTML, as respostas acima são ótimas, mas nenhuma delas realmente responde ao que estou procurando, até que me deparei com a Web com uma maneira simples e elegante de fazer isso:

var $input = $("#control");

$input.replaceWith($input.val('').clone(true));

todo o crédito é para Chris Coyier .

// Referneces
var control = $("#control"),
    clearBn = $("#clear");

// Setup the clear functionality
clearBn.on("click", function(){
    control.replaceWith( control.val('').clone( true ) );
});

// Some bound handlers to preserve when cloning
control.on({
    change: function(){ console.log( "Changed" ) },
     focus: function(){ console.log(  "Focus"  ) }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input type="file" id="control">
<br><br>
<a href="#" id="clear">Clear</a>

chebaby
fonte
..e para você, isso me ajudou a verificar e exibir erros em um possível upload de arquivo. Isso é redefinido por erro e permite que o usuário reenvie o mesmo arquivo, caso alguém esteja procurando algo parecido com isto.
Clinton Dobbs
1

As respostas acima oferecem soluções um pouco desajeitadas pelos seguintes motivos:

  1. Eu não gosto de ter que fazer wrapo inputprimeiro e, em seguida, obter o html, é muito envolvido e sujo.

  2. O JS entre navegadores é útil e parece que, neste caso, há muitas incógnitas para usar a typecomutação de maneira confiável (que, novamente, é um pouco suja) e definir valuecomo''

Então, ofereço minha solução baseada em jQuery:

$('#myinput').replaceWith($('#myinput').clone())

Ele faz o que diz, substitui a entrada por um clone de si mesmo. O clone não terá o arquivo selecionado.

Vantagens:

  1. Código simples e compreensível
  2. Sem embalagem desajeitada ou troca de tipo
  3. Compatibilidade entre navegadores (corrija-me se estiver errado aqui)

Resultado: programador feliz

Mosselman
fonte
3
Cross browser compatibility... meus testes mostram que o Firefox cópias sobre o .valuecomo parte do .clone(), portanto, tornando-o inútil
freefaller
@ freefaller porque não mudar o valor antes de ligar replaceWith? Eu estou usando clone()a mim mesmo e ele está bem no firefox de trabalho (eu não sei se este é ainda o caso para você, um ano depois =))
Abdo
@ Abdo - se você olhar para a minha resposta, verá que sim
freefaller
A questão não está perguntando sobre jQuery; está perguntando sobre javascript.
Arel
1

Aqui estão meus dois centavos, os arquivos de entrada são armazenados como matriz, então aqui está como anulá-lo

document.getElementById('selector').value = []

isso retorna uma matriz vazia e funciona em todos os navegadores

Sam Hasan
fonte
0

O que me ajudou é que tentei buscar e fazer upload do último arquivo selecionado usando um loop, em vez de limpar a fila, e funcionou. Aqui está o código.

for (int i = 0; i <= Request.Files.Count-1; i++)
{
 HttpPostedFileBase uploadfile = files[i];
 Stream fs = uploadfile.InputStream;
 BinaryReader br = new BinaryReader(fs);
 Byte[] imageBytes = br.ReadBytes((Int32)fs.Length);
}

Espero que isso possa ajudar alguns.

dotRag
fonte
0

Tentei a maioria das soluções, mas parecia que ninguém funcionava. No entanto, eu encontrei um passeio por ele abaixo.

A estrutura do formulário é: form=> label, inpute submit button. Depois de escolher um arquivo, o nome do arquivo será mostrado pelo rótulo, manualmente, em JavaScript.

Portanto, minha estratégia é: inicialmente o envio buttoné desativado, depois que um arquivo é escolhido, o disabledatributo do botão enviar será removido para que eu possa enviar o arquivo. Depois do envio, limpo o labelque faz com que pareça limpar o arquivo, inputmas na verdade não. Depois, desabilitarei o botão Enviar novamente para impedir o envio do formulário.

Ao definir o envio button disableou não, interrompo o envio do arquivo várias vezes, a menos que escolha outro arquivo.

user419050
fonte
0

Mudei para digitar texto e voltei a digitar para arquivo usando setAttribute

'<input file-model="thefilePic" style="width:95%;" type="file" name="file" id="filepicture" accept="image/jpeg" />'

'var input=document.querySelector('#filepicture');'

if(input != null)
{
    input.setAttribute("type", "text");
    input.setAttribute("type", "file");
}
Haiam
fonte