124 votes

Comment ouvrir une boîte de dialogue de sélection de fichier via js ?

$('#id').click();

Il ne fonctionne pas sur Chrome 26 sur Mac OS.

Le problème est en fait la création d'un widget "upload" qui peut être intégré dans un formulaire. Le widget sera composé de deux parties. La première partie est un div avec un bouton d'initialisation et des messages d'erreur/succès. Je pense que le moyen est de mettre un autre formulaire comme la deuxième partie avec l'entrée de fichier et de soumettre le fichier dans l'iframe. Après la soumission, nous remplissons le champ caché dans la première partie du formulaire principal ou nous montrons les erreurs dans le même formulaire.

Le moyen le plus simple est d'ajouter le formulaire de fichier au formulaire principal, mais c'est interdit.

263voto

JS uniquement - pas besoin de jquery

Il suffit de créer un élément de saisie et de déclencher le clic.

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

C'est le plus basique, pop un dialogue de sélection de fichier, mais il ne sert à rien sans traiter le fichier sélectionné...

Traitement des dossiers

Ajout d'un onchange à l'entrée nouvellement créée nous permettrait d'agir une fois que l'utilisateur a sélectionné le fichier.

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

input.onchange = e => { 
   var file = e.target.files[0]; 
}

input.click();

Pour l'instant, nous avons le fichier variable stockant diverses informations :

file.name // the file's name including extension
file.size // the size in bytes
file.type // file type ex. 'application/pdf'

Super !

Mais, que faire si nous avons besoin du contenu du fichier ?

Afin d'accéder au contenu réel du fichier, pour diverses raisons (placer une image, charger dans un canevas, créer une fenêtre avec une url de données en base64, etc. FileReader API

Nous devons créer une instance du FileReader et y charger la référence du fichier sélectionné par l'utilisateur.

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

input.onchange = e => { 

   // getting a hold of the file reference
   var file = e.target.files[0]; 

   // setting up the reader
   var reader = new FileReader();
   reader.readAsText(file,'UTF-8');

   // here we tell the reader what to do when it's done reading...
   reader.onload = readerEvent => {
      var content = readerEvent.target.result; // this is the content!
      console.log( content );
   }

}

input.click();

Essayez de coller le code ci-dessus dans la fenêtre de console de votre devtool, il devrait produire un dialogue select-a-file, après avoir sélectionné le fichier, la console devrait maintenant imprimer le contenu du fichier.

Exemple - "La nouvelle image de fond de Stackoverflow !"

Essayons de créer un dialogue de sélection de fichier pour changer l'image de fond de stackoverflows en quelque chose de plus piquant...

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

input.onchange = e => { 

   // getting a hold of the file reference
   var file = e.target.files[0]; 

   // setting up the reader
   var reader = new FileReader();
   reader.readAsDataURL(file); // this is reading as data url

   // here we tell the reader what to do when it's done reading...
   reader.onload = readerEvent => {
      var content = readerEvent.target.result; // this is the content!
      document.querySelector('#content').style.backgroundImage = 'url('+ content +')';
   }

}

input.click();

ouvrez devtools, et collez le code ci-dessus dans la fenêtre de la console, cela devrait faire apparaître une boîte de dialogue "select-a-file", lors de la sélection d'une image, le fond de la boîte de contenu de stackoverflows devrait changer pour l'image sélectionnée.

A la vôtre !

190voto

Bondye Points 4513

Utilisation de jQuery

Je créerais un bouton et une entrée invisible comme ceci :

<button id="button">Open</button>
<input id="file-input" type="file" name="name" style="display: none;" />

et ajoutez un peu de jQuery pour le déclencher :

$('#button').on('click', function() {
    $('#file-input').trigger('click');
});

Utilisation de Vanilla JS

Même idée, sans jQuery (crédits à @Pascale ) :

<button onclick="document.getElementById('file-input').click();">Open</button>
<input id="file-input" type="file" name="name" style="display: none;" />

29voto

Yairopro Points 1360

Fonction prête à l'emploi (utilisation de Promise)

/**
 * Select file(s).
 * @param {String} contentType The content type of files you wish to select. For instance, use "image/*" to select all types of images.
 * @param {Boolean} multiple Indicates if the user can select multiple files.
 * @returns {Promise<File|File[]>} A promise of a file or array of files in case the multiple parameter is true.
 */
function selectFile(contentType, multiple){
    return new Promise(resolve => {
        let input = document.createElement('input');
        input.type = 'file';
        input.multiple = multiple;
        input.accept = contentType;

        input.onchange = () => {
            let files = Array.from(input.files);
            if (multiple)
                resolve(files);
            else
                resolve(files[0]);
        };

        input.click();
    });
}

Essayez-le ici

// Content wrapper element
let contentElement = document.getElementById("content");

// Button callback
async function onButtonClicked(){
    let files = await selectFile("image/*", true);
    contentElement.innerHTML = files.map(file => `<img src="${URL.createObjectURL(file)}" style="width: 100px; height: 100px;">`).join('');
}

// ---- function definition ----
function selectFile (contentType, multiple){
    return new Promise(resolve => {
        let input = document.createElement('input');
        input.type = 'file';
        input.multiple = multiple;
        input.accept = contentType;

        input.onchange = _ => {
            let files = Array.from(input.files);
            if (multiple)
                resolve(files);
            else
                resolve(files[0]);
        };

        input.click();
    });
}

<button onclick="onButtonClicked()">Select images</button>
<div id="content"></div>

15voto

nunocastromartins Points 289

En HTML uniquement :

<label>
  <input type="file" name="input-name" style="display: none;" />
  <span>Select file</span>
</label>

Vérifiez ce violon avec le code ci-dessus.

14voto

Pascale Points 301

Dans un souci d'exhaustivité, La solution de Ron van der Heijden en pur JavaScript :

<button onclick="document.querySelector('.inputFile').click();">Select File ...</button>
<input class="inputFile" type="file" style="display: none;">

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