Déclenchez par programme la boîte de dialogue «Sélectionner un fichier»


100

J'ai un élément d'entrée de fichier caché. Est-il possible de déclencher sa boîte de dialogue de sélection de fichier à partir d'un événement de clic sur un bouton?

Réponses:


146

Si vous cherchez à avoir votre propre bouton pour télécharger un fichier au lieu d'utiliser <input type="file" />, vous pouvez faire quelque chose comme:

<input id="myInput" type="file" style="visibility:hidden" />
<input type="button" value="Show Dialog" onclick="$('#myInput').click();" />

Notez que j'ai utilisé visibility: hidden, au lieu de display: none. Vous ne pouvez pas appeler l'événement de clic sur une entrée de fichier non affichée.


Simple pour les cas de base, mais non compatible avec de nombreux navigateurs. Veuillez noter que c'est une bien meilleure idée de combiner cette solution avec la superposition de l'élément d'entrée du fichier sur un bouton à opacity: 0, comme cela a été mentionné dans la réponse de Xeon06.
SquareCat

10
Mise à jour: dans les navigateurs modernes, vous pouvez cliquer sur une entrée qui ne se trouve même pas dans le DOM. Impressionnant!
Adria

7
Je viens d'essayer click()une display:noneentrée et cela a fonctionné
Daniel Cheung

15
Oui, ici en 2015, click()sur un élément avec des display: noneoeuvres! ;) Comment les choses ont changé au cours des quatre dernières années.
ffxsam

Vous pouvez utiliser l' hiddenattribut à la place style="visibility:hidden": <input id="myInput" type="file" hidden>( w3schools.com/tags/att_global_hidden.asp )
cespon

114

La plupart des réponses ici manquent d'informations utiles:

Oui, vous pouvez cliquer par programme sur l'élément d'entrée à l'aide de jQuery / JavaScript, mais uniquement si vous le faites dans un gestionnaire d'événements appartenant à un événement QUI A ÉTÉ DÉMARRÉ PAR L'UTILISATEUR!

Ainsi, par exemple, rien ne se passera si vous, le script, cliquez par programme sur le bouton dans un rappel ajax, mais si vous mettez la même ligne de code dans un gestionnaire d'événements qui a été déclenché par l'utilisateur, cela fonctionnera.

PS Le debugger;mot-clé perturbe la fenêtre de navigation si c'est avant le clic programmatique ... au moins en chrome 33 ...


comme @LouisBataillard le mentionne à juste titre: non seulement le gestionnaire d'événements d'origine doit être initié par l'utilisateur; il doit s'agir spécifiquement d'un événement de clic. Voici un violon qu'il a fourni pour démontrer ceci: lien
Souhaieb Besbes

1
vous pouvez cliquer sur quelque chose qui est généré dynamiquement. dans jquery, c'est-à-dire$(staticElementParent).on("click", "dynamicChild", function(){})
Daniel Cheung

1
MERCI!!!! J'ai testé toutes ces réponses dans la console javascript et je suis devenu fou!
jdkealy

8
Cela fait une demi-heure que je lutte pour ouvrir une fenêtre de saisie de fichier par programmation. PERSONNE D'AUTRE a déclaré qu'il est impossible si l'événement n'est pas démarré par l'utilisateur ... vous méritez beaucoup de +1.
Umagon

1
À partir de Chrome 62, le debugger;mot - clé ne perturbe plus le clic programmatique
Chris W.

62

Pour mémoire, il existe une solution alternative qui ne nécessite pas de Javascript. C'est un peu un hack, exploitant le fait que cliquer sur une étiquette met l'accent sur l'entrée associée.

Vous avez besoin d'un <label>avec un forattribut approprié (pointe vers l'entrée), optionnellement stylé comme un bouton (avec bootstrap, utilisez btn btn-default). Lorsque l'utilisateur clique sur l'étiquette, la boîte de dialogue s'ouvre, exemple:

<!-- optionnal, to add a bit of style -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>

<!-- minimal setup -->
<label for="exampleInput" class="btn btn-default">
  Click me
</label>
<input type="file" id="exampleInput" style="display: none" />


2
J'aime celui-ci, je ne veux pas inclure jQuery complet dans mon projet Angular, fonctionne bien :)
Starscream1984

1
ce comportement est-il fiable dans tous les navigateurs modernes?
JoshuaDavid

Cela fonctionne sans aucun JS, en utilisant le comportement natif du navigateur. Associé aux événements onDrop, l'implémentation d'un téléchargement de fichiers riche en fonctionnalités fonctionne très bien!
Yanick Rochon

J'ai dû jouer avec le CSS mais cela a fonctionné - à savoir la visibilité d'entrée du fichier ayant "display: none" n'est pas correcte dans tous les navigateurs. (Mais une opacité de 0, etc. peut être utilisée)
driftcatcher

13

Je ne sais pas comment les navigateurs gèrent les clics sur les type="file"éléments (problèmes de sécurité et tout), mais cela devrait fonctionner:

$('input[type="file"]').click();

J'ai testé ce JSFiddle dans Chrome, Firefox et Opera et ils affichent tous la boîte de dialogue de navigation de fichiers.


5
Cela semble fonctionner uniquement lorsque l'événement "appelant" est lui-même un événement de clic. Par exemple, il ne semble pas possible d'ouvrir la boîte de dialogue de fichier basée sur un hoverévénement: jsfiddle.net/UQfaZ/1
Louis B.

Savez-vous comment cela peut être testé avec Selenium si l'entrée n'est pas dans le DOM?
Sebastien Lorber

4

J'emballe le input[type=file]dans une étiquette d'étiquette, puis je le stylise labelà votre guise et masque le input.

<label class="btn btn-default fileLabel" data-toggle="tooltip" data-placement="top" title="Upload">
    <input type="file">
    <span><i class="fa fa-upload"></i></span>
</label>

<style>
    .fileLabel input[type="file"] {
        position: fixed;
        top: -1000px;
    }
</style>

Solution purement CSS.


Il suffit de régler <input type="file" hidden>pour supprimer le besoin d'appliquer un style CSS.
Sylvain Lesage

3

Nativement, le seul moyen est de créer un <input type="file"> élément puis de simuler un clic, malheureusement.

Il y a un petit plugin (plug sans vergogne) qui vous évitera d'avoir à faire cela tout le temps: file-dialog

fileDialog()
    .then(file => {
        const data = new FormData()
        data.append('file', file[0])
        data.append('imageName', 'flower')

        // Post to server
        fetch('/uploadImage', {
            method: 'POST',
            body: data
        })
    })

3

La meilleure solution, fonctionne dans tous les navigateurs .. même sur mobile.

<div class="btn" id="s_photo">Upload</div>

<input type="file" name="s_file" id="s_file" style="opacity: 0;">';

<!--jquery-->

<script>
    $("#s_photo").click(function() {
        $("#s_file").trigger("click");
    });
</script>

Le masquage du type de fichier d'entrée pose des problèmes avec les navigateurs, l'opacité est la meilleure solution car elle ne se cache pas, mais ne s'affiche pas. :)


1
vous devez mentionner que cela nécessite une référence jquery.
Brino

L'opacité implique un concept totalement indépendant - vous avez simplement de la chance si cela n'affecte pas votre mise en page avec un élément "transparent". L'élément devrait être là, mais pas visible, donc visibility:hiddendevrait être un meilleur choix.
conny le

visibility: hiddenaffecte toujours la mise en page. display: noneest ce que vous voulez.
stommestack

1

Il n'y a pas de moyen de le faire entre navigateurs, pour des raisons de sécurité. Ce que les gens font généralement, c'est superposer le fichier d'entrée sur quelque chose d'autre et définir sa visibilité sur masqué afin qu'il soit déclenché par lui-même. Plus d'infos ici.


2
Le PO parle <input type="file">, non <select>.
Bojangles

Pas de problème. Je l'ai déjà fait moi-même. En réponse à votre modification, il existe un moyen de le faire; en déclenchant l'événement click de l'élément avec jQuery $.click().
Bojangles

1
@JamWaffles ok c'est bizarre. Je me souviens clairement avoir passé une journée entière là-dessus il y a quelques semaines. Cela n'a pas fonctionné dans Firefox et IE afair. Je me demande ce qu'était l'accord ...
Alex Turpin

Curieuse. J'ai un JSFiddle dans ma réponse qui fonctionne avec FF. Je ne peux pas tester dans IE (je suis sous Linux), donc je ne sais pas si cela va encore vomir.
Bojangles

2
Bon effort de recherche là-bas! Si je dépense un sou pour chaque fois que les développeurs Web doivent pirater un comportement assez normal en quelque chose, je serais très riche.
Bojangles

1

Assurez-vous que vous utilisez la liaison pour obtenir les accessoires de composant dans REACT

class FileUploader extends Component {
  constructor (props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
   onChange=(e,props)=>{
    const files = e.target.files;
    const selectedFile = files[0];
    ProcessFileUpload(selectedFile,props.ProgressCallBack,props.ErrorCallBack,props.CompleatedCallBack,props.BaseURL,props.Location,props.FilesAllowed);
  }
   handleClick = () => {
    this.refs.fileUploader.click();
  }
  render()
  {
  return(
      <div>
        <button type="button" onClick={this.handleClick}>Select File</button>  
        <input type='file' onChange={(e)=>this.onChange(e,this.props)} ref="fileUploader" style={{display:"none"}} />
      </div>)
  }
}



0

Pour ceux qui veulent la même chose mais utilisent React

openFileInput = () => {
    this.fileInput.click()
}

<a href="#" onClick={this.openFileInput}>
    <p>Carregue sua foto de perfil</p>
    <img src={img} />
</a>
<input style={{display:'none'}} ref={(input) => { this.fileInput = input; }} type="file"/>

0
<div id="uploadButton">UPLOAD</div>
<form action="[FILE_HANDLER_URL]" style="display:none">
     <input id="myInput" type="file" />
</form>
<script>
  const uploadButton = document.getElementById('uploadButton');
  const myInput = document.getElementById('myInput');

  uploadButton.addEventListener('click', () => {
    myInput.click();
  });
</script>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.