Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Styling file upload button for simple_form_for with Bootstrap in Rails 3

Using simple_form_for, Bootstrap and Rails 3. In a form:

<%= f.input :upload, label: 'PDF file:' , input_html: {accept: ('application/pdf') } %>

I don't know how I'd style this so that the "choose file" button can have a different class ('btn btn-primary').

Additionally, when using with Bootstrap at least, its severely misaligned by default. See attached image.

Finally, how do I redefine the text from "No file chosen" to "Chose file" when there isn't one added yet, and show the file name when there is one.

enter image description here

like image 987
tibbon Avatar asked Jan 24 '13 19:01

tibbon


6 Answers

This is how I do it:

  1. In the view add your form file field and hide it
  2. Add a styled additional field just to display the file name
  3. Add a button to trigger the file browse dialog

    <div class="control-group">
      <div class="attach-set">
        <%= f.input :real_file, input_html: { hidden: true }, label: 'Upload Attachment' %>
        <div class="input-append">
          <input id="file-display" class="input-large uneditable-input" type="text">
          <a id="upload-btn" class="btn"><i class="icon-upload-alt"></i> Browse</a>
        </div>
      </div> <!-- /attach-set -->
    </div> <!-- /control-group -->
    
  4. In your JS (Coffee w/ jQuery shown), pass the click from the display button onto the real file input and when they select a file drop the file name in the display text field (I drop the path so that I don't see C:\FakePath....)

    $(document).ready ->
    
      # ------------------------------------------------------
      # pretty-fy the upload field
      # ------------------------------------------------------
      $realInputField = $('#real_file')
    
      # drop just the filename in the display field
      $realInputField.change ->
        $('#file-display').val $(@).val().replace(/^.*[\\\/]/, '')
    
      # trigger the real input field click to bring up the file selection dialog
      $('#upload-btn').click ->
        $realInputField.click()
    
like image 70
BSB Avatar answered Oct 26 '22 22:10

BSB


This worked great for me and only requires HTML

<label class="btn btn-primary">
  Add a file!
  <span style="display:none;">
    <%= f.file_field :image, required: true, multiple: true, name: 'picture' %>
  </span>
</label>
like image 42
Yoko Avatar answered Oct 26 '22 22:10

Yoko


I ran across and am using Jasny's extension to Bootstrap 3. It seems to work well so far.

like image 6
kross Avatar answered Oct 26 '22 20:10

kross


No JS required, just plain css

scss

.fileinput-button {
  position: relative;
  overflow: hidden;
  float: left;
  margin-right: 4px;
  width: 110px;
  height: 32px;
  input{
    opacity: 0;
    filter: alpha(opacity=0);
    transform: translate(-300px, 0) scale(4);
    direction: ltr;
    cursor: pointer;
  } 
}

html / slim

span class="btn btn-success fileinput-button"
  i.fa.fa-pencil
  span
   |  Select File
  = f.file_field :cover_ar

I recommend using compass for cross browser compatibility

like image 4
Max Avatar answered Oct 26 '22 22:10

Max


As @rafaelfranca said you can't style file input but you can add your own button which will be clicking your hidden original button. See example here http://jsfiddle.net/rUdf2/6/

like image 2
Vasiliy Ermolovich Avatar answered Oct 26 '22 21:10

Vasiliy Ermolovich


Every Browser has a different type of file input field button and this makes it a pain. You can play a little with css. This has given me a basic styling with JS without the annoying "No file chosen" text in chrome and Safary:

$(document).ready(function() {
  $(".your_button").css("width", "80px");
});

Otherwise the best solution is to hide it and show a fake one that intercepts the click:

http://duckranger.com/2012/06/pretty-file-input-field-in-bootstrap/

With respect to the question of how to show that a file has been uploaded, a basic solution with jquery file upload is to detect the upload complete event and replace some of your text with a success message (The exact file name I believe it is not possible to obtain with modern browsers):

$(".your_button").fileupload({
    dataType: "json",
    done: function(e, data) {
        $(".place_for_your_text").text("File uploaded.");
    }
});

In summary, a basic solution is to use javascript in your assets to:

  1. Hide the annoying "No file chosen text" with css.
  2. Place your "Chose file" text next to the button and give it a class you can reference.
  3. Replace the text with "File uploaded"
like image 2
joscas Avatar answered Oct 26 '22 21:10

joscas