Skip to content

Commit ab44375

Browse files
authored
feat(form-file): reset file input when value set to null or empty string (#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
1 parent 69421ca commit ab44375

File tree

2 files changed

+41
-17
lines changed

2 files changed

+41
-17
lines changed

src/components/form-file/README.md

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -145,24 +145,27 @@ assitive technologies.
145145

146146

147147
## Clearing the file selection
148-
Because of limitations in the value binding with `<input type="file">` elements, `v-model`
149-
for `<b-form-file>` is unidirectional, and cannot be used to set or clear the file(s) selection.
150-
To get around this limitation, `<b-form-file>` provides a `reset()` method that can be
151-
called to clear the file input.
148+
With inputs of type file, normally the `v-model` is uni-directional (meaning
149+
you cannot pre-set the selected files). However, you can clear the file input's
150+
selected files by setting the `v-model` to either `null`, an empty string, or an
151+
empty array).
152152

153-
To take advantage of the `reset()` method, you will need to obtain a reference
154-
to the `<b-form-file>` component:
153+
Alternatively, `<b-form-file>` provides a `reset()` method that can be called to
154+
clear the file input. To take advantage of the `reset()` method, you will need
155+
to obtain a reference to the `<b-form-file>` component.
155156

156157
```html
157-
<div id="#app">
158-
<b-form-file v-model="file" ref="fileinput"></b-form-file>
159-
<b-button @click="clearFiles">Reset</b-button>
160-
</div>
161-
```
158+
<template>
159+
<div>
160+
<b-form-file v-model="file" ref="fileinput" class="mb-2"></b-form-file>
161+
<b-button @click="clearFiles" class="mr-2">Reset via method</b-button>
162+
<b-button @click="file = null">Reset via v-model</b-button>
163+
<p class="mt-2">Selected file: <b>{{ file ? file.name : ''}}</b><p>
164+
</div>
165+
</template>
162166

163-
```js
164-
window.app = new Vue({
165-
el: '#app',
167+
<script>
168+
export default {
166169
data () {
167170
return {
168171
file: null
@@ -173,8 +176,16 @@ window.app = new Vue({
173176
this.$refs.fileinput.reset();
174177
}
175178
}
176-
})
179+
}
180+
</script>
181+
182+
<!-- form-file-reset.vue -->
177183
```
178184

185+
**Implementation note:** As not all browsers allow setting a value of a file
186+
input (even to null or an empty string), `b-form-input` employs a technique that
187+
works cross-browser that involves changing the input type to null and then back
188+
to type file.
189+
179190

180191
<!-- Component reference added automatically from component package.json -->

src/components/form-file/form-file.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import idMixin from '../../mixins/id'
22
import formMixin from '../../mixins/form'
33
import formStateMixin from '../../mixins/form-state'
44
import formCustomMixin from '../../mixins/form-custom'
5-
import { from as arrayFrom } from '../../utils/array'
5+
import { from as arrayFrom, isArray } from '../../utils/array'
66

77
// temporary css until Bootstrap V4.2 is released
88
import './form-file.css'
@@ -36,7 +36,8 @@ export default {
3636
on: {
3737
change: this.onFileChange,
3838
focusin: this.focusHandler,
39-
focusout: this.focusHandler
39+
focusout: this.focusHandler,
40+
reset: this.onReset
4041
}
4142
})
4243

@@ -80,6 +81,9 @@ export default {
8081
}
8182
},
8283
props: {
84+
value: {
85+
default: null
86+
},
8387
accept: {
8488
type: String,
8589
default: ''
@@ -152,6 +156,11 @@ export default {
152156
} else {
153157
this.$emit('input', newVal)
154158
}
159+
},
160+
value (newVal) {
161+
if (!newVal || (isArray(newVal) && newVal.length === 0)) {
162+
this.reset()
163+
}
155164
}
156165
},
157166
methods: {
@@ -216,6 +225,10 @@ export default {
216225
this.selectedFile = files[0]
217226
}
218227
},
228+
onReset () {
229+
// Triggered when the parent form (if any) is reset
230+
this.selectedFile = this.multiple ? [] : null
231+
},
219232
onDragover (evt) {
220233
evt.preventDefault()
221234
evt.stopPropagation()

0 commit comments

Comments
 (0)