Pulsante caricamento Twitter Bootstrap Form File Element


573

Perché non esiste un pulsante di caricamento dell'elemento file per Twitter Bootstrap? Sarebbe dolce se il pulsante principale blu fosse implementato per il pulsante di caricamento. È anche possibile rifinire il pulsante di caricamento utilizzando i CSS? (sembra un elemento del browser nativo che non può essere manipolato)


Risposte:


972

Ecco una soluzione per Bootstrap 3 e 4.

Per rendere un controllo di input file funzionale che assomiglia a un pulsante, hai solo bisogno di HTML:

HTML

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

Funziona con tutti i browser moderni, incluso IE9 +. Se hai bisogno di supporto anche per IE precedente, utilizza l'approccio legacy mostrato di seguito.

Questa tecnica si basa sull'attributo HTML5 hidden. Bootstrap 4 utilizza il seguente CSS per evitare questa funzione nei browser non supportati. Potrebbe essere necessario aggiungere se si utilizza Bootstrap 3.

[hidden] {
  display: none !important;
}

Approccio legacy per il vecchio IE

Se hai bisogno di supporto per IE8 e precedenti, usa il seguente HTML / CSS:

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;
}

Nota che il vecchio IE non attiva l'input del file quando fai clic su a <label>, quindi il CSS "bloat" fa un paio di cose per aggirare questo:

  • Imposta l'input del file su tutta la larghezza / altezza dell'ambiente circostante <span>
  • Rende invisibile l'input del file

Feedback e letture aggiuntive

Ho pubblicato maggiori dettagli su questo metodo, nonché esempi su come mostrare all'utente quali / quanti file sono selezionati:

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


52
+ 1 Per me questa è di gran lunga la risposta migliore. Soluzione molto concisa che utilizza l'ultima versione di bootstrap.
Ulises,

6
@Ulises @JaredEitnier @IvanWang Non sono d'accordo con rispetto. E offri una spina spudorata alla mia risposta che utilizza semplicemente l' <label>elemento. Come la migliore soluzione :)
Kirill Fuchs

9
Sono d'accordo con @KirillFuchs; l'etichetta sarebbe migliore. Inoltre, l'utente non può vedere se ha selezionato il file giusto perché il pulsante non mostra il nome del file selezionato: jsfiddle.net/36o9pdf9/1
danwild

1
L'etichetta sarebbe semanticamente migliore. Consulta l'articolo per un metodo per mostrare quali file sono selezionati. (Alcune app si caricano automaticamente quando viene selezionato un file, quindi in questi casi il feedback del nome file non è critico.)
claviska,

1
Non riuscivo a farlo funzionare su IE11 insieme a un oggetto FormData. In qualche modo IE sta ignorando il campo di input quando si trova all'interno di un elemento label e, di conseguenza, i dati del file non sono disponibili dall'oggetto FormData.
René,

385

Sono sorpreso che non ci fosse menzione <label>dell'elemento.

Soluzione:

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

Non c'è bisogno di alcun JS, o funky css ...

Soluzione per includere il nome file:

<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 soluzione sopra richiede jQuery.


38
Questa risposta dovrebbe essere quella accettata. È anche meglio della risposta di @ claviska
Fernando Carvalhosa,

4
Non riesco proprio a capire perché questa non è la risposta accettata. Pulito, semplice e stabile (a meno che tu non stia prendendo di mira <IE9, cioè ...)
Jake Foster

3
Non riuscivo a farlo funzionare su IE11 insieme a un oggetto FormData. In qualche modo IE sta ignorando il campo di input quando si trova all'interno di un elemento label e, di conseguenza, i dati del file non sono disponibili dall'oggetto FormData.
René,

25
beh, non mostra quale file è stato scelto (
godblessstrawberry il

3
Non è necessario utilizzarlo forse si avvolge l'elemento target con l'etichetta.
0xcaff,

132

Senza alcun plug-in aggiuntivo richiesto, questa soluzione bootstrap funziona perfettamente per me:

<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>

demo:

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

inserisci qui la descrizione dell'immagine

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

inserisci qui la descrizione dell'immagine


6
Ho riscontrato alcuni problemi con l'area inferiore del pulsante non selezionabile. Questa risposta mi ha aiutato in bootstrap 3: stackoverflow.com/a/18164555/44336
Paul Lemke,

3
Questa è un'ottima soluzione in quanto mostra il nome del file allegato!
cb88,

2
Qualcuno potrebbe spiegare la necessità di href = 'javascript :;' ? Non ho bisogno di onchange = '$ ("# upload-file-info"). Html ($ (this) .val ());' per aggiornare l'elemento upload-file-info, ma la finestra di caricamento del file non si attiverà senza l'href.
user12121234

2
Da dove viene "C: \ fakepath" e come posso liberarmene?
Ya.

1
@Ya. C: \ fakepath è la funzione di sicurezza html5 ed è preceduto dal percorso del file se lo manipoliamo con javascript. Vedi questo post sul blog davidwalsh.name/fakepath per i dettagli.
codefreak

88

È incluso nel fork di Bootstrap di Jasny.

È possibile creare un semplice pulsante di caricamento utilizzando

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

Con il plug-in fileupload è possibile creare widget più avanzati. Dai un'occhiata a http://jasny.github.io/bootstrap/javascript/#fileinput


Funziona bene in IE9? Lo sto chiedendo perché presumo che la soluzione utilizzi Javascript e, allo stesso tempo, "IE non consente la manipolazione dell'elemento di input type =" file "da javascript per motivi di sicurezza."
Marek Příhoda,

Sì, funziona anche in IE9. Imposta l'opacità dell'elemento di input su 0, che fortunatamente funziona in tutti i browser :). È spiegato nell'articolo quirksmode.
Arnold Daniels,

1
non funziona con jQuery 1.9.0, perché hanno perso $ .browser support
Giedrius

14
Sembra terribile con il normale bootstrap - img688.imageshack.us/img688/948/pictureui.png
cwd

66

I pulsanti di caricamento sono un problema per lo stile perché modellano l'ingresso e non il pulsante.

ma puoi usare questo trucco:

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

Sommario:

  1. Prendi un normale <input type="file">e mettilo in un elemento con position: relative.

  2. Allo stesso elemento principale, aggiungi un'immagine normale <input>e un'immagine, che hanno gli stili corretti. Posiziona questi elementi in modo assoluto, in modo che occupino lo stesso posto di <input type="file">.

  3. Impostare l'indice z di <input type="file">2 su in modo che si trovi in ​​cima all'input / all'immagine in stile.

  4. Infine, imposta l'opacità di <input type="file">a 0. L' <input type="file">ora diventa effettivamente invisibile e gli stili di input / immagine brillano, ma puoi comunque fare clic sul pulsante "Sfoglia". Se il pulsante è posizionato sulla parte superiore dell'immagine, l'utente sembra fare clic sull'immagine e ottenere la normale finestra di selezione dei file. (Nota che non puoi usare la visibilità: nascosto, perché anche un elemento veramente invisibile non è cliccabile e dobbiamo rimanere cliccabili)


6
Questo è troppo lavoro per questi giorni. Usare qualcosa di pronto come la soluzione di Jasny nella prossima risposta ha molto più senso.
mgPePe

2
Se il tuo esempio include il supporto per il supporto di netscape, probabilmente non è aggiornato.
Tifomismo,

22

Per me va bene:

Aggiornare

Stile 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 );

17

Risposta semplificata utilizzando parti di altre risposte, principalmente user2309766 e dotcomsuperstar.

Caratteristiche:

  • Utilizza il componente aggiuntivo Bootstrap per pulsante e campo.
  • Un solo input; più input verrebbero raccolti da un modulo.
  • Nessun extra CSS tranne "display: none;" per nascondere l'input del file.
  • Il pulsante visibile attiva l'evento click per l'immissione di file nascosti.
  • split per rimuovere il percorso del file usa regex e delimitatori '\' e '/'.

Codice:

<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>


12

Con un po 'di ispirazione dagli altri post sopra, ecco una soluzione completa che combina quello che sembra un campo di controllo del modulo con un addon di input-group per un widget di input di file pulito che include un collegamento al file corrente.

.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>


9

Questo funziona perfettamente per me

<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>


6

Una soluzione semplice con risultati accettabili:

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

E lo stile:

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

5

Soluzione per upload multiplo

Ho modificato due risposte precedenti per includere più caricamenti. In questo modo l'etichetta mostra il nome del file, se ne è selezionato solo uno o x filesnel caso contrario.

<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>

inserisci qui la descrizione dell'immagine

Può anche applicarsi per modificare il testo e la classe del pulsante.

<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>

inserisci qui la descrizione dell'immagine


4

Ho creato un pulsante di caricamento personalizzato per accettare solo immagini, che possono essere modificate in base alle tue esigenze.

Spero che sia di aiuto!! :)

(Framework Bootstrap usato)

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!');
    }
  }
});

4

questo è il miglior stile di caricamento dei file che mi piace:

<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>

puoi ottenere demo e altri stili su:

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

ma usando questo, dovresti sostituire twitter bootstrap con file jasny bootstrap ..

Saluti.


4

Basato sulla soluzione assolutamente geniale di @claviska, alla quale è dovuto tutto il merito.

Input di file Bootstrap 4 con funzionalità complete con convalida e testo di aiuto.

Sulla base dell'esempio del gruppo di input abbiamo un campo di testo di input fittizio utilizzato per visualizzare il nome file per l'utente, che viene popolato onchangedall'evento sul campo del file di input effettivo nascosto dietro il pulsante etichetta. Oltre a includere il supporto per la validazione di bootstrap 4 , abbiamo anche reso possibile fare clic in qualsiasi punto dell'input per aprire la finestra di dialogo del file.

Tre stati dell'input del file

I tre stati possibili sono non convalidati, validi e non validi con il requiredset di attributi tag di input html fittizio .

inserisci qui la descrizione dell'immagine

Markup HTML per l'input

Introduciamo solo 2 classi personalizzate input-file-dummye input-file-btnper modellare e collegare correttamente il comportamento desiderato. Tutto il resto è markup 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>

Disposizioni comportamentali JavaScript

L'input fittizio deve essere letto solo, come nell'esempio originale, per impedire all'utente di modificare l'input che può essere modificato solo tramite la finestra di dialogo Apri file. Sfortunatamente la validazione non si verifica sui readonlycampi, quindi attiviamo / disattiviamo la modificabilità dell'input su focus e blur ( eventi jquery onfocusin e onfocusout) e assicuriamo che ritorni validabile una volta selezionato un file.

Oltre a rendere anche selezionabile il campo di testo, attivando l'evento click del pulsante, @claviska ha immaginato il resto della funzionalità di popolamento del campo fittizio.

$(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();
      });
  });
});

Modifiche in stile personalizzato

Soprattutto non vogliamo che il readonlycampo salti tra sfondo grigio e bianco, quindi assicuriamo che rimanga bianco. Il pulsante span non ha un cursore del puntatore ma dobbiamo comunque aggiungerne uno per l'input.

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

nJoy!



2

/ * * Bootstrap 3 filestyle * http://dev.tudosobreweb.com.br/bootstrap-filestyle/ * * Copyright (c) 2013 Markus Vinicius da Silva Lima * Aggiornamento bootstrap 3 di Paulo Henrique Foxer * Versione 2.0.0 * Licenza sotto la licenza del 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);

2

Ho modificato la risposta di @claviska e funziona come preferisco (Bootstrap 3, 4 non testato):

<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>

2

inserisci qui la descrizione dell'immagine

Il seguente codice rende come sopra l'immagine

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>

1

Ho lo stesso problema e lo provo così.

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

Il CSS

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

Il JS

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

Nota: il pulsante .btn-file deve avere lo stesso tag del file di input

Spero che tu abbia trovato la soluzione migliore ...


1

Prova a seguire in 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>

1

Ecco un trucco alternativo, non è la soluzione migliore ma ti dà solo una scelta

Codice 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');
});

1

Rispetto alla risposta di claviska - se vuoi mostrare il nome del file caricato in un caricamento di file di base, puoi farlo onchangenell'evento input . Usa questo codice:

 <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>

Questo codice JS jquery è responsabile del recupero del nome file caricato:

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

O con vaniglia JS:

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

esempio


1

Ho pensato di aggiungere il mio valore di tre penny, solo per dire come possono essere usati l'input predefinito .custom-file-labele il custom-file-inputfile BS4.

Quest'ultima classe si trova nel gruppo di input e non è visibile. Mentre il primo è l'etichetta visibile e ha uno pseudoelemento: after che sembra un pulsante.

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

Non puoi aggiungere classi ai psuedoelements, ma puoi modellarle in CSS (o SASS).

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

0

Non è richiesto nessun shiz di fantasia:

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);
      });
});

ATTENZIONE: I tre elementi del modulo in questione DEVONO essere fratelli l'uno dell'altro (file .image-scelto, pulsante .image-file, .image-file)


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.