75 votes

Comment définir la valeur d'entrée d'un fichier lors de la suppression d'un fichier sur une page?

Je suis d'essayer d'effectuer un contrôle où vous pouvez sélectionner un fichier de soumettre le formulaire et déposer un fichier pour faire la même chose. J'ai quelque chose comme ça où il va également afficher un aperçu du fichier, si c'est une image:

<div class="preview-image-container">

  <input type="file" name="File" id="File" accept="image/*" 
         class="image-url form-control" style="display:none;" />

  <div class="preview-image-dummy"></div><img class="preview-image-url" />
  <div class="preview-image-instruction">
    <div class="preview-image-btn-browse btn btn-primary">Select file</div>
    <p>or drop it here.</p>
  </div>

</div>

Voici un violon avec MCVE.

L'utilisateur déplace le fichier dans l' preview-image-container. Le fichier n'est pas soumis à l'AJAX, l'utilisateur doit soumettre le formulaire qui contiennent plus de données.

Pour des raisons de sécurité, nous ne sommes pas autorisés à modifier la valeur du fichier d'entrée avec JavaScript. Cependant, je sais que l'entrée par défaut prise en charge des fichiers drop, et il y a un tas de sites web qui nous permettent de sélectionner des fichiers en les déposant dans la forme je pense qu'il y a un moyen de le faire.

Comme vous pouvez le voir à partir de la MCVE, je ne m'intéresse qu'à l'aide de jQuery ou JavaScript sans autres bibliothèques.

Bien que dropzone.js pourrait être utilisé, il ne rentre pas dans mes exigences et elle aurait besoin d'un attentionnée quantité de temps pour personnaliser son apparence. En outre, dropzone.js ont certaines exigences de configuration qui ne peuvent pas être respectées au sein de mon ASP.NET application.


Il y a une question similaire, mais n'a pas une bonne réponse:
Comment fixer le fichier de l'objet dans le fichier d'entrée dans le formulaire en HTML?

Aussi ne ressemble pas à glisser / déposer les images les fichiers d'entrée et le prévisualiser avant de le télécharger car j'ai déjà réalisé glisser-déposer et la prévisualisation d'action. Ma question est spécifique au problème d'avoir un fichier vide de saisie lors de la suppression du fichier dans un conteneur parent.

118voto

Samuel Liew Points 17275

Avertissement: Corriger en décembre 2017 et pour les navigateurs modernes seulement.


TL;DR: Oui, maintenant vous pouvez!

*si vous avez un dataTransfer ou objet FileList

Auparavant, programmation, en modifiant les fichiers input[type=file] champ a été désactivé en raison de l'héritage des failles de sécurité, qui sont fixés sur les navigateurs modernes.

Le dernier des grands navigateurs (Firefox), a récemment permis de mettre les fichiers pour le fichier d'entrée de champ. Selon le W3C tests, il semble que vous pouvez déjà le faire sur Google Chrome!

Pertinentes de la capture d'écran et le texte cité de MDN:

enter image description here

Vous pouvez définir en tant que bien que d'obtenir la valeur de HTMLInputElement.files dans tous les navigateurs modernes.
La Source et la compatibilité du navigateur, voir MDN

Le Firefox de correction de discussion thread a cette démo vous pourrez tester sur, et voici la source si vous voulez le modifier. Au cas où ce lien meurt, je vais aussi inclure en tant qu'exécutable, l'extrait de code ci-dessous:

let target = document.documentElement;
let body = document.body;
let fileInput = document.querySelector('input');

target.addEventListener('dragover', (e) => {
  e.preventDefault();
  body.classList.add('dragging');
});

target.addEventListener('dragleave', () => {
  body.classList.remove('dragging');
});

target.addEventListener('drop', (e) => {
  e.preventDefault();
  body.classList.remove('dragging');
  
  fileInput.files = e.dataTransfer.files;
});
body {
  font-family: Roboto, sans-serif;
}

body.dragging::before {
  content: "Drop the file(s) anywhere on this page";
  position: fixed;
  left: 0; width: 100%;
  top: 0; height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 1.5em;
  background-color: rgba(255, 255, 0, .3);
  pointer-events: none;
}

button, input {
  font-family: inherit;
}

a {
  color: blue;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
      <link href="https://fonts.googleapis.com/css?family=Roboto:400,400i,700" rel="stylesheet"> 

  <title>JS Bin</title>
</head>
<body>
  
  <h1>Drag and drop files into file input</h1>
  
  <p><small>Supported in <a href="https://github.com/whatwg/html/issues/2861">WebKit and Blink</a>. To test, drag and drop one or more files from your operating system onto this page.</small></p>
  
  <p>
    <input type="file">
  </p>

</body>
</html>

Remarque importante:

Vous pouvez faire cela seulement si vous avez un FileList OU dataTransfer objet que vous êtes en mesure de fixer le fichier d'entrée de l'élément (comme la méthode setter N'accepte PAS de texte en clair des chaînes de caractères).

Pour de plus amples informations, voir Kaiido de réponse ici: Comment définir les objets de Fichier et la longueur de la propriété à l'objet FileList où les fichiers sont également reflétés à l'objet FormData?


Maintenant pour répondre à votre question de départ, il devrait être aussi simple que cela:

document.querySelector('.preview-image-instruction')
    .addEventListener('drop', (ev) => {
        ev.preventDefault();
        document.querySelector('.image-url').files = ev.dataTransfer.files;
    });

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X