Przycisk ładowania elementu formularza formularza startowego Twittera

573

Dlaczego nie ma fantazyjnego przycisku przesyłania elementu pliku do bootowania na Twitterze? Byłoby miło, gdyby zaimplementowano niebieski przycisk główny dla przycisku przesyłania. Czy możliwe jest nawet wyrafinowanie przycisku przesyłania za pomocą CSS? (wygląda jak natywny element przeglądarki, którym nie można manipulować)

jkushner
źródło
13
Możesz go znaleźć tutaj. markusslima.github.io/bootstrap-filestyle
rh0dium

Odpowiedzi:

972

Oto rozwiązanie dla Bootstrap 3 i 4.

Aby stworzyć funkcjonalną kontrolę wprowadzania pliku, która wygląda jak przycisk, potrzebujesz tylko HTML:

HTML

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

Działa to we wszystkich nowoczesnych przeglądarkach, w tym IE9 +. Jeśli potrzebujesz wsparcia dla starej wersji IE, skorzystaj z wcześniejszego podejścia pokazanego poniżej.

Techniki te opierają się na hiddenatrybucie HTML5 . Bootstrap 4 korzysta z następującego CSS, aby ukryć tę funkcję w nieobsługiwanych przeglądarkach. Może być konieczne dodanie, jeśli używasz Bootstrap 3.

[hidden] {
  display: none !important;
}

Starsze podejście do starej IE

Jeśli potrzebujesz wsparcia dla IE8 i niższych wersji, użyj następującego 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;
}

Zauważ, że stary IE nie wyzwala danych wejściowych pliku po kliknięciu na <label>, więc „wzdęcie” CSS robi kilka rzeczy do obejścia:

  • Sprawia, że ​​plik wejściowy obejmuje całą szerokość / wysokość otoczenia <span>
  • Sprawia, że ​​wejście pliku jest niewidoczne

Informacje zwrotne i dodatkowe czytanie

Opublikowałem więcej szczegółów na temat tej metody, a także przykłady pokazujące użytkownikowi, które / ile plików jest wybranych:

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

claviska
źródło
52
+ 1 Dla mnie jest to zdecydowanie najlepsza odpowiedź. Bardzo zwięzłe rozwiązanie z wykorzystaniem najnowszej wersji bootstrap.
Ulises
6
@Ulises @JaredEitnier @IvanWang Z szacunkiem się nie zgadzam. I zaoferuj bezwstydną wtyczkę do mojej odpowiedzi, która po prostu wykorzystuje <label>element. Jako najlepsze rozwiązanie :)
Kirill Fuchs
9
Muszę się zgodzić z @KirillFuchs; etykieta byłaby lepsza. Plus - użytkownik nie może sprawdzić, czy wybrał właściwy plik, ponieważ przycisk nie wyświetla nazwy wybranego pliku: jsfiddle.net/36o9pdf9/1
danwild
1
Etykieta byłaby semantycznie lepsza. Sprawdź artykuł w celu pokazania, które pliki są wybrane. (Niektóre aplikacje przesyłają się automatycznie po wybraniu pliku, więc w takich przypadkach informacja zwrotna pliku nie jest krytyczna.)
claviska
1
Nie mogłem tego uruchomić z IE11 razem z obiektem FormData. Jakoś IE ignoruje pole wejściowe, gdy znajduje się ono w elemencie etykiety, w wyniku czego dane pliku nie są dostępne z obiektu FormData.
René,
385

Jestem zaskoczony, że nie wspomniano o tym <label>elemencie.

Rozwiązanie:

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

Nie potrzebujesz żadnego JS ani funky css ...

Rozwiązanie dotyczące dołączenia nazwy pliku:

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

Powyższe rozwiązanie wymaga jQuery.

Kirill Fuchs
źródło
38
Ta odpowiedź powinna być zaakceptowana. To nawet lepsze niż odpowiedź @ claviski
Fernando Carvalhosa,
4
Nie do końca rozumiem, dlaczego nie jest to akceptowana odpowiedź. Czysty, prosty i stabilny (chyba że celujesz w <IE9, to znaczy ...)
Jake Foster
3
Nie mogłem tego uruchomić z IE11 razem z obiektem FormData. Jakoś IE ignoruje pole wejściowe, gdy znajduje się ono w elemencie etykiety, w wyniku czego dane pliku nie są dostępne z obiektu FormData.
René,
25
cóż, nie wyświetla, który plik jest
wybrany
3
Nie musisz go używać, forjeśli owijasz element docelowy etykietą.
0xcaff,
132

Bez dodatkowej wtyczki to rozwiązanie ładujące działa świetnie dla mnie:

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

próbny:

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

wprowadź opis zdjęcia tutaj

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

wprowadź opis zdjęcia tutaj

codefreak
źródło
6
Miałem pewne problemy z niemożnością kliknięcia dolnej części przycisku. Ta odpowiedź pomogła mi w bootstrap 3: stackoverflow.com/a/18164555/44336
Paul Lemke
3
To doskonałe rozwiązanie, ponieważ pokazuje nazwę załączonego pliku!
cb88,
2
Czy ktoś mógłby wyjaśnić potrzebę href = 'javascript :;' ? Nie potrzebuję onchange = '$ ("# upload-file-info"). Html ($ (this) .val ());' aby zaktualizować element upload-file-info, ale okno dialogowe przesyłania pliku nie uruchomi się bez href.
user12121234,
2
Skąd pochodzi „C: \ fakepath” i jak się go pozbyć?
.
1
@Ya. C: \ fakepath jest funkcją bezpieczeństwa HTML5 i ma przedrostek do ścieżki pliku, jeśli manipulujemy nią za pomocą javascript. Szczegółowe informacje można znaleźć w tym blogu davidwalsh.name/fakepath .
codefreak
88

Jest zawarty w widelcu bootstrapu Jasnego.

Prosty przycisk przesyłania można utworzyć za pomocą

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

Dzięki wtyczce fileupload możesz tworzyć bardziej zaawansowane widżety. Zajrzyj na http://jasny.github.io/bootstrap/javascript/#fileinput

Arnold Daniels
źródło
Czy to działa dobrze w IE9? Pytam, ponieważ zakładam, że rozwiązanie korzysta z JavaScript, a jednocześnie „IE nie zezwala na manipulowanie elementem wejściowym type =” file ”z javascript ze względów bezpieczeństwa.”
Marek Příhoda
Tak, działa również w IE9. Ustawia krycie elementu wejściowego na 0, co na szczęście działa we wszystkich przeglądarkach :). Jest to wyjaśnione w artykule quirksmode.
Arnold Daniels,
1
nie działa z jQuery 1.9.0, ponieważ porzucili obsługę $ .browser
Giedrius
14
Wygląda okropnie przy zwykłym bootstrapie - img688.imageshack.us/img688/948/pictureui.png
cwd
66

Przyciski przesyłania to problem w stylu, ponieważ stylizuje wejście, a nie przycisk.

ale możesz użyć tej sztuczki:

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

Podsumowanie:

  1. Weź normalny <input type="file">i umieść go w elemencie za pomocą position: relative.

  2. Do tego samego elementu nadrzędnego dodaj normalną <input>i obraz, które mają poprawne style. Ustaw te elementy bezwzględnie, aby zajmowały to samo miejsce co <input type="file">.

  3. Ustaw indeks Z <input type="file">na 2, tak aby leżał na górze stylizowanego wejścia / obrazu.

  4. Na koniec ustaw krycie <input type="file">na 0. <input type="file">Teraz staje się efektywnie niewidoczny, a style wejściowe / obraz świecą, ale nadal możesz kliknąć przycisk „Przeglądaj”. Jeśli przycisk znajduje się na górze obrazu, wydaje się, że użytkownik klika obraz i wyświetla normalne okno wyboru pliku. (Pamiętaj, że nie możesz używać widoczności: ukryty, ponieważ naprawdę niewidoczny element jest również nie do kliknięcia, a my musimy pozostać klikalnym)

chrzcielnica
źródło
6
To zdecydowanie za dużo pracy na te dni. Zastosowanie czegoś gotowego, takiego jak rozwiązanie Jasnego w następnej odpowiedzi, ma o wiele większy sens.
mgPePe
2
Jeśli twój przykład obejmuje obsługę netscape, prawdopodobnie nie jest aktualny.
Typhomism
22

Pracuje dla mnie:

Aktualizacja

Styl wtyczki 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
źródło
17

Uproszczona odpowiedź z wykorzystaniem części z innych odpowiedzi, głównie user2309766 i dotcomsuperstar.

Funkcje:

  • Używa dodatku przycisku Bootstrap dla przycisku i pola.
  • Tylko jedno wejście; wiele danych wejściowych byłoby wychwytywanych przez formularz.
  • Bez dodatkowych css oprócz „display: none;” aby ukryć dane wejściowe pliku.
  • Widoczny przycisk wyzwala zdarzenie kliknięcia w celu wprowadzenia ukrytego pliku.
  • split do usunięcia ścieżki pliku używa wyrażeń regularnych i ograniczników „\” i „/”.

Kod:

<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
źródło
12

Z pewnymi inspiracjami z innych postów powyżej, oto pełne rozwiązanie, które łączy coś, co wygląda jak pole kontrolne formularza z addon-group-addon dla czystego widżetu wejściowego pliku, który zawiera link do bieżącego pliku.

.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
źródło
9

To działa idealnie dla mnie

<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
źródło
9

Sprawdź dane wejściowe pliku Bootstrap na Twitterze . Korzysta z bardzo prostego rozwiązania, wystarczy dodać jeden plik javascript i wkleić następujący kod:

$('input[type=file]').bootstrapFileInput();
monsur.hoq
źródło
Link jest zerwany (lipiec 2019 r.)
Yetti99
@ Yetti99 tak, teraz jest zepsuty
monsur.hoq
@ Yetti99, zmieniłem link. Proszę, sprawdź teraz.
monsur.hoq
6

Proste rozwiązanie z akceptowalnym wynikiem:

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

I styl:

input[type=file].form-control {
    height: auto;
}
Salar
źródło
5

Rozwiązanie do wielokrotnego przesyłania

Poprawiłem dwie poprzednie odpowiedzi, aby uwzględnić wiele przesłanych plików. W ten sposób etykieta pokazuje nazwę pliku, jeśli tylko jeden jest wybrany lub x filesw przeciwnym przypadku.

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

wprowadź opis zdjęcia tutaj

Może to również dotyczyć zmiany tekstu przycisku i klasy.

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

wprowadź opis zdjęcia tutaj

Nuno André
źródło
4

Utworzyłem niestandardowy przycisk przesyłania, aby akceptować tylko obrazy, które można modyfikować zgodnie z wymaganiami.

Mam nadzieję że to pomoże!! :)

(Używany framework Bootstrap)

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
źródło
4

to najlepszy styl przesyłania plików, jaki lubię:

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

możesz uzyskać wersje demo i więcej stylów na:

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

ale za pomocą tego, należy wymienić twitter bootstrap z plików jasny bootstrapowych ..

pozdrowienia.

navins
źródło
4

Oparty na absolutnie genialnym rozwiązaniu @claviska, któremu należy się cały kredyt.

W pełni funkcjonalny Bootstrap 4 wejścia plików z walidacji i tekstem pomocy.

W oparciu o przykład grupy wejściowej mamy fikcyjne pole tekstowe używane do wyświetlania nazwy pliku dla użytkownika, które jest zapełniane onchangezdarzeniem w polu wejściowym pliku ukrytym za przyciskiem etykiety. Oprócz włączenia obsługi sprawdzania poprawności bootstrap 4, umożliwiliśmy także kliknięcie w dowolnym miejscu na wejściu, aby otworzyć okno dialogowe pliku.

Trzy stany pliku wejściowego

Trzy możliwe stany są niepotwierdzone, poprawne i niepoprawne z requiredustawionym atrybutem fikcyjnego tagu wejściowego HTML .

wprowadź opis zdjęcia tutaj

Znaczników HTML dla wejścia

Wprowadzamy tylko 2 niestandardowe klasy input-file-dummyi input-file-btnodpowiednio stylizujemy i łączymy pożądane zachowanie. Cała reszta jest standardowym znacznikiem Bootstrap 4.

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

Przepisy dotyczące zachowania JavaScript

Atrapa wejścia musi być tylko do odczytu, jak w oryginalnym przykładzie, aby uniemożliwić użytkownikowi zmianę danych wejściowych, które można zmienić tylko za pomocą okna dialogowego otwartego pliku. Niestety sprawdzanie poprawności nie występuje na readonlypolach, więc przełączamy edytowalność danych wejściowych na fokus i rozmycie ( zdarzenia jquery onfocusin i onfocusout) i upewniamy się, że będzie ponownie sprawdzana po wybraniu pliku.

Oprócz umożliwienia kliknięcia pola tekstowego, wyzwalając zdarzenie kliknięcia przycisku, pozostałe funkcje wypełniania pola zastępczego zostały zaplanowane przez @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();
      });
  });
});

Ulepszenia stylu niestandardowego

Co najważniejsze, nie chcemy, aby readonlypole przeskakiwało między szarym tłem a bielą, dlatego zapewniamy, że pozostanie białe. Przycisk zakresu nie ma kursora kursora, ale i tak musimy go dodać do danych wejściowych.

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

nJoy!

nikiel
źródło
2

/ * * Bootstrap 3 filestyle * http://dev.tudosobreweb.com.br/bootstrap-filestyle/ * Copyright (c) 2013 Markus Vinicius da Silva Lima * Aktualizacja bootstrap 3 przez Paulo Henrique Foxer * Wersja 2.0.0 * Licensed na licencji 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
źródło
2

Zmodyfikowałem odpowiedź @claviska i działa tak, jak lubię (Bootstrap 3, 4 nie testowany):

<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
źródło
2

wprowadź opis zdjęcia tutaj

Poniższy kod tworzy jak na obrazku

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
źródło
1

Mam ten sam problem i próbuję tego w ten sposób.

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

CSS

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

JS

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

Uwaga: Przycisk .btn-file musi mieć ten sam znacznik, co plik wejściowy

Mam nadzieję, że znalazłeś najlepsze rozwiązanie ...

Esgi Dendyanri
źródło
1

Spróbuj wykonać w 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
źródło
1

Oto alternatywna sztuczka, nie jest to najlepsze rozwiązanie, ale daje tylko wybór

Kod 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
źródło
1

W odniesieniu do odpowiedzi claviska - jeśli chcesz pokazać przesłaną nazwę pliku w podstawowym przesyłaniu pliku, możesz to zrobić w onchangeprzypadku zdarzeń wejściowych . Po prostu użyj tego kodu:

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

Kod JS Jquery jest odpowiedzialny za pobieranie przesłanej nazwy pliku:

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

Lub z waniliowym JS:

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

przykład

Michał Stochmal
źródło
1

Pomyślałem, że dodam swoją trzy pensy, żeby powiedzieć, jak domyślny .custom-file-labeli custom-file-inputplik wejściowy BS4 i jak można go użyć.

Ta ostatnia klasa znajduje się w grupie wejściowej i nie jest widoczna. Podczas gdy ten pierwszy jest widoczną etykietą i ma: po pseudoelementie, który wygląda jak przycisk.

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

Nie możesz dodawać klas do elementów psuedoelement, ale możesz nadać im styl CSS (lub SASS).

.custom-file-label:after {
    color: #fff;
    background-color: #1e7e34;
    border-color: #1c7430;
    pointer: cursor;
}
Matteo Ferla
źródło
0

Nie jest wymagane wymyślne shiz:

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

UWAGA: Te trzy elementy formularza MUSZĄ być ze sobą rodzeństwem (wybrany plik .image, przycisk pliku .image, plik .image)

mattdlockyer
źródło