Botón de carga del elemento del archivo de formulario de Bootstrap de Twitter

573

¿Por qué no hay un botón de carga de elemento de archivo elegante para Twitter Bootstrap? Sería bueno si el botón primario azul se implementara para el botón de carga. ¿Es posible incluso refinar el botón de carga usando CSS? (parece un elemento de navegador nativo que no puede ser manipulado)

jkushner
fuente
13
Lo puedes encontrar aquí. markusslima.github.io/bootstrap-filestyle
rh0dium

Respuestas:

972

Aquí hay una solución para Bootstrap 3 y 4.

Para hacer un control de entrada de archivo funcional que se parezca a un botón, solo necesita HTML:

HTML

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

Esto funciona en todos los navegadores modernos, incluido IE9 +. Si también necesita soporte para IE antiguo, utilice el enfoque heredado que se muestra a continuación.

Esta técnica se basa en el hiddenatributo HTML5 . Bootstrap 4 usa el siguiente CSS para calzar esta característica en navegadores que no son compatibles. Es posible que deba agregar si está utilizando Bootstrap 3.

[hidden] {
  display: none !important;
}

Enfoque heredado para IE antiguo

Si necesita soporte para IE8 y versiones inferiores, use el siguiente 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;
}

Tenga en cuenta que el IE antiguo no activa la entrada del archivo cuando hace clic en un <label>, por lo que el "bloat" de CSS hace un par de cosas para evitarlo:

  • Hace que la entrada del archivo abarque todo el ancho / alto del entorno <span>
  • Hace que la entrada del archivo sea invisible

Comentarios y lecturas adicionales

He publicado más detalles sobre este método, así como ejemplos de cómo mostrarle al usuario qué / cuántos archivos están seleccionados:

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

claviska
fuente
52
+ 1 Para mí, esta es, con mucho, la mejor respuesta. Solución muy concisa utilizando la última versión de bootstrap.
Ulises
66
@Ulises @JaredEitnier @IvanWang Estoy respetuosamente en desacuerdo. Y ofrecer un complemento descarado a mi respuesta que simplemente usa el <label>elemento. Como la mejor solución :)
Kirill Fuchs
99
Tengo que estar de acuerdo con @KirillFuchs; La etiqueta sería mejor. Además, el usuario no puede ver si seleccionó el archivo correcto porque el botón no muestra el nombre del archivo seleccionado: jsfiddle.net/36o9pdf9/1
danwild
1
La etiqueta sería semánticamente mejor. Consulte el artículo para ver un método para mostrar qué archivos están seleccionados. (Algunas aplicaciones de auto-carga cuando se selecciona un archivo, por lo que en esos casos la retroalimentación nombre de archivo no es crítica.)
claviska
1
No pude hacer que esto funcione en IE11 junto con un objeto FormData. De alguna manera, IE ignora el campo de entrada cuando está dentro de un elemento de etiqueta y, como resultado, los datos del archivo no están disponibles desde el objeto FormData.
René
385

Me sorprende que no se mencionara el <label>elemento.

Solución:

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

No hay necesidad de ningún JS o css funky ...

Solución para incluir el nombre del archivo:

<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 solución anterior requiere jQuery.

Kirill Fuchs
fuente
38
Esta respuesta debe ser la aceptada. Es incluso mejor que la respuesta de @ claviska
Fernando Carvalhosa
44
No puedo entender por qué esta no es la respuesta aceptada. Limpio, simple y estable (a menos que esté apuntando a <IE9, eso es ...)
Jake Foster
3
No pude hacer que esto funcione en IE11 junto con un objeto FormData. De alguna manera, IE ignora el campo de entrada cuando está dentro de un elemento de etiqueta y, como resultado, los datos del archivo no están disponibles desde el objeto FormData.
René
25
bueno, no muestra qué archivo se elige (
godblessstrawberry
3
No necesita usarlo forsi está envolviendo el elemento de destino con la etiqueta.
0xcaff
132

Sin necesidad de un complemento adicional, esta solución de arranque funciona muy bien para mí:

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

manifestación:

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

ingrese la descripción de la imagen aquí

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

ingrese la descripción de la imagen aquí

codefreak
fuente
66
Tuve algunos problemas con el área inferior del botón no se puede hacer clic. Esta respuesta me ayudó en Bootstrap 3: stackoverflow.com/a/18164555/44336
Paul Lemke
3
¡Esta es una excelente solución ya que muestra el nombre del archivo adjunto!
cb88
2
¿Podría alguien explicar la necesidad de href = 'javascript :;' ? No necesito el onchange = '$ ("# upload-file-info"). Html ($ (this) .val ());' para actualizar el elemento upload-file-info, pero el cuadro de diálogo de carga de archivos no se activará sin href.
user12121234
2
¿De dónde viene 'C: \ fakepath' y cómo me deshago de él?
Ya
1
@Ya. C: \ fakepath es la característica de seguridad html5 y está prefijada a la ruta del archivo si la manipulamos con javascript. Vea esta publicación de blog davidwalsh.name/fakepath para más detalles.
codefreak
88

Está incluido en el tenedor de arranque de Jasny.

Se puede crear un botón de carga simple usando

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

Con el complemento de carga de archivos puede crear widgets más avanzados. Echa un vistazo a http://jasny.github.io/bootstrap/javascript/#fileinput

Arnold Daniels
fuente
¿Funciona bien en IE9? Lo pregunto porque supongo que la solución usa Javascript y, al mismo tiempo, "el IE no permite la manipulación del elemento de entrada type =” file ”desde javascript por razones de seguridad".
Marek Příhoda
Sí, también funciona en IE9. Establece la opacidad del elemento de entrada en 0, que afortunadamente funciona en todos los navegadores :). Se explica en el artículo del modo peculiar.
Arnold Daniels
1
no funciona con jQuery 1.9.0, porque dejaron caer el soporte $ .browser
Giedrius
14
Miradas terribles con arranque normal - img688.imageshack.us/img688/948/pictureui.png
cwd
66

Los botones de carga son difíciles de aplicar porque dan estilo a la entrada y no al botón.

pero puedes usar este truco:

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

Resumen:

  1. Tome un normal <input type="file">y póngalo en un elemento con position: relative.

  2. Para este mismo elemento padre, agregue una imagen normal <input>y otra, que tengan los estilos correctos. Coloque estos elementos absolutamente, de modo que ocupen el mismo lugar que el <input type="file">.

  3. Establezca el índice z de <input type="file">a 2 para que quede encima de la entrada / imagen con estilo.

  4. Finalmente, establezca la opacidad de <input type="file">0. El <input type="file">ahora se vuelve efectivamente invisible y los estilos de entrada / imagen brillan, pero aún puede hacer clic en el botón "Examinar". Si el botón se coloca en la parte superior de la imagen, el usuario parece hacer clic en la imagen y obtiene la ventana normal de selección de archivos. (Tenga en cuenta que no puede usar la visibilidad: oculto, porque un elemento verdaderamente invisible tampoco se puede hacer clic y necesitamos que se pueda hacer clic)

bautizo
fuente
66
Esto es demasiado trabajo para estos días. Usar algo listo como la solución de Jasny en la próxima respuesta tiene mucho más sentido.
mgPePe
2
Si su ejemplo incluye soporte para soportar netscape, probablemente no esté actualizado.
Tifomismo
22

Funciona para mi:

Actualizar

Estilo del complemento 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
fuente
17

Respuesta simplificada usando partes de otras respuestas, principalmente user2309766 y dotcomsuperstar.

caracteristicas:

  • Utiliza el complemento del botón Bootstrap para el botón y el campo.
  • Solo una entrada; múltiples entradas serían recogidas por un formulario.
  • Sin css extra excepto "display: none;" para ocultar la entrada del archivo.
  • El botón visible activa un evento de clic para la entrada de archivos ocultos.
  • split para eliminar la ruta del archivo utiliza expresiones regulares y delimitadores '\' y '/'.

Código:

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

Con algo de inspiración de otras publicaciones anteriores, aquí hay una solución completa que combina lo que parece un campo de control de formulario con un complemento de grupo de entrada para un widget de entrada de archivo limpio que incluye un enlace al archivo actual.

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

puntocomly
fuente
9

Esto funciona perfectamente para mi

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

Por favor, consulte la entrada de archivo Bootstrap de Twitter . Utiliza una solución muy simple, solo agregue un archivo javascript y pegue el siguiente código:

$('input[type=file]').bootstrapFileInput();
monsur.hoq
fuente
Enlace roto (julio de 2019)
Yetti99
@ Yetti99 sí, está roto ahora
monsur.hoq
@ Yetti99, cambié el enlace. Por favor revise ahora.
monsur.hoq
6

Una solución simple con un resultado aceptable:

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

Y el estilo:

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

Solución para carga múltiple

Modifiqué dos respuestas anteriores para incluir múltiples cargas. De esta forma, la etiqueta muestra el nombre del archivo, si solo se selecciona uno, o x filesen el 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>

ingrese la descripción de la imagen aquí

También puede aplicarse para cambiar el texto del botón y la clase.

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

ingrese la descripción de la imagen aquí

Nuno André
fuente
4

He creado un botón de carga personalizado para aceptar solo imágenes, que pueden modificarse según sus requisitos.

¡¡Espero que esto ayude!! :)

(Marco Bootstrap usado)

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

Este es el mejor estilo de carga de archivos que me gusta:

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

puedes obtener demo y más estilos en:

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

pero con esto, debe reemplazar el programa de arranque de twitter con archivos de arranque de jasny.

Saludos.

navins
fuente
4

Basado en la solución absolutamente brillante de @claviska, a quien se le debe todo el crédito.

Entrada de archivo Bootstrap 4 con todas las funciones con validación y texto de ayuda.

Según el ejemplo del grupo de entrada , tenemos un campo de texto de entrada ficticio utilizado para mostrar el nombre de archivo al usuario, que se completa desde el onchangeevento en el campo del archivo de entrada real oculto detrás del botón de etiqueta. Además de incluir la validación bootstrap 4 soporte de , también hemos hecho posible hacer clic en cualquier lugar de la entrada para abrir el cuadro de diálogo del archivo.

Tres estados de la entrada del archivo

Los tres estados posibles no están validados, son válidos e inválidos con el requiredconjunto de atributos de etiqueta de entrada html ficticia .

ingrese la descripción de la imagen aquí

Marcado HTML para la entrada

Introducimos solo 2 clases personalizadas input-file-dummyy input-file-btnpara diseñar y conectar correctamente el comportamiento deseado. Todo lo demás es el marcado estándar de 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>

Disposiciones de comportamiento de JavaScript

La entrada ficticia debe ser de solo lectura, según el ejemplo original, para evitar que el usuario cambie la entrada que solo se puede cambiar a través del diálogo de abrir archivo. Desafortunadamente, la validación no ocurre en los readonlycampos, por lo que alternamos la editabilidad de la entrada en foco y desenfoque ( eventos jquery onfocusin y onfocusout) y nos aseguramos de que se vuelva a validar una vez que se selecciona un archivo.

Además de hacer que se pueda hacer clic en el campo de texto, al activar el evento de clic del botón, @claviska imaginó el resto de la funcionalidad de llenar el campo ficticio.

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

Ajustes de estilo personalizados

Lo más importante es que no queremos que el readonlycampo salte entre el fondo gris y el blanco, por lo que nos aseguramos de que permanezca en blanco. El botón span no tiene un cursor de puntero, pero debemos agregar uno para la entrada de todos modos.

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

nJoy!

nickl-
fuente
2

/ * * Bootstrap 3 filestyle * http://dev.tudosobreweb.com.br/bootstrap-filestyle/ * * Copyright (c) 2013 Markus Vinicius da Silva Lima * Actualizar bootstrap 3 por Paulo Henrique Foxer * Versión 2.0.0 * Con licencia bajo la licencia 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
fuente
2

Modifiqué la respuesta de @claviska y funciona como me gusta (Bootstrap 3, 4 no probado):

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

ingrese la descripción de la imagen aquí

El siguiente código hace como arriba la imagen

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

Tengo el mismo problema y lo intento así.

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

El CSS

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

El JS

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

Nota: El botón .btn-file debe estar en la misma etiqueta que el archivo de entrada

Espero que hayas encontrado la mejor solución ...

Esgi Dendyanri
fuente
1

Intenta seguir en 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
fuente
1

Aquí hay un truco alternativo, no es la mejor solución, pero solo te da una opción

Código 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
fuente
1

Con respecto a la respuesta de claviska: si desea mostrar el nombre del archivo cargado en una carga básica de archivos, puede hacerlo en el onchangeevento de entradas . Solo usa este código:

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

Este código jquery JS es responsable de recuperar el nombre del archivo cargado:

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

O con vainilla JS:

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

ejemplo

Michał Stochmal
fuente
1

Pensé agregar mi valor de tres peniques, solo para decir cómo la entrada predeterminada .custom-file-labely el custom-file-inputarchivo BS4 y cómo se puede usar.

La última clase está en el grupo de entrada y no es visible. Mientras que la primera es la etiqueta visible y tiene un pseudoelemento después de que se parece a un botón.

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

No puede agregar clases a psuedoelements, pero puede diseñarlas en CSS (o SASS).

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

No se requiere shiz elegante:

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

PRECAUCIÓN: Los tres elementos de formulario en cuestión DEBEN ser hermanos entre sí (.image-file-elegido, .image-file-button, .image-file)

mattdlockyer
fuente