Search code examples
javascripthtmlvue.jscapacitor

Conditionally update attributes of INPUT element before 'click' is triggered with $refs in Vue


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)
        }
      })
    }

Solution

  • 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