Il n’y a pas à dire, Bootstrap coupe souvent les coins ronds quand il est question de documenter le plugiciel d’un tiers parti. La saisie de fichier est un bel exemple. Particulièrement Bootstrap 4, même si la version 4.2 améliore avec le temps la documentation et surtout les exemples.
Au-delà de la « normalisation » de l’ergonomie et des IU (interface usager) pourquoi utilise-t-on Bootstrap si ce n’est de la facilité et la rapidité d’utilisation ? Alors on n’attend rien de moins en lisant la documentation. Un simple copier-coller suffirait et à la limite un petit JavaScript caché en bas de la page. Au pire, on scrute le code source pour mieux comprendre.
Mais pas avec la saisie de fichier (input de type « file »). Bootstrap se contente d’écrire « nous utilisons bs-custom-file-input dans ce document ». Fait-il partie du bundle ? He non ! Et le site qui l’offre, tout en étant encore plus succinct, offre bien plus qu’un simple input...
Pire, Bootstrap termine la documentation sur ce bout de phrase « Bootstrap also provides a way to translate the “Browse” text in HTML with the data-browse attribute which can be added to the custom input label ». Give me a break ! On a beau suivre le document qui explique le principe, on finit par refaire le tout maison. Plus simple, plus rapide et sans « plug-in » !
Je suis plutôt pur JavaScript (Vanilla) mais le minimum jQuery est déjà requis avec Bootstrap 4. Alors aussi bien l’utiliser !
1. La balise
Exactement comme l’exemple de Bootstrap 4.1. Noter l’ajout de l’attribut « accept »...
<div class="custom-file"> <input type="file" class="custom-file-input" id="hFichier" name="hFichier" lang="fr" accept=".jpg,.jpeg,.gif,.png" /> <label class="custom-file-label" for="hFichier">Sélectionner un fichier</label> </div>
2. En français
Un petit CSS pour modifier le contenu du bouton généré par Bootstrap en anglais peu importe la langue du navigateur. Et noter l’utilisation de l’attribut « lang » suggéré par Bootstrap.
.custom-file-input ~ .custom-file-label:lang(fr)::after { content: "Choisir..."; } .custom-file-input ~ .custom-file-label:lang(es)::after { content: "Elegir...`"; }
3. Le JavaScript
Une fois le fichier sélectionné, il faut manuellement l’indiquer. L’avantage avec ce script, et les autres disponibles sur le Web sont qu’il est générique pour toutes les saisies de fichier du document. Et il retourne seulement le titre sans le chemin d’accès (c:\\dossier_X\monfichier.ext).
<script> $("input[type=file]").change(function (e){$(this).next('.custom-file-label').text(e.target.files[0].name);}) </script>
Ou la fonction que l’on retrouve sur le Web :
$("input[type=file]").change(function () { var fieldVal = $(this).val(); if (fieldVal != undefined || fieldVal != "") { $(this).next(".custom-file-label").text(fieldVal); } });
C’est aussi simple que ça ! Pourquoi Bootstrap ne l’indique pas tout simplement dans sa documentation restera pour moi un mystère...
Code complet
<!doctype html> <html lang="fr"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous"> <title>Bootstrap 4.2 - Saisie de fichier (File browser) - Trucsweb.com</title> <style> .custom-file-input ~ .custom-file-label:lang(fr)::after { content: "Choisir..."; } .custom-file-input ~ .custom-file-label:lang(es)::after { content: "Elegir...`"; } </style> </head> <body> <h1>Bootstrap 4.2 - Saisie de fichier (File browser)</h1> <form method="post" name="oTeleversement" id="oTeleversement" action="script.php" enctype="multipart/form-data"> <div class="custom-file"> <input type="file" class="custom-file-input" id="hFichier" name="hFichier" lang="fr" accept=".jpg,.jpeg,.gif,.png" /> <label class="custom-file-label" for="hFichier">Sélectionner un fichier</label> </div> </form> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script> <script> $("input[type=file]").change(function (e){$(this).next('.custom-file-label').text(e.target.files[0].name);}) </script> </body> </html>
Autres solutions
Bootstrap c’est bien, mais c’est essentiellement visuel, il n’est question que d’interface usager (IU). Il existe sur le Web des tas d’outils tous plus performants les uns que les autres pour gérer de façon encore plus pointue le téléversement de document. Un très complet que j’affectionne particulièrement est « bootstrap-fileinput ».
Transfert sur le serveur
Pour éviter de couper moi aussi les coins ronds, il faut ajouter qu’il ne s’agit que d’une interface usager (IU). Le transfert physique du fichier, le téléversement (upload), ne fait pas partie de ce tutoriel. Pour ce faire, vous devez avoir accès au serveur qui utilise généralement une composante. C’est une autre histoire qui dépend entièrement de votre serveur et de la technologie utilisée (PHP, ASP, .NET, Pyton...). N’oubliez pas que votre formulaire doit absolument être soumis encodé en binaire pour téléverser un fichier (enctype="multipart/form-data")...
Références
- Bootstrap 4.2 - File browser
- bs-custom-file-input par johann-s
- bootstrap-fileinput v4.4.8 par Kartik Visweswaran
- bootstrap-fileinput v4.4.8 sur Github