Skip to content

Commit

Permalink
feat(form-file): reset file input when value set to null or empty str…
Browse files Browse the repository at this point in the history
…ing (#2170)

* feat(form-file): reset file input when value  set to null or empty string

As an alternative to calling the `reset()` method, users can now clear the form file input by setting the v-model to null or an empty string.

The watcher checks for null and empty string and internally calls reset()

* Update form-file.js

* Update README.md
  • Loading branch information
tmorehouse committed Nov 14, 2018
1 parent 69421ca commit ab44375
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 17 deletions.
41 changes: 26 additions & 15 deletions src/components/form-file/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,24 +145,27 @@ assitive technologies.


## Clearing the file selection
Because of limitations in the value binding with `<input type="file">` elements, `v-model`
for `<b-form-file>` is unidirectional, and cannot be used to set or clear the file(s) selection.
To get around this limitation, `<b-form-file>` provides a `reset()` method that can be
called to clear the file input.
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`, an empty string, or an
empty array).

To take advantage of the `reset()` method, you will need to obtain a reference
to the `<b-form-file>` component:
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
<div id="#app">
<b-form-file v-model="file" ref="fileinput"></b-form-file>
<b-button @click="clearFiles">Reset</b-button>
</div>
```
<template>
<div>
<b-form-file v-model="file" ref="fileinput" 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>

```js
window.app = new Vue({
el: '#app',
<script>
export default {
data () {
return {
file: null
Expand All @@ -173,8 +176,16 @@ window.app = new Vue({
this.$refs.fileinput.reset();
}
}
})
}
</script>

<!-- 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 back
to type file.


<!-- Component reference added automatically from component package.json -->
17 changes: 15 additions & 2 deletions src/components/form-file/form-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import idMixin from '../../mixins/id'
import formMixin from '../../mixins/form'
import formStateMixin from '../../mixins/form-state'
import formCustomMixin from '../../mixins/form-custom'
import { from as arrayFrom } from '../../utils/array'
import { from as arrayFrom, isArray } from '../../utils/array'

// temporary css until Bootstrap V4.2 is released
import './form-file.css'
Expand Down Expand Up @@ -36,7 +36,8 @@ export default {
on: {
change: this.onFileChange,
focusin: this.focusHandler,
focusout: this.focusHandler
focusout: this.focusHandler,
reset: this.onReset
}
})

Expand Down Expand Up @@ -80,6 +81,9 @@ export default {
}
},
props: {
value: {
default: null
},
accept: {
type: String,
default: ''
Expand Down Expand Up @@ -152,6 +156,11 @@ export default {
} else {
this.$emit('input', newVal)
}
},
value (newVal) {
if (!newVal || (isArray(newVal) && newVal.length === 0)) {
this.reset()
}
}
},
methods: {
Expand Down Expand Up @@ -216,6 +225,10 @@ export default {
this.selectedFile = files[0]
}
},
onReset () {
// Triggered when the parent form (if any) is reset
this.selectedFile = this.multiple ? [] : null
},
onDragover (evt) {
evt.preventDefault()
evt.stopPropagation()
Expand Down

0 comments on commit ab44375

Please sign in to comment.