Coder Social home page Coder Social logo

johann-s / bs-custom-file-input Goto Github PK

View Code? Open in Web Editor NEW
210.0 10.0 40.0 969 KB

A little plugin for Bootstrap 4 custom file input

Home Page: https://bs-custom-file-input.netlify.com/

License: MIT License

JavaScript 83.59% HTML 16.41%
bootstrap bootstrap4 vanilla-js custom-input vanilla-javascript vanillajs react angular typescript

bs-custom-file-input's Introduction

bs-custom-file-input

npm version dependencies Status devDependencies Status Build Status Coverage Status JS gzip size BrowserStack Status

A little plugin which makes Bootstrap 4 custom file input dynamic with no dependencies.

You can use it on React and Angular too because this plugin is written with the most used JavaScript framework: VanillaJS.

Demo

Features:

  • Works with Bootstrap 4
  • Works without dependencies and jQuery
  • Display file name
  • Display file names for multiple input
  • Reset your custom file input to its initial state
  • Handle form reset
  • Allow custom selectors for input, and form
  • Allow to drag and drop files
  • Allow you to change the default display with a child in the <label> element
  • Built in UMD to be used everywhere
  • Small, only 2kb and less if you gzip it

Table of contents

Install

With npm

npm install bs-custom-file-input --save

CDN

CDN Link
jsDelivr https://cdn.jsdelivr.net/npm/bs-custom-file-input/dist/bs-custom-file-input.js
jsDelivr, minified https://cdn.jsdelivr.net/npm/bs-custom-file-input/dist/bs-custom-file-input.min.js

How to use it

You should wait for the document ready event and call the init method to make your custom file input dynamic. We expose one global variable available everywhere: bsCustomFileInput

$(document).ready(function () {
  bsCustomFileInput.init()
})

Use it with npm

import bsCustomFileInput from 'bs-custom-file-input'

For more examples check out this file.

This library is UMD ready so you can use it everywhere.

Methods

init

Finds your Bootstrap custom file input and will make them dynamic.

Parameters

  • inputSelector

    • default value: .custom-file input[type="file"]
    • type: string

    You can pass a custom input selector, but be sure to pass a file input selector

  • formSelector

    • default value: form
    • type: string

    Allows you to pass a custom form selector, but be sure to pass a form selector

destroy

Removes this plugin from your Bootstrap custom file input and restore them at their first initial state

Compatibility

bsCustomFileInput is compatible with:

  • IE10+
  • Edge
  • Firefox
  • Chrome
  • Safari
  • Chrome Android
  • Safari iOS

You can find our BrowserStack list of browsers here.

Support me

If you want to thank me, you can support me and become my Patron

Thanks

BrowserStack Logo

Thanks to BrowserStack for providing the infrastructure that allows us to test in real browsers!

License

MIT

bs-custom-file-input's People

Contributors

dependabot[bot] avatar johann-s avatar martijncuppens avatar xhmikosr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bs-custom-file-input's Issues

Plugin doesn't appear to work with Vue

Issue: This plugin doesn't appear to work when used alongside the Vue JavaScript library.

Here's a demo illustrating the problem: https://codepen.io/d-at-pm/pen/bGNqZzb

In this scenario the Bootstrap dependencies and the plugin are initialized before Vue is mounted into the DOM. Once a new file is selected the input label does not update with the new filename.

It is worth mentioning that if the plugin itself is initialized after Vue is mounted to the DOM then it does work.

This might not actually be an issue with this plugin itself and probably due to the way that Vue handles DOM nodes when initialized but I am curious if anyone else is aware of or has experienced this issue.

Any plans of adding sizing feature

I am using form-control-sm in all my forms but for files i am unable to set the size. Can you add this feature or guide me what i can do? I am using bootstrap.

Update:
I am using following styles to accomplish this. Hope it is the right approach for now.

<div class="form-group">
    <label for="facilityimage">Facility Image</label>
    <div class="input-group">
        <div class="custom-file custom-file-sm">
            <input type="file" id="facilityimage" name="facilityimage" class="custom-file-input" >                            
            <label class="custom-file-label" for="facilityimage">Facility Image</label>
        </div>
    </div>
</div>

and adding following css

.custom-file-sm, .custom-file-sm .custom-file-input, .custom-file-sm .custom-file-label
{
    height: calc(1.8125rem + 2px);
    font-size: 0.875rem;
}
.custom-file-sm .custom-file-input, .custom-file-sm .custom-file-label, .custom-file-sm .custom-file-label:after
{
    padding: 0.25rem 0.5rem;
}
.custom-file-sm .custom-file-label
{
    color: #939ba2;           /*  Just matching Placeholder Color   */
}
.custom-file-sm .custom-file-label:after
{
    height: 1.8125rem;
}

Missing export

I get this error when importing the module using Bootstrap's npm starter template: Uncaught SyntaxError: The requested module '../../node_modules/bs-custom-file-input/dist/bs-custom-file-input.js' does not provide an export named 'default'

Not able to make this work - no filename. Script and

I've installed via NPM into my Laravel 8 project.
I've added all this at the bottom of my page

<script src="./coverage/bs-custom-file-input.js"></script>
<script>
    bsCustomFileInput.init();

    var btn = document.getElementById('btnResetForm');
    var form = document.querySelector('form');
    btn.addEventListener('click', function () {
        form.reset()
    })
</script>

I've added this to my form
<div class="input-group mt-3"> <div class="custom-file"> <input id="inputGroupFile01" type="file" class="custom-file-input"> <label class="custom-file-label" for="inputGroupFile01">Choose file</label> </div> </div>
When I click Browse, I am able to choose a file, but nothing else. No filename shows.
I see "use with npm - import bsCustomFileInput from 'bs-custom-file-input'" but I'm not sure what this means if I've already installed it via npm.

I have a 404 for the js file and an uncaught ref error bsCustomFileInput is not defined.

What am I missing?
Thanks

Remove Source-Maps for Production Builds

Hi @Johann-S,

I would be happy to have a version of production build files without source maps. These are not necessary for production, and we only keep included files in our deployment. This will result in warnings inside the console because of missing bs-custom-file-input.min.js.map

//# sourceMappingURL=bs-custom-file-input.min.js.map

Thank you so far for this wonderful plugin! πŸ‘ŒπŸ»

Display number of items instead of their name on multiple inputs

Hi! Thanks for this plugin, I've been using a lot!

I wonder if, when the input is for several files (multiple), it shouldn't be better to display the number of selected items, instead of showing their names.

Browsers and Bootstrap v5 already do this by default:
image


This suggestion came about because I tried to upload files with very large names and an overflow happens. Of course it was easy to solve, adding the CSS property overflow: hidden to the class .custom-file-label, but this way most of the file names are hidden.

image

And since the file names already appear in the title when hovering the input, why not show the number of files uploaded in the input? I think it would be more useful!

Update method

Add an update method for dynamic custom file input created

Doesn't work with bootstrap 5

Hi,

I was just checking out the bootstrap 5 docs and it seems like this plugin doesn't work with bootstrap 5 (demo). It would be awesome if bootstrap 5 could be supported.

Vulnerable to XSS when passing an svg with onload

Bootstrap claims to be using this plugin, so I'm reporting the vulnerability here.

You can get script execution if you create a file with the following name and upload it to the custom file input.

<svg onload=alert(1)>

Captura de tela de 2020-01-30 13-35-51

That was Firefox. On Chromium and GNOME Web, the <svg> was inserted as HTML but it didn't trigger an alert popup. It would be best to escape for HTML before setting the filename.

I am using mdbootstrap 4.8.5 version in vue app.

This is my index.js file.

import 'jquery/dist/jquery';
import 'popper.js';
import 'bootstrap';
import 'mdbootstrap/js/mdb';
import "./partial/searcher";
import "./partial/home";

import '@fortawesome/fontawesome-free/js/all';

But i can see follow error.
mdb.js:15937 Uncaught ReferenceError: bsCustomFileInput is not defined
at HTMLDocument.eval (mdb.js:15937)
Can you help me kindly?

Feature: file size validation

The JS is pretty simple - check the size of each item in the FileList. It would be great if this component automatically added the validation for that with an attribute binding, e.g. data-max-size.

Does not show file name when browser back button has been pressed

Today I ran into a bug when using your plugin. Steps to reproduce:

  1. Open a page with a form containing a bs-custom-file-input
  2. Select a file
  3. Submit the form, server-side redirects you to another pgae
  4. Press the browser's back button
  5. The page with the form is displayed again, observe the following:
  • The file is still selected - yep.
  • The tooltip still displays the file name - yep.
  • The file name is displayed in the "label" - nope.

I guess that there is a missing update()/refresh() call.

Please tell me whether you can (and will : D) fix it anytime soon, or if you'd need a PR for this or if you don't think it's a bug at all.

Thanks for your nice plugin!

Best regards,
D.R.

ReferenceError: window is not defined

Hello,

Thank you for this great plugin. I am using for a nextjs react application but I have bumped into an error I can't get rid off unless I comment the following line:

var fileApi = !!window.File;

Otherwise, when I try to build my application I get the following error:

image

Removing the line makes the problem go away and the component keeps working fine so I am not sure if you really need it or you could avoid calling window there.

Thank you!
Alberto

Clear text on value clear

If the input is cleared using something like:
document.getElementById('fileInput').value = '';
The filename stays in place even though the underlying input has been cleared.

Add Bootstrap 5 support

Hello. Can you add support for Bootstrap 5?

I think we just need to add new classes selectors.

Thanks.

disable drag & drop?

Can you disable drag & drop?

The reason why I want to do this is that the file-type filtering with input tag's accept attribute does not work if you drag & drop as the issue below.
#41

Thank you!

Where the file name appears

<div class="custom-file">
  <input class="custom-file-input qrcode" id="qrcode" type="file">
  <label class="custom-file-label" for="qrcode" data-browse="提亀">
    qrcode<i class="ml-1 fas fa-qrcode">no this upload file name,file name is at label.innerHTML</i>
  </label>
</div>

bootstrap 4.4.1

The file name should be blank for all elements under the label element.

Add class to label when text has changed

If would be great if a class was added to the label when the text is changed to the filename. This would allow differentiating the default label style (to match a placeholder) w/ the filename label (to match input text)

When to call bsCustomFileInput.init() in a react app (when using in a Modal dialog)?

I've tried calling it in componentDidMount() of the dialog, (like the example), but It is not working. I've had to move it to the onChange for the file input so that it actually updates the screen. I'm pretty sure the problem is that my File.Input field is in the modal rather than on the base part of the page, noting this here for others that have this problem. Would be really nice if this could somehow be integrated into the react-bootstrap so that these kinds of workaround aren't needed.

The code in the onChange handler looks like this:

    if (this.customFileInit) {
      bsCustomFileInput.destroy();
    }
    bsCustomFileInput.init();
    this.customFileInit = true;

Bootstrap v5 compatibility

Hi,
while updating and testing on of my sites to BS v5 alpha, I've experienced this library breaking due .custom-file is .form-file now.

Too bad calling bsCustomFileInput.init('.form-file input[type="file"]') did not do the trick.

What am I missing?

Cheers
midzer

How to remove selected file?

How to remove selected file from input?
I try:

 $('selector').val('');

but that only clear label.
How to clear only one input from form?

Label descendants are removed or "concatenated"

Hello,

What am I trying to do?
I'm trying to use Bootstrap display utility classes to render different elements inside the label on different screen sizes.

What is the issue?
The descendants of the .custom-file-label tag are being modified in a weird way.

Example 1:
This is the HTML I provide in my file:

<div class="m-auto">
    <span class="d-block d-md-none">Upload</span>
    <span class="d-none d-md-block">Drop files here or click to upload</span>
</div>

And this is what it is rendered as after the plugin is initialized:

<div class="m-auto">UploadDrop files here or click to upload</div>

Example 2:
This is the HTML I provide in my file:

<div class="m-auto d-block d-md-none">Upload</div>
<div class="m-auto d-none d-md-block">Drop files here or click to upload</div>

And this is what it is rendered as after the plugin is initialized:

<div class="m-auto d-block d-md-none">UploadDrop files here or click to upload</div>
<div class="m-auto d-none d-md-block">Drop files here or click to upload</div>

I am using React and Bootstrap v5 (I'm using v4 class names as well to make this compatible, since this plugin looks for v4 class names)

`destroy` should be able to specify a specific element, not wipe out the entire documents custom ones

If I have multiple custom file inputs on a form, and want to remove just one, I should call destroy to clean up any event handlers etc to prevent memory leakage, but at that point it'll destroy all the remaining file inputs on my form.

Ideally I should be able to call destroy with an identifier, or alternatively init could return a cleanup function that will destroy anything it specifically initialised?

Make a new release

A lots of code improvement have been made, and the dist file should be smaller too

Label text overflows when uploading multiple files in iOS Safari

I noticed when doing some testing that when using iOS Safari, if you upload multiple image files (which have pretty long names when stored in Photos), the text overflows the label and isn't hidden.

I propose something like:

.custom-file-label {
    white-space: nowrap !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    padding-right: 25%;
}

The padding is optional but I think it looks better truncated with an ellipsis. This was the easiest way to achieve that.

Support Bootstrap 5

Hi!

It would be great if your plugin would also support the new Bootstrap 5.

All the best from Vienna,
-D.R.

Dynamically adding new custom file inputs and reinitializing leads to wrong default texts

Hey folks,

I experienced following behavior in my web app:
So my page has one custom file input per default. However if a file is selected, a new custom file input is appended to the form, hence bsCustomFileInput needs to be reinitialized in order to get the recently added file inputs to work. I tried both bsCustomFileInput.init() and bsCustomFileInput.init(<field.selector>), both lead to wrong default texts as the second initialization sets the currently selected filename as the default text and overrides the actual default value for ALL custom file inputs. Eg:

input1.files = [] (default: "Choose file")
= user input ("file1.txt") =>
input1.files = ["file1.txt"] (default: "Choose file")
input2.files = [] (default: "Choose file", NOT initialized yet)
= bsCustomFileInput.init() or bsCustumFileInput.init(<input1.selector>) =>
input1.files = ["file1.txt"] (default: "file1.txt")
input2.files = [] (default: "Choose file")

Unfortunately I do not see any kind of quick workaround for this particular problem, so I think I am going for my own solution for now.

For a future release I think it would be nice to have a function to add new custom file inputs to the document or reinitialize the inputs without losing currently not used default values.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.