Bootstrap 4 File Input

197,274

Solution 1

Updated 2021

Bootstrap 5

Custom file input no longer exists so to change Choose file... you'd need to use JS or some CSS like this.

Bootstrap 4.4

Displaying the selected filename can also be done with plain JavaScript. Here's an example that assumes the standard custom-file-input with label that is the next sibling element to the input...

document.querySelector('.custom-file-input').addEventListener('change',function(e){
  var fileName = document.getElementById("myInput").files[0].name;
  var nextSibling = e.target.nextElementSibling
  nextSibling.innerText = fileName
})

https://codeply.com/p/LtpNZllird

Bootstrap 4.1+

Now in Bootstrap 4.1 the "Choose file..." placeholder text is set in the custom-file-label:

<div class="custom-file" id="customFile" lang="es">
        <input type="file" class="custom-file-input" id="exampleInputFile" aria-describedby="fileHelp">
        <label class="custom-file-label" for="exampleInputFile">
           Select file...
        </label>
</div>

Changing the "Browse" button text requires a little extra CSS or SASS. Also notice how language translation works using the lang="" attribute.

.custom-file-input ~ .custom-file-label::after {
    content: "Button Text";
}

https://codeply.com/go/gnVCj66Efp (CSS)
https://codeply.com/go/2Mo9OrokBQ (SASS)

Another Bootstrap 4.1 Option

Alternatively you can use this custom file input plugin

https://www.codeply.com/go/uGJOpHUd8L/file-input


Bootstrap 4 Alpha 6 (Original Answer)

I think there are 2 separate issues here..

<label class="custom-file" id="customFile">
        <input type="file" class="custom-file-input">
        <span class="custom-file-control form-control-file"></span>
</label>

1 - How the change the initial placeholder and button text

In Bootstrap 4, the initial placeholder value is set on the custom-file-control with a CSS pseudo ::after element based on the HTML language. The initial file button (which isn't really a button but looks like one) is set with a CSS pseudo ::before element. These values can be overridden with CSS..

#customFile .custom-file-control:lang(en)::after {
  content: "Select file...";
}

#customFile .custom-file-control:lang(en)::before {
  content: "Click me";
}

2 - How to get the selected filename value, and update the input to show the value.

Once a file is selected, the value can be obtained using JavaScript/jQuery.

$('.custom-file-input').on('change',function(){
    var fileName = $(this).val();
})

However, since the placeholder text for the input is a pseudo element, there's no easy way to manipulate this with Js/jQuery. You can however, have a another CSS class that hides the pseudo content once the file is selected...

.custom-file-control.selected:lang(en)::after {
  content: "" !important;
}

Use jQuery to toggle the .selected class on the .custom-file-control once the file is selected. This will hide the initial placeholder value. Then put the filename value in the .form-control-file span...

$('.custom-file-input').on('change',function(){
  var fileName = $(this).val();
  $(this).next('.form-control-file').addClass("selected").html(fileName);
})

You can then handle the file upload or re-selection as needed.

Demo on Codeply (alpha 6)

Solution 2

I just solved it this way

Html:

<div class="custom-file">
   <input id="logo" type="file" class="custom-file-input">
   <label for="logo" class="custom-file-label text-truncate">Choose file...</label>
</div>

JS:

$('.custom-file-input').on('change', function() { 
   let fileName = $(this).val().split('\\').pop(); 
   $(this).next('.custom-file-label').addClass("selected").html(fileName); 
});

Note: Thanks to ajax333221 for mentioning the .text-truncate class that will hide the overflow within label if the selected file name is too long.

Solution 3

As of Bootstrap 4.3 you can change placeholder and button text inside the label tag:

<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />

<div class="custom-file">
  <input type="file" class="custom-file-input" id="exampleInputFile">
  <label class="custom-file-label" for="exampleInputFile" data-browse="{Your button text}">{Your placeholder text}</label>
</div>

Solution 4

For changing the language of the file browser:
As an alternate to what ZimSystem mentioned (override the CSS), a more elegant solution is suggested by the bootstrap docs: build your custom bootstrap styles by adding languages in SCSS
Read about it here: https://getbootstrap.com/docs/4.0/components/forms/#file-browser

Note: you need to have the lang attribute properly set in your document for this to work

For updating the value on file selection:
You could do it with inline js like this:

   <label class="custom-file">
      <input type="file" id="myfile" class="custom-file-input" onchange="$(this).next().after().text($(this).val().split('\\').slice(-1)[0])">
      <span class="custom-file-control"></span>
   </label>

Note: the .split('\\').slice(-1)[0] part removes the C:\fakepath\ prefix

Solution 5

Bootstrap 4

More details are here https://learncodeweb.com/snippets/browse-button-in-bootstrap-4-with-select-image-preview/

Today I need to create a browse button with a multi-upload files option all the above snippets are not good for me.

The official Bootstrap example is also not working when I select multiple files.

I come up with this code maybe will help others in the future.

$(document).ready(function() {
  $('input[type="file"]').on("change", function() {
    let filenames = [];
    let files = document.getElementById("customFile").files;
    if (files.length > 1) {
      filenames.push("Total Files (" + files.length + ")");
    } else {
      for (let i in files) {
        if (files.hasOwnProperty(i)) {
          filenames.push(files[i].name);
        }
      }
    }
    $(this)
      .next(".custom-file-label")
      .html(filenames.join(","));
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container mt-5">
  <h1 class="text-center">Bootstrap 4 Upload multiple files</h1>
  <div class="col-sm-6 mr-auto ml-auto border p-4">
    <form method="post" enctype="multipart/form-data" action="upload.php">
      <div class="form-group">
        <label><strong>Upload Files</strong></label>
        <div class="custom-file">
          <input type="file" name="files[]" multiple class="custom-file-input form-control" id="customFile">
          <label class="custom-file-label" for="customFile">Choose file</label>
        </div>
      </div>
      <div class="form-group">
        <button type="submit" name="upload" value="upload" id="upload" class="btn btn-block btn-dark"><i class="fa fa-fw fa-upload"></i> Upload</button>
      </div>
    </form>
  </div>
</div>

The working code example is given here with bootstrap 3 and bootstrap 4.3.1.

https://codepen.io/mianzaid/pen/GeEbYV

Share:
197,274
Matej Vrzala M4
Author by

Matej Vrzala M4

Full Stack Web Developer. I like sports and books.

Updated on December 30, 2021

Comments

  • Matej Vrzala M4
    Matej Vrzala M4 over 2 years

    I am struggling with bootstrap 4 file browser. If I use custom-file-control I will see Choose file value all the time. https://v4-alpha.getbootstrap.com/components/forms/#file-browser

    I would like to change the value of choose file after the file has been chosen. This value is actually hidden in css .custom-file-control:lang(en)::after and I do not know how to access and change it in javascript. I can get the value of chosen file like this:

    document.getElementById("exampleInputFile").value.split("\\").pop();
    

    not I need to change

    .custom-file-control:lang(en)::after {
        content: "Choose file...";
    }
    

    somehow

    link: http://codepen.io/Matoo125/pen/LWobNp

  • Gringo Suave
    Gringo Suave almost 7 years
    C:\fakepath\... very funny.
  • George Kagan
    George Kagan almost 7 years
    1) Or use <html lang="en">
  • user14717
    user14717 almost 7 years
    Where is this C:\fakepath\... coming from?
  • Mena
    Mena over 6 years
    @ZimSystem Thanks for the solution. I'm getting same C:\fakepath\.. in firefox developer edition, is there a way to fix this?
  • Mena
    Mena over 6 years
    Just did now, missed it the first time. Thanks.
  • Jurgen De Landsheer
    Jurgen De Landsheer over 6 years
    you can also use: .custom-file-control.selected::after { content: "" !important; } to make it work for all languages (if your site supports multiple languages)
  • ego
    ego over 6 years
    I used this to get file name without "fakepath": var fileName = document.getElementById("upload-image-input").files[0].name;
  • Kristof Komlossy
    Kristof Komlossy over 6 years
    I assume it changed at some point, but now you are able to simply change the visible text snippet by setting the text of the span tag
  • Jason
    Jason over 6 years
    Nice. Using this to add to all custom file inputs: $('.custom-file-input').change(function () { $(this).next().after().text($(this).val().split('\\').slice(‌​-1)[0]); });
  • spaceemotion
    spaceemotion over 6 years
    Thanks for the .split('\\').pop() part!
  • Elnoor
    Elnoor over 6 years
    @spaceemotion happy it helped
  • ghukill
    ghukill about 6 years
    FWIW, I had to add type="file" to the <input> tag. But otherwise, worked great.
  • Elnoor
    Elnoor about 6 years
    @ghukill my answer was a quick design thingy, but i will just add the type attribute too, for those who will copy. Thanks
  • Zim
    Zim about 6 years
    Yes... the input placeholder, but not the button as explained above
  • ajax333221
    ajax333221 almost 6 years
    Worth saying you can hide the overflow with text-truncate like this class='custom-file-label text-truncate'
  • Elnoor
    Elnoor almost 6 years
    @ajax333221 that is awesome, didn't know about that class. Thanks. I just adjust ed answer.
  • user8897013
    user8897013 about 5 years
    @ajax333221 Using text-truncate I don't get ellipsis... If I don't use it, the text overruns the box (expected). But if I use text-truncate it just inserts text all the up to the end and stops (mid-letter depending on length). I even tried adding an inline style with text-overflow: ellipsis;, but no luck. Is this expected?
  • Abdelsalam Shahlol
    Abdelsalam Shahlol almost 5 years
    Can you provide a link to Bootstrap documentation?
  • Oldboy
    Oldboy over 4 years
    Actually, the most useful answer for me so +1. Minor improvement: add 'form-control' class to label element.
  • Andrei Veshtard
    Andrei Veshtard over 4 years