Comment puis-je effacer une entrée de fichier HTML avec JavaScript?

154

Je souhaite effacer l'entrée de fichier dans mon formulaire.

Je sais comment définir les sources sur la même méthode ... Mais cette méthode n'effacera pas le chemin du fichier sélectionné.

Remarque : je voudrais éviter d'avoir à recharger la page, réinitialiser le formulaire ou effectuer un appel AJAX.

Est-ce possible?

Thomaux
la source

Réponses:

-10

Pourquoi ne pas supprimer ce nœud, en créer un nouveau avec le même nom?

DFectuoso
la source
46
comment voulez-vous dire, donnez-moi un exemple s'il vous plaît.
1
vous perdrez vos gestionnaires, comme celui-ci: var inputPhoto = document.getElementById ('photoInput'); inputPhoto.addEventListener ('change', handler_file, false);
Rui Martins
Voté pour l'explication manquante!
Jason le
212

Il existe 3 façons d'effacer l'entrée de fichier avec javascript:

  1. définissez la propriété value sur vide ou null.

    Fonctionne pour IE11 + et d'autres navigateurs modernes.

  2. Créez un nouvel élément d'entrée de fichier et remplacez l'ancien.

    L'inconvénient est que vous perdrez les écouteurs d'événements et les propriétés d'expansion.

  3. Réinitialisez le formulaire du propriétaire via la méthode form.reset ().

    Pour éviter d'affecter d'autres éléments d'entrée dans le même formulaire propriétaire, nous pouvons créer un nouveau formulaire vide et ajouter l'élément d'entrée de fichier à ce nouveau formulaire et le réinitialiser. Cette méthode fonctionne pour tous les navigateurs.

J'ai écrit une fonction javascript. démo: 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
la source
1
Ne devrions-nous pas également supprimer le formulaire créé par la suite?
Andrey
1
Non, vous n'en avez pas besoin. l'élément de formulaire n'a pas été ajouté à l'arborescence du document de la page.
cuixiping le
5
Juste un mot d'avertissement, l'utilisation des approches 2. ou 3. peut avoir des implications pour vous si vous souhaitez conserver les événements et autres attributs qui ont été ajoutés à un élément par programmation. Dans mon cas, j'ai ajouté un événement onclick à un élément de formulaire qui a disparu après la réinitialisation du formulaire. Dans un tel cas, l'approche 1. est meilleure. (Cela a été noté pour 2., mais peut également arriver pour 3.)
Wolfie Inu
86

tl; dr : Pour les navigateurs modernes, utilisez simplement

input.value = '';

Ancienne réponse:

Que diriez-vous:

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

Je dois encore comprendre pourquoi cela ne fonctionne pas avec Webkit .

Quoi qu'il en soit, cela fonctionne avec IE9>, Firefox et Opera.
La situation avec Webkit est que je semble ne pas pouvoir le remettre en fichier.
Avec IE8, la situation est qu'il lève une exception de sécurité.

Edit: Pour Webkit, Opera et Firefox, cela fonctionne, cependant:

input.value = '';

(vérifiez la réponse ci-dessus avec cette proposition)

Je vais voir si je peux trouver une manière plus propre de faire ce cross-browser sans avoir besoin du GC.

Edit2:

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

Fonctionne avec la plupart des navigateurs. Ne fonctionne pas avec IE <9, c'est tout.
Testé sur Firefox 20, Chrome 24, Opera 12, IE7, IE8, IE9 et IE10.

brunoais
la source
36

La définition de la valeur sur ''ne fonctionne pas dans tous les navigateurs.

Essayez plutôt de définir la valeur nullcomme suit:

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

EDIT: J'obtiens les raisons de sécurité très valables pour ne pas autoriser JS à définir l'entrée de fichier, mais il semble raisonnable de fournir un mécanisme simple pour effacer déjà la sélection de sortie. J'ai essayé d'utiliser une chaîne vide mais cela ne fonctionnait pas dans tous les navigateurs, NULLfonctionnait dans tous les navigateurs que j'ai essayés (Opera, Chrome, FF, IE11 + et Safari).

EDIT: Veuillez noter que le réglage sur NULLfonctionne sur tous les navigateurs tandis que le réglage sur une chaîne vide ne l'a pas fait.

BigMac66
la source
6
Malheureusement, je ne vois pas cela dans all browsers... cela ne fonctionne pas dans IE8, IE9 ou IE10 (mais fonctionne dans IE11).
freefaller
Eh bien dang. Je n'ai pas testé les anciennes versions du navigateur IE. Désolé.
BigMac66
31

Malheureusement, aucune des réponses ci-dessus ne semble couvrir toutes les bases - du moins pas avec mes tests avec javascript vanille.

  • .value = nullsemble fonctionner sur FireFox, Chome, Opera et IE11 (mais pas IE8 / 9/10 )

  • .cloneNode(et .clone()dans jQuery) sur FireFox semble copier le .valuedessus, rendant ainsi le clone inutile.

Voici donc la fonction javascript vanille que j'ai écrite qui fonctionne sur FireFox (27 et 28), Chrome (33), IE (8, 9, 10, 11), Opera (17) ... ce sont les seuls navigateurs actuellement disponibles à moi de tester avec.

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

Le ctrlparamètre est l'entrée de fichier elle-même, donc la fonction serait appelée comme ...

clearFileInput(document.getElementById("myFileInput"));
freefaller
la source
1
Voilà la réponse. L'un des problèmes avec tant de réponses à cette question - pas seulement sur cette page, mais aussi dans d'autres forums, est que vous pouvez effacer le texte "3 fichiers sélectionnés", mais cela n'efface pas réellement les fichiers http queue. Ce qui se passe alors, c'est que la prochaine fois que vous essayez de télécharger, vous ne pouvez sélectionner qu'un seul fichier, et pire, il est enregistré dans le dossier de fichiers précédent. Cette réponse effacera les deux et vous pourrez reprendre le téléchargement du prochain ensemble de fichiers tout aussi facilement que vous avez téléchargé le premier ensemble de fichiers.
TARKUS
La ifdéclaration ne devrait-elle pas être placée à l'intérieur du catchbloc?
Fahmi
@Fahmi - non, ça ne devrait pas
freefaller
Oh, je pensais que IE8 / 9/10 lèvera une exception en essayant de définir la valeur sur null. Ça vous dérange d'expliquer à quoi sert alors de mettre à l' ctrl.value = null;intérieur d'un try...catchbloc? Désolé pour la question newb.
Fahmi
1
ctrl.parentNode.replaceChild(ctrl.cloneNode(true), ctrl);- à quel moment nous effaçons-nous réellement la valeur, puisque la cloneNodecopie également?
Fahmi
12

SOLUTION

Le code suivant a fonctionné pour moi avec jQuery. Il fonctionne dans tous les navigateurs et permet de conserver les événements et les propriétés personnalisées.

var $el = $('#your-input-id');
$el.wrap('<form>').closest('form').get(0).reset();
$el.unwrap();

DEMO

Voir ce jsFiddle pour le code et la démonstration.

LIENS

Gyrocode.com
la source
11

Vous devez le remplacer par une nouvelle entrée de fichier. Voici comment cela peut être fait avec jQuery:

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

et utilisez cette ligne lorsque vous devez effacer le champ de saisie (sur un événement par exemple):

inputFile.parent().html( inputFile.parent().html() );
Jamland
la source
Pour remplacer l'élément d'origine, cela semble mieux: stackoverflow.com/questions/1043957/…
Mengdi Gao
9
document.getElementById('your_input_id').value=''

Edit:
Celui-ci ne fonctionne pas dans IE et Opera, mais semble fonctionner pour Firefox, Safari et Chrome.

Soufiane Hassou
la source
7
Cela fonctionne pour moi, même si je me demande toujours pendant combien de temps.
Pekka
cela ne fonctionnera pas, uniquement dans certains navigateurs, et la définition de la valeur d'une entrée de fichier est une faille de sécurité ... pas un bon choix.
5

J'avais le même problème et j'ai trouvé ça.

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
la source
4

C'est en fait assez simple.

document.querySelector('#input-field').value = '';
anonyme
la source
3

Je cherchais un moyen simple et propre d'effacer l'entrée de fichier HTML, les réponses ci-dessus sont excellentes, mais aucune d'entre elles ne répond vraiment à ce que je recherche, jusqu'à ce que je tombe sur le Web avec une manière simple et élégante de le faire:

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

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

tout le mérite revient à 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
la source
..et à vous mon pote, cela m'a aidé lors de la vérification et de l'affichage des erreurs dans un téléchargement potentiel de fichier. Cela se réinitialise en cas d'erreur et permet à l'utilisateur de télécharger à nouveau le même fichier au cas où quelqu'un chercherait quelque chose comme ça.
Clinton Dobbs
1

Les réponses ci-dessus offrent des solutions quelque peu maladroites pour les raisons suivantes:

  1. Je n'aime pas avoir wraple inputpremier et ensuite obtenir le html, c'est très compliqué et sale.

  2. Cross browser JS est pratique et il semble que dans ce cas, il y ait trop d'inconnues pour utiliser de manière fiable la typecommutation (qui, encore une fois, est un peu sale) et le réglage valuesur''

Je vous propose donc ma solution basée sur jQuery:

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

Il fait ce qu'il dit, il remplace l'entrée par un clone de lui-même. Le clone n'aura pas le fichier sélectionné.

Avantages:

  1. Code simple et compréhensible
  2. Pas d'emballage maladroit ni de changement de type
  3. Compatibilité cross browser (corrigez-moi si je me trompe ici)

Résultat: programmeur heureux

Mosselman
la source
3
Cross browser compatibility... mes tests montrent que FireFox copie le dans le .valuecadre du .clone(), le rendant donc inutile
freefaller
@freefaller pourquoi ne pas changer la valeur avant d'appeler replaceWith? Je m'utilise moi- clone()même et cela fonctionne bien dans Firefox (je ne sais pas si c'est toujours le cas pour vous un an plus tard =))
Abdo
@Abdo - si vous regardez ma réponse, vous verrez que je le fais
freefaller
La question ne concerne pas jQuery; il pose des questions sur javascript.
Arel
1

Voici mes deux cents, les fichiers d'entrée sont stockés sous forme de tableau, voici comment l'annuler

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

cela renvoie un tableau vide et fonctionne sur tous les navigateurs

Sam Hasan
la source
0

Ce qui m'a aidé, c'est que j'ai essayé de récupérer et de télécharger le dernier fichier sélectionné en utilisant une boucle, au lieu de vider la file d'attente, et cela a fonctionné. Voici le code.

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);
}

J'espère que cela pourrait aider certains.

dotRag
la source
0

J'ai essayé la plupart des solutions, mais il ne semblait que personne ne fonctionnait. Cependant, j'ai trouvé une promenade pour cela ci-dessous.

La structure du formulaire est: form=> label, inputet submit button. Après avoir choisi un fichier, le nom du fichier sera affiché par l'étiquette en le faisant manuellement dans JavaScript.

Ma stratégie est donc la suivante: initialement, la soumission buttonest désactivée, après qu'un fichier est choisi, l' disabledattribut du bouton d' envoi sera supprimé de sorte que je puisse soumettre le fichier. Après avoir soumis, j'efface le, labelce qui donne l'impression d'effacer le fichier, inputmais ce n'est pas le cas. Ensuite, je désactiverai à nouveau le bouton d'envoi pour éviter de soumettre le formulaire.

En définissant la soumission button disableou non, j'arrête la soumission du fichier plusieurs fois, sauf si je choisis un autre fichier.

utilisateur419050
la source
0

J'ai changé pour taper du texte et revenir à taper dans un fichier en utilisant 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
la source
0

Il input.value = nulls'agit d'une méthode de travail, mais elle ne déclenchera l' changeévénement d'entrée que si elle est appelée à partir d'un onclickévénement.

La solution à cela serait d'appeler ce onchangegestionnaire manuellement chaque fois que vous devez réinitialiser l'entrée.

function reset_input(input) {
    $(input)[0].value = null;
    input_change_handler();
}
function input_change_handler() {
    // this happens when there's been a change in file selection

    if ($(input)[0].files.length) {
        // file(s) selected
    } else {
        // nothing is selected
    }
}
$(input).on('change', input_change_handler);
Tengiz
la source