É possível limpar um <input type='file' />
valor de controle com jQuery? Eu tentei o seguinte:
$('#control').attr({ value: '' });
Mas não está funcionando.
É possível limpar um <input type='file' />
valor de controle com jQuery? Eu tentei o seguinte:
$('#control').attr({ value: '' });
Mas não está funcionando.
Respostas:
Fácil: envolva um <form>
elemento, chame reset no formulário e remova o formulário usando .unwrap()
. Diferente das .clone()
soluções de outra forma nesse encadeamento, você acaba com o mesmo elemento no final (incluindo propriedades customizadas que foram definidas nele).
Testado e trabalhando em Opera, Firefox, Safari, Chrome e IE6 +. Também funciona em outros tipos de elementos de formulário, com exceção de type="hidden"
.
window.reset = function(e) {
e.wrap('<form>').closest('form').get(0).reset();
e.unwrap();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<input id="file" type="file">
<br>
<input id="text" type="text" value="Original">
</form>
<button onclick="reset($('#file'))">Reset file</button>
<button onclick="reset($('#text'))">Reset text</button>
Como o Timo observa abaixo, se você tiver os botões para acionar a redefinição do campo dentro do campo <form>
, deverá chamar .preventDefault()
o evento para impedir que o <button>
envio seja acionado .
Não funciona no IE 11 devido a um erro não corrigido. O texto (nome do arquivo) é limpo na entrada, mas sua File
lista permanece preenchida.
Resposta rápida: substitua-o.
No código abaixo, eu uso o replaceWith
método jQuery para substituir o controle por um clone próprio. Caso você tenha algum manipulador vinculado a eventos nesse controle, queremos preservá-lo também. Para fazer isso, passamos true
como o primeiro parâmetro do clone
método.
<input type="file" id="control"/>
<button id="clear">Clear</button>
var control = $("#control");
$("#clear").on("click", function () {
control.replaceWith( control = control.clone( true ) );
});
Fiddle: http://jsfiddle.net/jonathansampson/dAQVM/
Se a clonagem, enquanto preserva os manipuladores de eventos, apresenta qualquer problema que você possa considerar ao usar a delegação de eventos para manipular cliques neste controle a partir de um elemento pai:
$("form").on("focus", "#control", doStuff);
Isso evita a necessidade de qualquer manipulador ser clonado junto com o elemento quando o controle está sendo atualizado.
input.value = null;
O Jquery deve cuidar dos problemas entre navegadores / navegadores antigos para você.
Isso funciona em navegadores modernos que eu testei: Chromium v25, Firefox v20, Opera v12.14
Usando jquery 1.9.1
HTML
<input id="fileopen" type="file" value="" />
<button id="clear">Clear</button>
Jquery
$("#clear").click(function () {
$("#fileopen").val("");
});
Em jsfiddle
A seguinte solução javascript também funcionou para mim nos navegadores mencionados acima.
document.getElementById("clear").addEventListener("click", function () {
document.getElementById("fileopen").value = "";
}, false);
Em jsfiddle
Não tenho como testar com o IE, mas teoricamente isso deve funcionar. Se o IE for diferente o suficiente para que a versão Javascript não funcione porque a MS o fez de uma maneira diferente, na minha opinião, o método jquery deve lidar com isso para você; caso contrário, vale a pena apontar para a equipe jquery junto com o método que o IE exige. (Vejo pessoas dizendo "isso não funcionará no IE", mas nenhum javascript de baunilha para mostrar como ele funciona no IE (supostamente um "recurso de segurança"?), Talvez relate isso como um bug para a MS também (se eles conte-o como tal), para que seja corrigido em qualquer versão mais recente)
Como mencionado em outra resposta, uma postagem no fórum jquery
if ($.browser.msie) {
$('#file').replaceWith($('#file').clone());
} else {
$('#file').val('');
}
Mas o jquery agora removeu o suporte para testes de navegador, jquery.browser.
Essa solução javascript também funcionou para mim, é o equivalente baunilha do método jquery.replaceWith .
document.getElementById("clear").addEventListener("click", function () {
var fileopen = document.getElementById("fileopen"),
clone = fileopen.cloneNode(true);
fileopen.parentNode.replaceChild(clone, fileopen);
}, false);
Em jsfiddle
O importante a ser observado é que o cloneNode método não preserva os manipuladores de eventos associados.
Veja este exemplo.
document.getElementById("fileopen").addEventListener("change", function () {
alert("change");
}, false);
document.getElementById("clear").addEventListener("click", function () {
var fileopen = document.getElementById("fileopen"),
clone = fileopen.cloneNode(true);
fileopen.parentNode.replaceChild(clone, fileopen);
}, false);
Em jsfiddle
Mas o jquery.clone oferece isso [* 1]
$("#fileopen").change(function () {
alert("change");
});
$("#clear").click(function () {
var fileopen = $("#fileopen"),
clone = fileopen.clone(true);
fileopen.replaceWith(clone);
});
Em jsfiddle
[* 1] O jquery é capaz de fazer isso se os eventos foram adicionados pelos métodos do jquery, pois mantém uma cópia em jquery.data ; ele não funciona de outra forma; portanto, é um truque / solução alternativa e significa que as coisas não são compatível entre diferentes métodos ou bibliotecas.
document.getElementById("fileopen").addEventListener("change", function () {
alert("change");
}, false);
$("#clear").click(function () {
var fileopen = $("#fileopen"),
clone = fileopen.clone(true);
fileopen.replaceWith(clone);
});
Em jsfiddle
Você não pode obter o manipulador de eventos anexado diretamente do próprio elemento.
Aqui está o princípio geral no vanilla javascript, é assim que o jquery e todas as outras bibliotecas o fazem (aproximadamente).
(function () {
var listeners = [];
function getListeners(node) {
var length = listeners.length,
i = 0,
result = [],
listener;
while (i < length) {
listener = listeners[i];
if (listener.node === node) {
result.push(listener);
}
i += 1;
}
return result;
}
function addEventListener(node, type, handler) {
listeners.push({
"node": node,
"type": type,
"handler": handler
});
node.addEventListener(type, handler, false);
}
function cloneNode(node, deep, withEvents) {
var clone = node.cloneNode(deep),
attached,
length,
evt,
i = 0;
if (withEvents) {
attached = getListeners(node);
if (attached) {
length = attached.length;
while (i < length) {
evt = attached[i];
addEventListener(clone, evt.type, evt.handler);
i += 1;
}
}
}
return clone;
}
addEventListener(document.getElementById("fileopen"), "change", function () {
alert("change");
});
addEventListener(document.getElementById("clear"), "click", function () {
var fileopen = document.getElementById("fileopen"),
clone = cloneNode(fileopen, true, true);
fileopen.parentNode.replaceChild(clone, fileopen);
});
}());
Em jsfiddle
É claro que o jquery e outras bibliotecas têm todos os outros métodos de suporte necessários para manter essa lista; isso é apenas uma demonstração.
.val('')
. Não é apenas mais simples do que clonar o elemento de upload ou adicionar um formulário aninhado? +1.
.val("")
) funcionou perfeitamente, obrigado. Muito mais simples do que clonar a entrada e substituí-la também.
Por razões óbvias de segurança, você não pode definir o valor de uma entrada de arquivo, nem mesmo para uma sequência vazia.
Tudo o que você precisa fazer é redefinir o formulário em que o campo ou se você deseja redefinir apenas a entrada de arquivo de um formulário contendo outros campos, use o seguinte:
function reset_field (e) {
e.wrap('<form>').parent('form').trigger('reset');
e.unwrap();
}
Aqui está um exemplo: http://jsfiddle.net/v2SZJ/1/
Isso funciona para mim.
$("#file").replaceWith($("#file").clone());
http://forum.jquery.com/topic/how-to-clear-a-file-input-in-ie
Espero que ajude.
No IE8, eles fizeram o campo Upload de arquivos somente leitura por segurança. Veja a postagem no blog da equipe do IE :
Historicamente, o HTML File Upload Control () tem sido a fonte de um número significativo de vulnerabilidades de divulgação de informações. Para resolver esses problemas, duas alterações foram feitas no comportamento do controle.
Para bloquear ataques que dependem de "roubar" pressionamentos de tecla para induzir clandestinamente o usuário a digitar um caminho de arquivo local no controle, a caixa de edição Caminho do arquivo agora é somente leitura. O usuário deve selecionar explicitamente um arquivo para upload usando a caixa de diálogo Procurar arquivo.
Além disso, o URLAction “Incluir caminho do diretório local ao fazer upload de arquivos” foi definido como "Desativar" para a Zona da Internet. Essa alteração evita o vazamento de informações do sistema de arquivos local potencialmente confidenciais para a Internet. Por exemplo, em vez de enviar o caminho completo C: \ users \ ericlaw \ documents \ secret \ image.png, o Internet Explorer 8 agora enviará apenas o nome do arquivo image.png.
$("#control").val('')
é tudo o que você precisa! Testado no Chrome usando o JQuery 1.11
Outros usuários também testaram no Firefox.
Fiquei preso com todas as opções aqui. Aqui está um truque que eu fiz que funcionou:
<form>
<input type="file">
<button type="reset" id="file_reset" style="display:none">
</form>
e você pode acionar a redefinição usando jQuery com um código semelhante a este:
$('#file_reset').trigger('click');
(jsfiddle: http://jsfiddle.net/eCbd6/ )
Eu acabei com isso:
if($.browser.msie || $.browser.webkit){
// doesn't work with opera and FF
$(this).after($(this).clone(true)).remove();
}else{
this.setAttribute('type', 'text');
this.setAttribute('type', 'file');
}
pode não ser a solução mais elegante, mas funciona até onde eu sei.
Eu usei https://github.com/malsup/form/blob/master/jquery.form.js , que tem uma função chamadaclearInputs()
, que é cross-browser, bem testada, fácil de usar e também lida com problemas do IE e limpeza de campos ocultos se necessário. Talvez seja uma solução um pouco longa para limpar apenas a entrada de arquivos, mas se você estiver lidando com uploads de arquivos entre navegadores, essa solução é recomendada.
O uso é fácil:
// Limpe todos os campos do arquivo: $ ("input: file"). clearInputs (); // Limpe também os campos ocultos: $ ("input: file"). clearInputs (true); // Limpe campos específicos: $ ("# myfilefield1, # myfilefield2"). clearInputs ();
/ ** * Limpa os elementos de formulário selecionados. * / $ .fn.clearFields = $ .fn.clearInputs = função (includeHidden) { var re = / ^ (?: cor | data | datetime | email | mês | número | senha | intervalo | pesquisa | tel | texto | tempo | url | semana) $ / i; // 'hidden' não está nesta lista retorne this.each (function () { var t = this.type, tag = this.tagName.toLowerCase (); if (re.test (t) || tag == 'textarea') { this.value = ''; } caso contrário, se (t == 'caixa de seleção' || t == 'rádio') { this.checked = false; } caso contrário, se (tag == 'selecionar') { this.selectedIndex = -1; } caso contrário, se (t == "arquivo") { if (/MSIE/.test(navigator.userAgent)) { $ (this) .replaceWith ($ (this) .clone (true)); } outro { $ (this) .val (''); } } caso contrário, se (includeHidden) { // includeHidden pode ser o valor true ou uma sequência de seleção // indicando um teste especial; por exemplo: // $ ('# myForm'). clearForm ('. special: hidden') // o acima limparia entradas ocultas que têm a classe 'especial' if ((includeHidden === true && /hidden/.test(t)) || (typeof includeHidden == 'string' && $ (this) .is (includeHidden))) this.value = ''; } }); };
O valor das entradas do arquivo é somente leitura (por razões de segurança). Você não pode colocá-lo em branco programaticamente (exceto chamando o método reset () do formulário, que tem um escopo mais amplo do que apenas esse campo).
Consegui fazer o meu trabalhar com o seguinte código:
var input = $("#control");
input.replaceWith(input.val('').clone(true));
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>
A .clone()
coisa não funciona no Opera (e possivelmente em outros). Mantém o conteúdo.
O método mais próximo aqui para mim foi o de Jonathan, no entanto, garantindo que o campo preservasse seu nome, classes, etc., gerando um código confuso no meu caso.
Algo assim pode funcionar bem (graças a Quentin também):
function clearInput($source) {
var $form = $('<form>')
var $targ = $source.clone().appendTo($form)
$form[0].reset()
$source.replaceWith($targ)
}
Eu consegui fazer isso funcionar usando o seguinte ...
function resetFileElement(ele)
{
ele.val('');
ele.wrap('<form>').parent('form').trigger('reset');
ele.unwrap();
ele.prop('files')[0] = null;
ele.replaceWith(ele.clone());
}
Isso foi testado no IE10, FF, Chrome e Opera.
Existem duas advertências ...
Ainda não funciona corretamente no FF, se você atualizar a página, o elemento file será preenchido novamente com o arquivo selecionado. De onde está obtendo essa informação está além de mim. O que mais relacionado a um elemento de entrada de arquivo eu poderia tentar limpar?
Lembre-se de usar a delegação em todos os eventos anexados ao elemento de entrada do arquivo, para que eles ainda funcionem quando o clone for criado.
O que não entendo é que quem pensou que não permitir que você limpe um campo de entrada de uma seleção de arquivo inaceitável inválida era uma boa idéia?
OK, não me permita defini-lo dinamicamente com um valor para não poder lixivar arquivos do sistema operacional de um usuário, mas deixe-me limpar uma seleção inválida sem redefinir um formulário inteiro.
Não é como 'aceitar' faz nada além de um filtro e, no IE10, ele nem entende os tipos de mímica do MS Word, é uma piada!
.pop()
a matriz de arquivos em vez de defini-la como nula. isso parece limpar o arquivo corretamente.
No meu Firefox 40.0.3, apenas trabalho com este
$('input[type=file]').val('');
$('input[type=file]').replaceWith($('input[type=file]').clone(true));
Tentei com a maioria das técnicas mencionadas pelos usuários, mas nenhuma delas funcionou em todos os navegadores. ou seja: clone () não funciona no FF para entradas de arquivo. Acabei copiando manualmente a entrada do arquivo e substituindo o original pela copiada. Funciona em todos os navegadores.
<input type="file" id="fileID" class="aClass" name="aName"/>
var $fileInput=$("#fileID");
var $fileCopy=$("<input type='file' class='"+$fileInput.attr("class")+" id='fileID' name='"+$fileInput.attr("name")+"'/>");
$fileInput.replaceWith($fileCopy);
$("input[type=file]").wrap("<div id='fileWrapper'/>");
$("#fileWrapper").append("<div id='duplicateFile' style='display:none'>"+$("#fileWrapper").html()+"</div>");
$("#fileWrapper").html($("#duplicateFile").html());
Isso funciona com Chrome, FF e Safari
$("#control").val("")
Pode não funcionar com o IE ou Opera
Torne-o assíncrono e redefina-o depois que as ações desejadas do botão forem executadas.
<!-- Html Markup --->
<input id="btn" type="file" value="Button" onchange="function()" />
<script>
//Function
function function(e) {
//input your coding here
//Reset
var controlInput = $("#btn");
controlInput.replaceWith(controlInput = controlInput.val('').clone(true));
}
</script>
function clear() {
var input = document.createElement("input");
input.setAttribute('type', 'file');
input.setAttribute('value', '');
input.setAttribute('id', 'email_attach');
$('#email_attach').replaceWith( input.cloneNode() );
}
Isto não funciona para mim:
$('#Attachment').replaceWith($(this).clone());
or
$('#Attachment').replaceWith($('#Attachment').clone());
assim, no asp mvc, uso recursos de barbear para substituir a entrada de arquivo. primeiro, crie uma variável para a string de entrada com Id e Nome e, em seguida, use-a para mostrar na página e substituir no botão de redefinição, clique em:
@{
var attachmentInput = Html.TextBoxFor(c => c.Attachment, new { type = "file" });
}
@attachmentInput
<button type="button" onclick="$('#@(Html.IdFor(p => p.Attachment))').replaceWith('@(attachmentInput)');">--</button>
Uma maneira fácil é alterar o tipo de entrada e alterá-lo novamente.
Algo assim:
var input = $('#attachments');
input.prop('type', 'text');
input.prop('type', 'file')
É fácil lol (funciona em todos os navegadores [exceto ópera]):
$('input[type=file]').each(function(){
$(this).after($(this).clone(true)).remove();
});
JS Fiddle: http://jsfiddle.net/cw84x/1/
reset()
para eg.reset2()
, porque pelo menos no Chrome todos os campos são limpos, se estiveremreset()
. E adicione event.preventDefault () depois de limpar a chamada para impedir o envio. Desta forma:<button onclick="reset2($('#file'));event.preventDefault()">Reset file</button>
. Exemplo de trabalho: jsfiddle.net/rPaZQ/23 .