File Selection Tool with Bootstrap 4

I am having difficulty with the bootstrap 4 file browser. Whenever I use custom-file-control, the "Choose file" value is always displayed.

My goal is to change the "Choose file" value after a file has been selected. This value is actually hidden in CSS

.custom-file-control:lang(en)::after
, and I'm unsure how to access and modify it using JavaScript. I can retrieve the chosen file's value like this:

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

Now, I need to somehow alter

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

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

Answer №1

Updated for the Year 2021

New Features in Bootstrap 5

The custom file input feature has been removed in Bootstrap 5. To modify the text "Choose file..." now requires the use of JavaScript or some CSS tricks like this example.

For Bootstrap 4.4 Users

To display the selected filename without custom file input, you can utilize plain JavaScript. Here's a sample code snippet assuming there is a standard custom-file-input with a label as 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
})

Code Example - Displaying Selected File Name

Introducing Bootstrap 4.1+

In Bootstrap 4.1, the placeholder text "Choose file..." is now defined inside 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>

To change the text on the browse button, some additional CSS or SASS modifications are required. Also, notice how language translations work using the lang="" attribute.

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

CSS Sample - Change Button Text
SASS Sample - Modify Button Appearance

Another Option for Bootstrap 4.1 Users

Alternatively, you can integrate this custom file input plugin

Custom File Input Plugin - Demo


Details About Bootstrap 4 Alpha 6 (Original Answer)

There seem to be 2 distinct issues at play here..

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

Issue 1 - Tweaking Initial Placeholder and Button Text

In Bootstrap 4, the initial placeholder value can be adjusted via the custom-file-control using a CSS pseudo ::after element based on the website language. The initial file button appearance (though not functional) can be modified using a CSS pseudo ::before element. These settings can be overwritten with CSS customization..

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

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

Issue 2 - Retrieving Selected Filename and Updating Input Display

Once a file is chosen, its name can be extracted using JavaScript/jQuery.

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

Since the placeholder text is managed through a pseudo element, manipulating it with Js/jQuery isn't straightforward. However, you can have an additional CSS class that conceals the pseudo content upon selecting a file...

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

Toggle the .selected class on the .custom-file-control utilizing jQuery once a file is picked. This action hides the initial placeholder value and displays the filename 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);
})

Further processes related to file uploading or re-selection can then be handled accordingly.

Live Demonstration on Codeply (alpha 6)

Answer №2

This is how I managed to solve it

Here is the HTML code snippet:

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

And this is the JS code snippet:

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

Important: Many thanks to ajax333221 for pointing out the .text-truncate class that helps in hiding overflow within label if the selected file name is too lengthy.

Answer №3

Starting from the latest version of Bootstrap 4.3, it is now possible to customize the placeholder and button text directly within 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 custom button text}">{Your custom placeholder text}</label>
</div>

Answer №4

To change the language of the file browser:
Instead of overriding the CSS as suggested by ZimSystem, a more elegant solution is recommended in the bootstrap documentation: create custom bootstrap styles by incorporating languages in SCSS
Learn more about it here: https://getbootstrap.com/docs/4.0/components/forms/#file-browser

Tip: Ensure that the lang attribute is correctly configured in your document for this method to be effective

To update the value upon file selection:
You can achieve this using inline javascript like so:

   <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] segment removes the C:\fakepath\ prefix

Answer №5

Enhancing Bootstrap 4 Browse Button

For more detailed information, you can visit this link

Today I had the task of creating a browse button that allows for multiple file uploads, but none of the existing snippets met my requirements.

Even the example provided in the official Bootstrap documentation did not work as expected when selecting multiple files.

I have come up with a code snippet that might be useful for others facing similar challenges 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/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e7858888939493958697a7d3c9d1c9d7">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container mt-5">
  <h1 class="text-center">Bootstrap 4 Enhance Multiple File Uploads</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>

A functional code example is available here, compatible with both bootstrap 3 and bootstrap 4.3.1 versions.

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

Answer №6

For Bootstrap version 5

document.querySelectorAll('.form-file-input')
        .forEach(element => element.addEventListener('change', event => event.target.parentElement.querySelector('.form-file-text').innerText = event.target.files[0].name));

This code snippet will impact all file input elements without the requirement to specify element IDs.

Answer №7

If you are looking for an alternative to using jquery, you can try the following solution:

<label class="custom-file">
      <input type="file" id="myfile" class="custom-file-input" onchange="this.nextElementSibling.innerText = this.files[0].name">
      <span class="custom-file-control"></span>
</label>

Answer №8

Here is the solution with blue box-shadow, border, and outline removed in the custom-file input of bootstrap. The file name will appear when a filename is chosen, and if no file is selected, it will display No file chosen.

    $(document).on('change', 'input[type="file"]', function (event) { 
        var filename = $(this).val();
        if (filename == undefined || filename == ""){
        $(this).next('.custom-file-label').html('No file chosen');
        }
        else 
        { $(this).next('.custom-file-label').html(event.target.files[0].name); }
    });
    input[type=file]:focus,.custom-file-input:focus~.custom-file-label {
        outline:none!important;
        border-color: transparent;
        box-shadow: none!important;
    }
    .custom-file,
    .custom-file-label,
    .custom-file-input {
        cursor: pointer;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"/>
    <div class="container py-5">
    <div class="input-group mb-3">
      <div class="input-group-prepend">
        <span class="input-group-text">Upload</span>
      </div>
      <div class="custom-file">
        <input type="file" class="custom-file-input" id="inputGroupFile01">
        <label class="custom-file-label" for="inputGroupFile01">Choose file</label>
      </div>
    </div>
    </div>

Answer №9

Regarding the file named "bootstrap_4_layout.html.twig":

The function attached to the event listener of '.custom-file-input' element sets the text of its next sibling to the name of the selected file.

Answer №10

After some experimenting, I found a solution that works perfectly in my CSS file:

.custom-file-label::after{content: 'Click Here for New Text' !important;}


Answer №11

Using the power of jquery, achieving this task is quite simple. Here's the code snippet:

$("input.custom-file-input").on("change",function(){if(this.files.length){var filename=this.file[0].name;if(filename.length>23){filename=filename.substr(0,11)+"..."+filename.substr(-10);}$(this).siblings(".custom-file-label").text(filename);}});

Answer №12

If you want to show the name of the file selected using the file input type, you can use the following code snippet:

document.querySelectorAll('input[type=file]').forEach( input => {
    input.addEventListener('change', e => {
        e.target.nextElementSibling.innerText = input.files[0].name;
    });
});

Answer №13

Here is an alternative solution inspired by @Elnoor's method, designed to accommodate multiple file uploads without resorting to the "fakepath hack":

HTML:

<div class="file-container">
    <input id="files" type="file" class="file-input" multiple>
    <label for="files" class="file-label text-truncate">Select files...</label>
</div>

JS:

$('input[type="file"]').on('change', function () {
    let fileNames = [];
    let chosenFiles = document.getElementById('files').files;

    for (let index in chosenFiles) {
        if (chosenFiles.hasOwnProperty(index)) {
            fileNames.push(chosenFiles[index].name);
        }
    }

    $(this).next('.file-label').addClass("file-selected").html(fileNames.join(', '));
});

Answer №14

Bootstrap 4.4:

Create a bar to allow users to select a file. Once a file is selected, display the name of the file along with its extension.

<div class="custom-file">
    <input type="file" class="custom-file-input" id="idEditUploadVideo"
     onchange="$('#idFileName').html(this.files[0].name)">
    <label class="custom-file-label" id="idFileName" for="idEditUploadVideo">Choose file</label>
</div>

Answer №15

If you're looking to apply this code universally to all customized input fields, implement the following jQuery script:

$(document).ready(function () {
    $('.custom-input-field').on('change', function (event) {
         event.target.nextElementSibling.innerHTML = event.target.files[0].name;
    });
});

Answer №16

Enhanced File Uploader with Bootstrap 5.2 Create a custom file input without the need for additional CSS.

Preview Image: https://i.sstatic.net/BVV1O.png

HTML Code Sample:

<div class="input-group">   
     <input type="file" id="uploadFile_Plan_PDF" class="Zupload" accept="application/pdf" hidden/>
     <button type="button" class="btn btn-outline-secondary">
      <i class="fa-solid fa-file-pdf"></i>
     </button>
     <input readonly="readonly" type="text" class="form-control">                                
     <button type="button" class="btn btn-outline-secondary" disabled>
      <i class="fa-solid fa-eye"></i>
     </button>
     <button type="button" class="btn btn-outline-secondary">
      <i class="fa-solid fa-times"></i>
     </button>
</div>

JS Code Snippet:

const collection_uploadFile = document.querySelectorAll(".Zupload");
for (let i = 0; i < collection_uploadFile.length; i++) {
  let uploadFile = collection_uploadFile[i]
  let buttonUpload = uploadFile.nextElementSibling;
  let textBoxUpload = buttonUpload.nextElementSibling;
  let buttonView = textBoxUpload.nextElementSibling;
  let buttonClear = buttonView.nextElementSibling;              

  uploadFile.addEventListener('change', function (e) {
    textBoxUpload.value = this.value;
    buttonView.disabled = this.value?false:true;
  });
  buttonUpload.addEventListener('click', function (e) {uploadFile.click();});
  textBoxUpload.addEventListener('click', function (e) {uploadFile.click();});
  buttonClear.addEventListener('click', function (e) {
    uploadFile.value =""; 
    uploadFile.dispatchEvent(new Event("change"));
  });
}

Live Demo:

Check out the Zupload on jsfiddle

Answer №17

 <!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">

    <title>Greetings from the digital world!</title>
  </head>
  <body>
    <h1>Welcome to this virtual space!</h1>
  <div class="custom-file">
    <input type="file" class="custom-file-input" id="inputGroupFile01">
    <label class="custom-file-label" for="inputGroupFile01">Select a file</label>
  </div>
    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
 <script>
$(function() {
  $(document).on('change', ':file', function() {var input = $(this), numFiles = input.get(0).files ? input.get(0).files.length : 1,
        label = input.val().replace(/\\/g, '/').replace(/.*\//, '');input.trigger('fileselect', [numFiles, label]);
  });
  $(document).ready( function() {
      $(':file').on('fileselect', function(event, numFiles, label) {var input = $(this).parents('.custom-file').find('.custom-file-label'),
      log = numFiles > 1 ? numFiles + ' files selected' : label;if( input.length ) {input.text(log);} else {if( log ) alert(log);}});
  });
});
 </script>
  </body>
</html>

Answer №18

Not using jQuery

HTML:

<INPUT type="file" class="custom-file-input"  onchange="return onChangeFileInput(this);">

JavaScript:

function onChangeFileInput(elem){
  var sibling = elem.nextSibling.nextSibling;
  sibling.innerHTML=elem.value;
  return true;
}

KliG

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for accessing the information received from an AJAX call

When making an AJAX post request for processed data from the database in the form of an array [value1, value2, value3,...,valueN], I aim to use it on a ChartJS object. Here is the AJAX Request: $(document).ready($.post('callMeForAJAX.jsp', func ...

When using a Vue.js component, the value of this.$route can sometimes come back

I am attempting to retrieve the parameters from the URL and pass them into a method within a Vue component. Despite following advice to use this.$route, I am consistently getting an 'undefined' response. I have tried various solutions suggested ...

Establish a constant height while maintaining the original width dimensions

Is there a way to make an image maintain a specific height while also adjusting its width according to the user's screen size? Below is the CSS for the image: #cafe { max-width: 100%; height: 700px; } See the resulting output: https://i.sstatic ...

Ensuring consistent placement and scrollability of two divs across all screen sizes

I am in need of a solution to fix the top and bottom divs in the given image. The scroll should only occur when there is overflow. <!DOCTYPE html> <html> <head> <script src="//code.jquery.com/jquery-1.9.1.min.js"></script> ...

I have an HTML table with multiple cells containing inner HTML tables. I have implemented a function along with buttons to filter the main table, excluding the inner tables

My HTML Table is generated from my database, containing information about machines and their status pulled from emails with HTML Tables. Each row has a click option to open/hide the <td> tag showing the original table for more details and better trac ...

Building an AJAX Fetch with Django, SQL, Vanilla JS, and React

As I work on building my website with Django and React, I am encountering a challenge that involves making an AJAX request to fetch data from the server and update it dynamically using JavaScript on the client side. To achieve this, I rely on Django for c ...

Scaling a plane in Three.js to cover the entire screen

My process of adding a plane to the scene goes like this: // Setting up Camera this.three.camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 60); // Creating Plane const planeGeometry = new THREE.PlaneBufferGeometry(1,1,thi ...

Dynamically load the configuration for a JQuery plugin

Currently, I am utilizing a JQuery plugin from this source. My goal is to dynamically load the configuration of the plugin without directly modifying it within the plugin file. Below are the default options provided by the plugin: $.Slitslider.def ...

I'm sorry, but we were unable to locate the /bin/sh

After running a command using execSync that runs with sh, I observed the following: spawnSync /bin/sh ENOENT bin is now included in the PATH environment variable. Any ideas on this issue? ...

managing the placement of tooltipster tooltips for a set of radio buttons

I have successfully set up tooltipster to display my validation messages, but I am facing an issue with one specific case. The problem arises when dealing with a set of radio buttons where selecting "Yes" from the Yes/No options is mandatory. Despite setti ...

When using Angular, automatically shift focus to the next input field by pressing the

I am faced with a challenge involving multiple editable inputs on my screen. Alongside these editable inputs, there are buttons and disabled inputs present. The current behavior is such that when I press Tab, the focus shifts to the HTML elements between ...

Issues with FullCalendar functionality in CakePHP 1.2.5 are arising when using jQuery version 1.4.1

Currently, I am encountering an issue with fetching events data through a URL that returns JSON data. Surprisingly, the code works flawlessly with jQuery 1.3.2, however, it throws errors when using jQuery 1.4.1. The specific error message displayed in the ...

Creating a rectangular pyramid using three.js r68: a step-by-step guide

Currently working on r68, I'm in search of a modern example showcasing the creation of a rectangular pyramid that will allow me to implement THREE.MeshFaceMaterial(). Many existing examples are outdated and lead to errors with my current setup. My re ...

The encoding of Node.js using npm

Looking to install the validate .json file below using npm: { "name": "node-todo", "version": "0.0.0", "description": "Simple todo application", "main": "server.js", "dependencies": { "express": "~3.4.4", "mongoose": "~ ...

Issue: The error message "undefined variable 'angular'" appears when attempting to access offline files stored on a network drive

I have successfully developed offline forms using angular js v1.6.4, angular-ui-bootstrap, and angular-ui-router without the need for server hosting. When the package is saved on local storage, it functions perfectly on both IE and Chrome browsers. Howeve ...

Using ajax to execute a basic PHP function

How can I execute a PHP function with a query using AJAX? This is my HTML: <input type="submit" value="Open Process" name="openProcess" id="openProcess" onclick="javascript:applicationOpenProcess()" > And here's my PHP function: function ope ...

The functionality of `setState` is experiencing issues when used in conjunction with the `onLongPress` event of

I am new to react-native and I am trying to create a feature where a counter increases or decreases when a button is pressed for a long duration. I am using the onLongPress prop of TouchableOpacity along with setTimeout() to delay the state change by 400ms ...

Add a div to another div when a droppable element is dropped, ensuring it only happens once

I have a draggable feature that, when dropped onto the target area, adds a delete button dynamically: $( "#committed" ).droppable({ hoverClass: 'drophover', drop: function( event, ui ) { ...

The URL is being modified, yet the page remains static in the React application

I've been working on setting up a router with react-router-dom, but I'm facing an issue where my URL gets updated without the page routing to the specified component. Here's a snippet from my App.js: import "./App.css"; import { Br ...

Flexslider optimized for mobile devices

I am currently using the Sparkling theme on a Wordpress website. This particular theme utilizes Flexslider within a div at the top of the page. Each slide featured in the slider includes an image, as well as a div containing a post title and excerpt. The ...