Bouton de téléchargement d'élément de fichier Twitter Bootstrap Form

573

Pourquoi n'y a-t-il pas un bouton de téléchargement d'élément de fichier sophistiqué pour Twitter Bootstrap? Ce serait bien si le bouton principal bleu était implémenté pour le bouton de téléchargement. Est-il même possible d'affiner le bouton de téléchargement en utilisant CSS? (semble être un élément de navigateur natif qui ne peut pas être manipulé)

jkushner
la source
13
Vous pouvez le trouver ici. markusslima.github.io/bootstrap-filestyle
rh0dium

Réponses:

972

Voici une solution pour Bootstrap 3 et 4.

Pour créer un contrôle d'entrée de fichier fonctionnel qui ressemble à un bouton, vous n'avez besoin que de HTML:

HTML

<label class="btn btn-default">
    Browse <input type="file" hidden>
</label>

Cela fonctionne dans tous les navigateurs modernes, y compris IE9 +. Si vous avez également besoin d'assistance pour l'ancien IE, veuillez utiliser l'approche héritée illustrée ci-dessous.

Cette technique repose sur l' hiddenattribut HTML5 . Bootstrap 4 utilise le CSS suivant pour caler cette fonctionnalité dans les navigateurs non compatibles. Vous devrez peut-être ajouter si vous utilisez Bootstrap 3.

[hidden] {
  display: none !important;
}

Approche héritée pour les anciens IE

Si vous avez besoin de prise en charge pour IE8 et versions antérieures, utilisez le code HTML / CSS suivant:

HTML

<span class="btn btn-default btn-file">
    Browse <input type="file">
</span>

CSS

.btn-file {
    position: relative;
    overflow: hidden;
}
.btn-file input[type=file] {
    position: absolute;
    top: 0;
    right: 0;
    min-width: 100%;
    min-height: 100%;
    font-size: 100px;
    text-align: right;
    filter: alpha(opacity=0);
    opacity: 0;
    outline: none;
    background: white;
    cursor: inherit;
    display: block;
}

Notez que l'ancien IE ne déclenche pas l'entrée de fichier lorsque vous cliquez sur un <label>, donc le CSS "ballonnement" fait quelques choses pour contourner cela:

  • Rend l’entrée de fichier sur toute la largeur / hauteur de l’environnement <span>
  • Rend l'entrée de fichier invisible

Commentaires et lectures supplémentaires

J'ai publié plus de détails sur cette méthode, ainsi que des exemples pour montrer à l'utilisateur quel / combien de fichiers sont sélectionnés:

http://www.abeautifulsite.net/whipping-file-inputs-into-shape-with-bootstrap-3/

claviska
la source
52
+ 1 Pour moi, c'est de loin la meilleure réponse. Solution très concise utilisant la dernière version de bootstrap.
Ulises
6
@Ulises @JaredEitnier @IvanWang Je ne suis respectueusement pas d'accord. Et offrez un plug sans vergogne à ma réponse qui utilise simplement l' <label>élément. Comme la meilleure solution :)
Kirill Fuchs
9
Je dois être d'accord avec @KirillFuchs; l'étiquette serait mieux. De plus - l'utilisateur ne peut pas voir s'il a sélectionné le bon fichier car le bouton n'affiche pas le nom du fichier sélectionné: jsfiddle.net/36o9pdf9/1
danwild
1
L'étiquette serait sémantiquement meilleure. Consultez l'article pour une méthode montrant quels fichiers sont sélectionnés. (Certaines applications se téléchargent automatiquement lorsqu'un fichier est sélectionné, donc dans ces cas, la rétroaction du nom de fichier n'est pas critique.)
claviska
1
Je n'ai pas pu faire fonctionner cela sur IE11 avec un objet FormData. D'une manière ou d'une autre, IE ignore le champ de saisie lorsqu'il se trouve à l'intérieur d'un élément d'étiquette et, par conséquent, les données de fichier ne sont pas disponibles à partir de l'objet FormData.
René
385

Je suis surpris qu'il n'y ait aucune mention de l' <label>élément.

Solution:

<label class="btn btn-primary" for="my-file-selector">
    <input id="my-file-selector" type="file" class="d-none">
    Button Text Here
</label>

Pas besoin de JS ou de CSS funky ...

Solution pour inclure le nom de fichier:

<label class="btn btn-primary" for="my-file-selector">
    <input id="my-file-selector" type="file" style="display:none" 
    onchange="$('#upload-file-info').html(this.files[0].name)">
    Button Text Here
</label>
<span class='label label-info' id="upload-file-info"></span>

La solution ci-dessus nécessite jQuery.

Kirill Fuchs
la source
38
Cette réponse doit être acceptée. C'est encore mieux que la réponse de @claviska
Fernando Carvalhosa
4
Je ne comprends pas très bien pourquoi ce n'est pas la réponse acceptée. Propre, simple et stable (sauf si vous ciblez <IE9, c'est-à-dire ...)
Jake Foster
3
Je n'ai pas pu faire fonctionner cela sur IE11 avec un objet FormData. D'une manière ou d'une autre, IE ignore le champ de saisie lorsqu'il se trouve à l'intérieur d'un élément d'étiquette et, par conséquent, les données de fichier ne sont pas disponibles à partir de l'objet FormData.
René
25
eh bien, il n'affiche pas quel fichier est choisi (
godblessstrawberry
3
Vous n'avez pas besoin d'utiliser forsi vous enveloppez l'élément cible avec l'étiquette.
0xcaff
132

Sans plugin supplémentaire requis, cette solution de bootstrap fonctionne très bien pour moi:

<div style="position:relative;">
        <a class='btn btn-primary' href='javascript:;'>
            Choose File...
            <input type="file" style='position:absolute;z-index:2;top:0;left:0;filter: alpha(opacity=0);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";opacity:0;background-color:transparent;color:transparent;' name="file_source" size="40"  onchange='$("#upload-file-info").html($(this).val());'>
        </a>
        &nbsp;
        <span class='label label-info' id="upload-file-info"></span>
</div>

démo:

http://jsfiddle.net/haisumbhatti/cAXFA/1/ (bootstrap 2)

entrez la description de l'image ici

http://jsfiddle.net/haisumbhatti/y3xyU/ (bootstrap 3)

entrez la description de l'image ici

codefreak
la source
6
J'ai eu quelques problèmes avec la zone inférieure du bouton non cliquable. Cette réponse m'a aidé dans le bootstrap 3: stackoverflow.com/a/18164555/44336
Paul Lemke
3
C'est une excellente solution car elle affiche le nom de fichier du fichier joint!
cb88
2
Quelqu'un pourrait-il expliquer la nécessité du href = 'javascript :;' ? Je n'ai pas besoin de onchange = '$ ("# upload-file-info"). Html ($ (this) .val ());' pour mettre à jour l'élément upload-file-info, mais la boîte de dialogue de téléchargement de fichier ne se déclenchera pas sans le href.
user12121234
2
D'où vient «C: \ fakepath» et comment puis-je m'en débarrasser?
Ouais.
1
@Ya. C: \ fakepath est une fonction de sécurité html5 et est préfixé au chemin du fichier si nous le manipulons avec javascript. Voir cet article de blog davidwalsh.name/fakepath pour plus de détails.
codefreak
88

Il est inclus dans la fourchette de bootstrap de Jasny.

Un simple bouton de téléchargement peut être créé en utilisant

<span class="btn btn-file">Upload<input type="file" /></span>

Avec le plugin fileupload, vous pouvez créer des widgets plus avancés. Jetez un œil à http://jasny.github.io/bootstrap/javascript/#fileinput

Arnold Daniels
la source
Est-ce que cela fonctionne bien dans IE9? Je pose la question parce que je suppose que la solution utilise Javascript et, en même temps, "l'IE ne permet pas la manipulation de l'élément d'entrée type =" file "à partir de javascript pour des raisons de sécurité."
Marek Příhoda
Oui, cela fonctionne également dans IE9. Il définit l'opacité de l'élément d'entrée sur 0, ce qui, heureusement, fonctionne dans tous les navigateurs :). C'est expliqué dans l'article quirksmode.
Arnold Daniels
1
cela ne fonctionne pas avec jQuery 1.9.0, car ils ont abandonné le support de $ .browser
Giedrius
14
Semble terrible avec un bootstrap régulier - img688.imageshack.us/img688/948/pictureui.png
cwd
66

Les boutons de téléchargement sont difficiles à styliser car ils stylisent l'entrée et non le bouton.

mais vous pouvez utiliser cette astuce:

http://www.quirksmode.org/dom/inputfile.html

Sommaire:

  1. Prenez une normale <input type="file">et mettez-la dans un élément avec position: relative.

  2. À ce même élément parent, ajoutez une normale <input>et une image, qui ont les styles corrects. Positionnez ces éléments de façon absolue, afin qu'ils occupent la même place que le <input type="file">.

  3. Définissez le z-index de <input type="file">2 sur afin qu'il se trouve au-dessus de l'entrée / image stylisée.

  4. Enfin, définissez l'opacité de la <input type="file">sur 0. Le <input type="file">devient désormais effectivement invisible, et les styles d'entrée / image transparaissent, mais vous pouvez toujours cliquer sur le bouton "Parcourir". Si le bouton est positionné au-dessus de l'image, l'utilisateur semble cliquer sur l'image et obtient la fenêtre de sélection de fichier normale. (Notez que vous ne pouvez pas utiliser la visibilité: caché, car un élément vraiment invisible est également impossible à cliquer, et nous avons besoin de la pour rester cliquable)

baptme
la source
6
C'est beaucoup trop de travail pour ces jours. Utiliser quelque chose de prêt comme la solution de Jasny dans la réponse suivante est beaucoup plus logique.
mgPePe
2
Si votre exemple inclut la prise en charge de la prise en charge de netscape, il n'est probablement pas à jour.
Typhomism
22

Travaille pour moi:

Mise à jour

Style de plugin jQuery :

// Based in: http://duckranger.com/2012/06/pretty-file-input-field-in-bootstrap/
// Version: 0.0.3
// Compatibility with: Bootstrap 3.2.0 and jQuery 2.1.1
// Use:
//     <input class="nice_file_field" type="file" data-label="Choose Document">
//     <script> $(".nice_file_field").niceFileField(); </script>
//
(function( $ ) {
  $.fn.niceFileField = function() {
    this.each(function(index, file_field) {
      file_field = $(file_field);
      var label = file_field.attr("data-label") || "Choose File";

      file_field.css({"display": "none"});

      nice_file_block_text  = '<div class="input-group nice_file_block">';
      nice_file_block_text += '  <input type="text" class="form-control">';
      nice_file_block_text += '  <span class="input-group-btn">';
      nice_file_block_text += '   <button class="btn btn-default nice_file_field_button" type="button">' + label + '</button>';
      nice_file_block_text += '  </span>';
      nice_file_block_text += '</div>';

      file_field.after(nice_file_block_text);

      var nice_file_field_button = file_field.parent().find(".nice_file_field_button");
      var nice_file_block_element = file_field.parent().find(".nice_file_block");

      nice_file_field_button.on("click", function(){ console.log("click"); file_field.click() } );
      file_field.change( function(){
        nice_file_block_element.find("input").val(file_field.val());
      });
    });
  };
})( jQuery );
fguillen
la source
17

Réponse simplifiée utilisant des parties d'autres réponses, principalement user2309766 et dotcomsuperstar.

Fonctionnalités:

  • Utilise l'addon Bootstrap pour le bouton et le champ.
  • Une seule entrée; plusieurs entrées seraient récupérées par un formulaire.
  • Aucun css supplémentaire sauf "display: none;" pour masquer l'entrée du fichier.
  • Le bouton visible déclenche un événement de clic pour une entrée de fichier cachée.
  • split pour supprimer le chemin du fichier, utilisez l'expression régulière et les délimiteurs «\» et «/».

Code:

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="input-group">
  <span class="input-group-btn">
    <span class="btn btn-primary" onclick="$(this).parent().find('input[type=file]').click();">Browse</span>
    <input name="uploaded_file" onchange="$(this).parent().parent().find('.form-control').html($(this).val().split(/[\\|/]/).pop());" style="display: none;" type="file">
  </span>
  <span class="form-control"></span>
</div>

mindriot
la source
12

Avec une inspiration des autres articles ci-dessus, voici une solution complète qui combine ce qui ressemble à un champ de contrôle de formulaire avec un addon de groupe d'entrée pour un widget d'entrée de fichier propre qui comprend un lien vers le fichier actuel.

.input-file { position: relative; margin: 60px 60px 0 } /* Remove margin, it is just for stackoverflow viewing */
.input-file .input-group-addon { border: 0px; padding: 0px; }
.input-file .input-group-addon .btn { border-radius: 0 4px 4px 0 }
.input-file .input-group-addon input { cursor: pointer; position:absolute; width: 72px; z-index:2;top:0;right:0;filter: alpha(opacity=0);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";opacity:0; background-color:transparent; color:transparent; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<div class="input-group input-file">
  <div class="form-control">
    <a href="/path/to/your/current_file_name.pdf" target="_blank">current_file_name.pdf</a>
  </div>
  <span class="input-group-addon">
    <a class='btn btn-primary' href='javascript:;'>
      Browse
      <input type="file" name="field_name" onchange="$(this).parent().parent().parent().find('.form-control').html($(this).val());">
    </a>
  </span>
</div>

dotcomly
la source
9

Cela fonctionne parfaitement pour moi

<span>
    <input  type="file" 
            style="visibility:hidden; width: 1px;" 
            id='${multipartFilePath}' name='${multipartFilePath}'  
            onchange="$(this).parent().find('span').html($(this).val().replace('C:\\fakepath\\', ''))"  /> <!-- Chrome security returns 'C:\fakepath\'  -->
    <input class="btn btn-primary" type="button" value="Upload File.." onclick="$(this).parent().find('input[type=file]').click();"/> <!-- on button click fire the file click event -->
    &nbsp;
    <span  class="badge badge-important" ></span>
</span>
MoBKK
la source
9

Veuillez vérifier la saisie du fichier d'amorçage Twitter . Il utilise une solution très simple, ajoutez simplement un fichier javascript et collez le code suivant:

$('input[type=file]').bootstrapFileInput();
monsur.hoq
la source
Lien rompu (juillet 2019)
Yetti99
@ Yetti99 oui, il est cassé maintenant
monsur.hoq
@ Yetti99, j'ai changé de lien. S'il vous plait verifiez maintenant.
monsur.hoq
6

Une solution simple avec un résultat acceptable:

<input type="file" class="form-control">

Et le style:

input[type=file].form-control {
    height: auto;
}
Salar
la source
5

Solution pour plusieurs téléchargements

J'ai modifié deux réponses précédentes pour inclure plusieurs téléchargements. De cette façon, l'étiquette affiche le nom du fichier, si un seul est sélectionné, ou x filesdans le cas contraire.

<label class="btn btn-primary" for="my-file-selector">
    <input id="my-file-selector" type="file" multiple="multiple" style="display:none"
        onchange="$('#upload-file-info').html(
            (this.files.length > 1) ? this.files.length + ' files' : this.files[0].name)">                     
    Files&hellip;
</label>
<span class='label label-info' id="upload-file-info"></span>

entrez la description de l'image ici

Il peut également s'appliquer pour modifier le texte et la classe du bouton.

<label class="btn btn-primary" for="multfile">
    <input id="multfile" type="file" multiple="multiple" style="display:none"
        onchange="$('#multfile-label').html(
            (this.files.length == 1) ? this.files[0].name : this.files.length + ' files');
            $(this).parent().addClass('btn-success')">
    <span id="multfile-label">Files&hellip;</span>
</label>

entrez la description de l'image ici

Nuno André
la source
4

J'ai créé un bouton de téléchargement personnalisé pour accepter uniquement les images, qui peuvent être modifiées selon vos besoins.

J'espère que cela t'aides!! :)

(Framework Bootstrap utilisé)

Codepen-link

HTML

<center>
 <br />
 <br />
 <span class="head">Upload Button Re-Imagined</span>
 <br />
 <br />
 <div class="fileUpload blue-btn btn width100">
   <span>Upload your Organizations logo</span>
   <input type="file" class="uploadlogo" />
 </div>
</center>

CSS

 .head {
   font-size: 25px;
   font-weight: 200;
 }

 .blue-btn:hover,
 .blue-btn:active,
 .blue-btn:focus,
 .blue-btn {
   background: transparent;
   border: solid 1px #27a9e0;
   border-radius: 3px;
   color: #27a9e0;
   font-size: 16px;
   margin-bottom: 20px;
   outline: none !important;
   padding: 10px 20px;
 }

 .fileUpload {
   position: relative;
   overflow: hidden;
   height: 43px;
   margin-top: 0;
 }

 .fileUpload input.uploadlogo {
   position: absolute;
   top: 0;
   right: 0;
   margin: 0;
   padding: 0;
   font-size: 20px;
   cursor: pointer;
   opacity: 0;
   filter: alpha(opacity=0);
   width: 100%;
   height: 42px;
 }


 /*Chrome fix*/

 input::-webkit-file-upload-button {
   cursor: pointer !important;
 }

JS

// You can modify the upload files to pdf's, docs etc
//Currently it will upload only images
$(document).ready(function($) {

  // Upload btn
  $(".uploadlogo").change(function() {
    readURL(this);
  });

  function readURL(input) {
    var url = input.value;
    var ext = url.substring(url.lastIndexOf('.') + 1).toLowerCase();
    if (input.files && input.files[0] && (ext == "png" || ext == "jpeg" || ext == "jpg" || ext == "gif" || ext == "svg")) {
      var path = $('.uploadlogo').val();
      var filename = path.replace(/^.*\\/, "");
      $('.fileUpload span').html('Uploaded logo : ' + filename);
      // console.log(filename);
    } else {
      $(".uploadlogo").val("");
      $('.fileUpload span').html('Only Images Are Allowed!');
    }
  }
});
Ashwin
la source
4

c'est le meilleur style de téléchargement de fichiers que j'aime:

<div class="fileupload fileupload-new" data-provides="fileupload">
  <div class="input-append">
    <div class="uneditable-input span3"><i class="icon-file fileupload-exists"></i> <span class="fileupload-preview"></span></div><span class="btn btn-file"><span class="fileupload-new">Select file</span><span class="fileupload-exists">Change</span><input type="file" /></span><a href="#" class="btn fileupload-exists" data-dismiss="fileupload">Remove</a>
  </div>
</div>

vous pouvez obtenir une démo et plus de styles sur:

http://www.jasny.net/bootstrap/javascript/#fileinput

mais en utilisant cela, vous devez remplacer twitter bootstrap par des fichiers jasny bootstrap ..

Cordialement.

navins
la source
4

Basé sur la solution @claviska absolument géniale, à qui tout le crédit est dû.

Entrée de fichier Bootstrap 4 complète avec validation et texte d'aide.

Sur la base de l' exemple de groupe d'entrée, nous avons un champ de texte de saisie factice utilisé pour afficher le nom de fichier à l'utilisateur, qui est rempli à partir de l' onchangeévénement sur le champ de fichier d'entrée réel caché derrière le bouton d'étiquette. En plus d'inclure le support de validation bootstrap 4, nous avons également permis de cliquer n'importe où sur l'entrée pour ouvrir la boîte de dialogue de fichier.

Trois états de l'entrée du fichier

Les trois états possibles sont non validés, valides et invalides avec le requiredjeu d' attributs de balise d'entrée html factice .

entrez la description de l'image ici

Balisage HTML pour l'entrée

Nous introduisons seulement 2 classes personnalisées input-file-dummyet input-file-btnpour styliser et câbler correctement le comportement souhaité. Tout le reste est un balisage Bootstrap 4 standard.

<div class="input-group">
  <input type="text" class="form-control input-file-dummy" placeholder="Choose file" aria-describedby="fileHelp" required>
  <div class="valid-feedback order-last">File is valid</div>
  <div class="invalid-feedback order-last">File is required</div>
  <label class="input-group-append mb-0">
    <span class="btn btn-primary input-file-btn">
      Browse… <input type="file" hidden>
    </span>
  </label>
</div>
<small id="fileHelp" class="form-text text-muted">Choose any file you like</small>

Dispositions comportementales JavaScript

L'entrée factice doit être en lecture seule, comme dans l'exemple d'origine, pour empêcher l'utilisateur de modifier l'entrée qui ne peut être modifiée que via la boîte de dialogue d'ouverture de fichier. Malheureusement, la validation ne se produit pas sur les readonlychamps, nous basculons donc l'éditabilité de l'entrée sur le focus et le flou ( événements jquery onfocusin et onfocusout) et nous assurons qu'elle redevient validable une fois qu'un fichier est sélectionné.

En plus de rendre le champ de texte cliquable, en déclenchant l'événement click du bouton, le reste des fonctionnalités de remplissage du champ fictif a été envisagé par @claviska.

$(function () {
  $('.input-file-dummy').each(function () {
    $($(this).parent().find('.input-file-btn input')).on('change', {dummy: this}, function(ev) {
      $(ev.data.dummy)
        .val($(this).val().replace(/\\/g, '/').replace(/.*\//, ''))
        .trigger('focusout');
    });
    $(this).on('focusin', function () {
        $(this).attr('readonly', '');
      }).on('focusout', function () {
        $(this).removeAttr('readonly');
      }).on('click', function () {
        $(this).parent().find('.input-file-btn').click();
      });
  });
});

Modifications de style personnalisé

Plus important encore, nous ne voulons pas que le readonlychamp passe entre le fond gris et le blanc, nous nous assurons donc qu'il reste blanc. Le bouton span n'a pas de curseur pointeur mais nous devons quand même en ajouter un pour l'entrée.

.input-file-dummy, .input-file-btn {
  cursor: pointer;
}
.input-file-dummy[readonly] {
  background-color: white;
}

nJoy!

nickl-
la source
2

/ * * Bootstrap 3 filestyle * http://dev.tudosobreweb.com.br/bootstrap-filestyle/ * * Copyright (c) 2013 Markus Vinicius da Silva Lima * Update bootstrap 3 by Paulo Henrique Foxer * Version 2.0.0 * Licensed sous licence MIT. * * /

(function ($) {
"use strict";

var Filestyle = function (element, options) {
    this.options = options;
    this.$elementFilestyle = [];
    this.$element = $(element);
};

Filestyle.prototype = {
    clear: function () {
        this.$element.val('');
        this.$elementFilestyle.find(':text').val('');
    },

    destroy: function () {
        this.$element
            .removeAttr('style')
            .removeData('filestyle')
            .val('');
        this.$elementFilestyle.remove();
    },

    icon: function (value) {
        if (value === true) {
            if (!this.options.icon) {
                this.options.icon = true;
                this.$elementFilestyle.find('label').prepend(this.htmlIcon());
            }
        } else if (value === false) {
            if (this.options.icon) {
                this.options.icon = false;
                this.$elementFilestyle.find('i').remove();
            }
        } else {
            return this.options.icon;
        }
    },

    input: function (value) {
        if (value === true) {
            if (!this.options.input) {
                this.options.input = true;
                this.$elementFilestyle.prepend(this.htmlInput());

                var content = '',
                    files = [];
                if (this.$element[0].files === undefined) {
                    files[0] = {'name': this.$element[0].value};
                } else {
                    files = this.$element[0].files;
                }

                for (var i = 0; i < files.length; i++) {
                    content += files[i].name.split("\\").pop() + ', ';
                }
                if (content !== '') {
                    this.$elementFilestyle.find(':text').val(content.replace(/\, $/g, ''));
                }
            }
        } else if (value === false) {
            if (this.options.input) {
                this.options.input = false;
                this.$elementFilestyle.find(':text').remove();
            }
        } else {
            return this.options.input;
        }
    },

    buttonText: function (value) {
        if (value !== undefined) {
            this.options.buttonText = value;
            this.$elementFilestyle.find('label span').html(this.options.buttonText);
        } else {
            return this.options.buttonText;
        }
    },

    classButton: function (value) {
        if (value !== undefined) {
            this.options.classButton = value;
            this.$elementFilestyle.find('label').attr({'class': this.options.classButton});
            if (this.options.classButton.search(/btn-inverse|btn-primary|btn-danger|btn-warning|btn-success/i) !== -1) {
                this.$elementFilestyle.find('label i').addClass('icon-white');
            } else {
                this.$elementFilestyle.find('label i').removeClass('icon-white');
            }
        } else {
            return this.options.classButton;
        }
    },

    classIcon: function (value) {
        if (value !== undefined) {
            this.options.classIcon = value;
            if (this.options.classButton.search(/btn-inverse|btn-primary|btn-danger|btn-warning|btn-success/i) !== -1) {
                this.$elementFilestyle.find('label').find('i').attr({'class': 'icon-white '+this.options.classIcon});
            } else {
                this.$elementFilestyle.find('label').find('i').attr({'class': this.options.classIcon});
            }
        } else {
            return this.options.classIcon;
        }
    },

    classInput: function (value) {
        if (value !== undefined) {
            this.options.classInput = value;
            this.$elementFilestyle.find(':text').addClass(this.options.classInput);
        } else {
            return this.options.classInput;
        }
    },

    htmlIcon: function () {
        if (this.options.icon) {
            var colorIcon = '';
            if (this.options.classButton.search(/btn-inverse|btn-primary|btn-danger|btn-warning|btn-success/i) !== -1) {
                colorIcon = ' icon-white ';
            }

            return '<i class="'+colorIcon+this.options.classIcon+'"></i> ';
        } else {
            return '';
        }
    },

    htmlInput: function () {
        if (this.options.input) {
            return '<input type="text" class="'+this.options.classInput+'" style="width: '+this.options.inputWidthPorcent+'% !important;display: inline !important;" disabled> ';
        } else {
            return '';
        }
    },

    constructor: function () {
        var _self = this,
            html = '',
            id = this.$element.attr('id'),
            files = [];

        if (id === '' || !id) {
            id = 'filestyle-'+$('.bootstrap-filestyle').length;
            this.$element.attr({'id': id});
        }

        html = this.htmlInput()+
             '<label for="'+id+'" class="'+this.options.classButton+'">'+
                this.htmlIcon()+
                '<span>'+this.options.buttonText+'</span>'+
             '</label>';

        this.$elementFilestyle = $('<div class="bootstrap-filestyle" style="display: inline;">'+html+'</div>');

        var $label = this.$elementFilestyle.find('label');
        var $labelFocusableContainer = $label.parent();

        $labelFocusableContainer
            .attr('tabindex', "0")
            .keypress(function(e) {
                if (e.keyCode === 13 || e.charCode === 32) {
                    $label.click();
                }
            });

        // hidding input file and add filestyle
        this.$element
            .css({'position':'absolute','left':'-9999px'})
            .attr('tabindex', "-1")
            .after(this.$elementFilestyle);

        // Getting input file value
        this.$element.change(function () {
            var content = '';
            if (this.files === undefined) {
                files[0] = {'name': this.value};
            } else {
                files = this.files;
            }

            for (var i = 0; i < files.length; i++) {
                content += files[i].name.split("\\").pop() + ', ';
            }

            if (content !== '') {
                _self.$elementFilestyle.find(':text').val(content.replace(/\, $/g, ''));
            }
        });

        // Check if browser is Firefox
        if (window.navigator.userAgent.search(/firefox/i) > -1) {
            // Simulating choose file for firefox
            this.$elementFilestyle.find('label').click(function () {
                _self.$element.click();
                return false;
            });
        }
    }
};

var old = $.fn.filestyle;

$.fn.filestyle = function (option, value) {
    var get = '',
        element = this.each(function () {
            if ($(this).attr('type') === 'file') {
                var $this = $(this),
                    data = $this.data('filestyle'),
                    options = $.extend({}, $.fn.filestyle.defaults, option, typeof option === 'object' && option);

                if (!data) {
                    $this.data('filestyle', (data = new Filestyle(this, options)));
                    data.constructor();
                }

                if (typeof option === 'string') {
                    get = data[option](value);
                }
            }
        });

    if (typeof get !== undefined) {
        return get;
    } else {
        return element;
    }
};

$.fn.filestyle.defaults = {
    'buttonText': 'Escolher arquivo',
    'input': true,
    'icon': true,
    'inputWidthPorcent': 65,
    'classButton': 'btn btn-primary',
    'classInput': 'form-control file-input-button',
    'classIcon': 'icon-folder-open'
};

$.fn.filestyle.noConflict = function () {
    $.fn.filestyle = old;
    return this;
};

// Data attributes register
$('.filestyle').each(function () {
    var $this = $(this),
        options = {
            'buttonText': $this.attr('data-buttonText'),
            'input': $this.attr('data-input') === 'false' ? false : true,
            'icon': $this.attr('data-icon') === 'false' ? false : true,
            'classButton': $this.attr('data-classButton'),
            'classInput': $this.attr('data-classInput'),
            'classIcon': $this.attr('data-classIcon')
        };

    $this.filestyle(options);
});
})(window.jQuery);
Paulo Henrique Foxer
la source
2

J'ai modifié la réponse @claviska et fonctionne comme j'aime (Bootstrap 3, 4 non testé):

<label class="btn btn-default">
    <span>Browse</span>
    <input type="file" style="display: none;" onchange="$(this).prev('span').text($(this).val()!=''?$(this).val():'Browse')">
</label>
marioosh
la source
2

entrez la description de l'image ici

Le code suivant fait comme ci-dessus l'image

Html

<form>
<div class="row">
<div class="col-lg-6">
<label for="file">
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-default" type="button">Browse</button>
</span>
<input type="text" class="form-control" id="info" readonly="" style="background: #fff;" placeholder="Search for...">
</div><!-- /input-group -->
</label>
</div><!-- /.col-lg-6 -->
</div>

</div>
<input type="file" style="display: none;" onchange="$('#info').val($(this).val().split(/[\\|/]/).pop()); " name="file" id="file">
</form>

Javascript

<script type="text/javascript">

$(function() {
    $("label[for=file]").click(function(event) {
        event.preventDefault();
        $("#file").click();
    });
});

</script>
NaveenDA
la source
1

J'ai le même problème et je l'essaie comme ça.

<div>
<button type='button' class='btn btn-info btn-file'>Browse</button>
<input type='file' name='image'/>
</div>

Le CSS

<style>
.btn-file {
    position:absolute;
}
</style>

Le JS

<script>
$(document).ready(function(){
    $('.btn-file').click(function(){
        $('input[name="image"]').click();
    });
});
</script>

Remarque: Le bouton .btn-file doit être dans la même balise que le fichier d'entrée

J'espère que vous avez trouvé la meilleure solution ...

Esgi Dendyanri
la source
1

Essayez de suivre dans Bootstrap v.3.3.4

<div>
    <input id="uplFile" type="file" style="display: none;">

    <div class="input-group" style="width: 300px;">
        <div  id="btnBrowse"  class="btn btn-default input-group-addon">Select a file...</div>
        <span id="photoCover" class="form-control">
    </div>
</div>

<script type="text/javascript">
    $('#uplFile').change(function() {
        $('#photoCover').text($(this).val());
    });

    $('#btnBrowse').click(function(){
        $('#uplFile').click();
    });
</script>
Siyavash Hamdi
la source
1

Voici une astuce alternative, ce n'est pas la meilleure solution mais elle vous donne juste le choix

Code HTML:

<button clss="btn btn-primary" id="btn_upload">Choose File</button>
<input id="fileupload" class="hide" type="file" name="files[]">

Javascript:

$("#btn_upload").click(function(e){
e.preventDefault();
$("#fileupload").trigger('click');
});
Somwang Souksavatd
la source
1

En ce qui concerne la réponse de claviska - si vous voulez afficher le nom du fichier téléchargé dans un téléchargement de fichier de base, vous pouvez le faire dans l' onchangeévénement des entrées . Utilisez simplement ce code:

 <label class="btn btn-default">
                    Browse...
                    <span id="uploaded-file-name" style="font-style: italic"></span>
                    <input id="file-upload" type="file" name="file"
                           onchange="$('#uploaded-file-name').text($('#file-upload')[0].value);" hidden>
 </label>

Ce code Jquery JS est responsable de la récupération du nom de fichier téléchargé:

$('#file-upload')[0].value

Ou avec vanille JS:

document.getElementById("file-upload").value

exemple

Michał Stochmal
la source
1

J'ai pensé ajouter ma valeur de trois points, juste pour dire comment l' entrée de fichier par défaut .custom-file-labelet custom-file-inputBS4 et comment cela peut être utilisé.

Cette dernière classe fait partie du groupe d'entrée et n'est pas visible. Alors que le premier est l'étiquette visible et a un: après pseudo-élément qui ressemble à un bouton.

<div class="custom-file">
<input type="file" class="custom-file-input" id="upload">
<label class="custom-file-label" for="upload">Choose file</label>
</div>

Vous ne pouvez pas ajouter de classes aux éléments de simulation, mais vous pouvez les styliser en CSS (ou SASS).

.custom-file-label:after {
    color: #fff;
    background-color: #1e7e34;
    border-color: #1c7430;
    pointer: cursor;
}
Matteo Ferla
la source
0

Aucun shiz de fantaisie requis:

HTML:

<form method="post" action="/api/admin/image" enctype="multipart/form-data">
    <input type="hidden" name="url" value="<%= boxes[i].url %>" />
    <input class="image-file-chosen" type="text" />
    <br />
    <input class="btn image-file-button" value="Choose Image" />
    <input class="image-file hide" type="file" name="image"/> <!-- Hidden -->
    <br />
    <br />
    <input class="btn" type="submit" name="image" value="Upload" />
    <br />
</form>

JS:

$('.image-file-button').each(function() {
      $(this).off('click').on('click', function() {
           $(this).siblings('.image-file').trigger('click');
      });
});
$('.image-file').each(function() {
      $(this).change(function () {
           $(this).siblings('.image-file-chosen').val(this.files[0].name);
      });
});

ATTENTION: Les trois éléments de formulaire en question DOIVENT être frères et sœurs les uns des autres (.image-file-selected, .image-file-button, .image-file)

mattdlockyer
la source