I'm updating an input element's attributes conditionally, and then firing the input's click using $refs ... all in one go from a modal.
The problem is the click was firing before the attributes have changed, so i've added a 10ms setTimeout, which has solved the problem.
Surely there is a better, more Vue way of doing this though?
The input element:
<input
ref="file"
type="file"
name=""
:multiple="!androidCameraToggle"
:capture="androidCameraToggle"
:accept="[androidCameraToggle ? 'image/*' : 'image/*;capture=camera']"
style="display:none"
@change="addImage"
>
Data:
data () {
return {
androidCameraToggle: false
}
},
The modal:
async sourcePrompt() {
const swalWithBootstrapButtons = this.$swal.mixin({
customClass: {
confirmButton: 'btn btn-primary p-2',
cancelButton: 'btn btn-primary p-2'
}
})
swalWithBootstrapButtons.fire({
title: 'Upload Photo',
text: "Choose image source.",
icon: 'question',
showCancelButton: true,
confirmButtonText: 'Camera',
cancelButtonText: 'Photo Album'
}).then((result) => {
if (result.value) {
this.androidCameraToggle = true
let fileInput = this.$refs.file
setTimeout(function(){ fileInput.click()}, 10)
} else if (result.dismiss === swalWithBootstrapButtons.DismissReason.cancel) {
this.androidCameraToggle = false
let fileInput = this.$refs.file
setTimeout(function(){ fileInput.click() }, 10)
}
})
}
You can use this.$nextTick()
api.
nextTick(callback)
- The callback function will be executed after the next html update. So when you update a attribute of an html element. nextTick
will be called after the html has finished updating. It's kind of like mounted
hook but fired after every html update. So to fire your click event listener you have to pass it has callback of the nextTick
function after you update the attribute value.
You can learn more about nextTick
from the official docs