bootstrap-vue
Version:
BootstrapVue, with over 40 plugins and more than 80 custom components, custom directives, and over 300 icons, provides one of the most comprehensive implementations of Bootstrap v4 components and grid system for Vue.js. With extensive and automated WAI-AR
297 lines (221 loc) • 10.5 kB
Markdown
# Form File Input
> Customized, cross-browser consistent, file input control that supports single file, multiple
> files, and directory upload (for browsers that support directory mode)
```html
<template>
<div>
<!-- Styled -->
<b-form-file
v-model="file"
:state="Boolean(file)"
placeholder="Choose a file or drop it here..."
drop-placeholder="Drop file here..."
></b-form-file>
<div class="mt-3">Selected file: {{ file ? file.name : '' }}</div>
<!-- Plain mode -->
<b-form-file v-model="file2" class="mt-3" plain></b-form-file>
<div class="mt-3">Selected file: {{ file2 ? file2.name : '' }}</div>
</div>
</template>
<script>
export default {
data() {
return {
file: null,
file2: null
}
}
}
</script>
<!-- b-form-file.vue -->
```
For cross browser consistency, Form file defaults to the Bootstrap custom file input to replace the
browser defaults. They're built on top of semantic and accessible markup, so it is a solid
replacement for the default file input.
## Single file (default)
On single file mode, when no file is selected or user cancels Browse dialog, `v-model` is `null`
indicating no file selected. When a file is selected the return value will be a JavaScript
[`File`](https://developer.mozilla.org/en/docs/Web/API/File) object instance.
## Multiple files
Multiple file uploading is supported by adding `multiple` prop to component. In this case `v-model`
is _always_ an `Array`. When no files are selected, an empty array will be returned. When a file or
files are selected the return value will be an array of JavaScript
[`File`](https://developer.mozilla.org/en/docs/Web/API/File) object instances.
## Directory mode
By adding `directory` prop, the user can select directories instead of files. When a directory is
selected, the directory and its entire hierarchy of contents are included in the set of selected
items. The selected file system entries can be obtained using the `webkitEntries` property.
**CAUTION** This is a non standard feature while being supported by latest Firefox and Chrome
versions, and should not be relied for production.
[Read more on MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/webkitdirectory)
Directory mode is not supported when the file input is in plain mode.
## Drag and Drop support
Drop mode is enabled by default. It can disabled by setting the `no-drop` prop. `no-drop`has no
effect in plain mode.
You can optionally set a different placeholder while dragging via the `drop-placeholder` prop. The
default is no drop placeholder text. Only plain text is supported. HTML and components are not
supported. The `drop-placeholder` prop has no effect if `no-drop`is set or in `plain` mode,
## Limiting to certain file types
You can limit the file types by setting the `accept` prop to a string containing the allowed file
type(s). To specify more than one type, separate the values with a comma.
```html
<div>
<!-- Accept all image formats by IANA media type wildcard-->
<b-form-file accept="image/*"></b-form-file>
<!-- Accept specific image formats by IANA type -->
<b-form-file accept="image/jpeg, image/png, image/gif"></b-form-file>
<!-- Accept specific image formats by extension -->
<b-form-file accept=".jpg, .png, .gif"></b-form-file>
</div>
```
To accept any file type, leave `accept` as null (default). You can mix and match IANA media types
and extensions.
Refer to [IANA Media Types](http://www.iana.org/assignments/media-types/) for a complete list of
standard media types.
**Note:** Not all browsers support or respect the `accept` attribute on file inputs.
## Customizing
`<b-form-file>`, when not in [`plain` mode](#non-custom-file-input), provides several features for
customizing its appearance.
### Control sizing
Use the `size` prop to control the visual size of the input. The default size is considered `md`
(medium). Optional sizes are `lg` (large) and `sm` (small). These sizes line up with the sizes
available on other form controls.
```html
<div>
<b-form-group label="Small:" label-for="file-small" label-cols-sm="2" label-size="sm">
<b-form-file id="file-small" size="sm"></b-form-file>
</b-form-group>
<b-form-group label="Default:" label-for="file-default" label-cols-sm="2">
<b-form-file id="file-default"></b-form-file>
</b-form-group>
<b-form-group label="Large:" label-for="file-large" label-cols-sm="2" label-size="lg">
<b-form-file id="file-large" size="lg"></b-form-file>
</b-form-group>
</div>
<!-- form-file-sizes.vue -->
```
**Note:** Bootstrap v4.x does not natively support sizes for the custom file control. However,
BootstrapVue includes custom SCSS/CSS that adds support for sizing the custom file input control.
### Customize the placeholder text
Use the prop `placeholder` to change the prompt text that is shown when no files are selected. Only
plain text is supported. HTML and components are not supported.
### Customize browse button label
If you want to globally change `Browse` label, you can add something like this to your global
stylesheets. Also it is advised to use
[:lang()](https://developer.mozilla.org/en-US/docs/Web/CSS/:lang) for multi-language sites.
```css
.custom-file-input:lang(en) ~ .custom-file-label::after {
content: 'Browse';
}
```
Alternatively you can set the content of the custom file browse button text via the `browse-text`
prop. Note, only plain text is supported. HTML and components are not supported.
### File name formatter function
Set the prop `file-name-formatter` to a function that accepts a single argument which is an array of
[`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) objects. The function should return
a single formatted string (HTML is not supported). The formatter will not be called if no files are
selected.
Regardless of if the prop `multiple` is set or not, the argument to the formatter will always be an
array.
```html
<template>
<b-form-file multiple :file-name-formatter="formatNames"></b-form-file>
</template>
<script>
export default {
methods: {
formatNames(files) {
if (files.length === 1) {
return files[0].name
} else {
return `${files.length} files selected`
}
}
}
}
</script>
<!-- file-formatter-function.vue -->
```
### File name formatting via scoped slot
Alternatively, you can use the scoped slot `file-name` to render the file names. The scoped slot
will receive the following properties:
| Property | Type | Description |
| -------- | ----- | ----------------------- |
| `files` | Array | Array of `File` objects |
| `names` | Array | Array of file names |
Both properties are always arrays, regardless of the setting of the `multiple` prop.
```html
<template>
<b-form-file multiple>
<template slot="file-name" slot-scope="{ names }">
<b-badge variant="dark">{{ names[0] }}</b-badge>
<b-badge v-if="names.length > 1" variant="dark" class="ml-1">
+ {{ names.length - 1 }} More files
</b-badge>
</template>
</b-form-file>
</template>
<!-- file-formatter-slot.vue -->
```
When using the `file-name` slot, the `file-name-formatter` prop is ignored. Also, the slot will not
be rendered when there are no file(s) selected.
## Non custom file input
You can have `<b-form-file>` render a browser native file input by setting the `plain` prop. Note
that many of the custom form-file features do not apply when `plain` is set.
## Contextual state feedback
Bootstrap includes validation styles for `valid` and `invalid` states on most form controls.
Generally speaking, you'll want to use a particular state for specific types of feedback:
- `false` (denotes invalid state) is great for when there's a blocking or required field. A user
must fill in this field properly to submit the form.
- `true` (denotes valid state) is ideal for situations when you have per-field validation throughout
a form and want to encourage a user through the rest of the fields.
- `null` Displays no validation state (neither valid nor invalid)
To apply one of the contextual state icons on `<b-form-file>`, set the `state` prop to `false` (for
invalid), `true` (for valid), or `null` (no validation state).
**Note:** Contextual states are **not** supported when in button mode.
## Autofocus
When the `autofocus` prop is set on `<b-form-file>`, the input will be auto-focused when it is
inserted (i.e. **mounted**) into the document, or re-activated when inside a Vue `<keep-alive>`
component. Note that this prop **does not** set the `autofocus` attribute on the input, nor can it
tell when the input becomes visible.
## Accessibility
When using the custom version of `<b-form-file>` input which hides the original input, it is
**highly recommended** that you supply a document unique ID string via the `id` prop. This will
automatically render the extra ARIA attributes required to improve usability for persons using
assistive technologies.
## Clearing the file selection
With inputs of type file, normally the `v-model` is uni-directional (meaning you cannot pre-set the
selected files). However, you can clear the file input's selected files by setting the `v-model` to
either `null` (for single mode) or an empty array `[]` (for multiple/directory mode).
Alternatively, `<b-form-file>` provides a `reset()` method that can be called to clear the file
input. To take advantage of the `reset()` method, you will need to obtain a reference to the
`<b-form-file>` component.
```html
<template>
<div>
<b-form-file v-model="file" ref="file-input" class="mb-2"></b-form-file>
<b-button @click="clearFiles" class="mr-2">Reset via method</b-button>
<b-button @click="file = null">Reset via v-model</b-button>
<p class="mt-2">Selected file: <b>{{ file ? file.name : '' }}</b></p>
</div>
</template>
<script>
export default {
data() {
return {
file: null
}
},
methods: {
clearFiles() {
this.$refs['file-input'].reset()
}
}
}
</script>
<!-- b-form-file-reset.vue -->
```
**Implementation note:** As not all browsers allow setting a value of a file input (even to null or
an empty string), `b-form-input` employs a technique that works cross-browser that involves changing
the input type to `null` and then immediately back to type `file`.
<!-- Component reference added automatically from component package.json -->