Can't prevent change value of v-select component

Viewed 1239

I'm using Vuetify to render a combobox, when the user change the value of that combobox I want to display a message asking to confirm the operation, but I'm not able to prevent the change of the value if the user disagree to change the value. I tried with both input and change events.

Below the HTML:

  <v-app>
    <v-container class="indigo lighten-5">
      <v-row no-gutters>
        <v-col cols="12">
          <v-select v-model="o.selected" :items="values" @input="inputSelect"></v-select>
        </v-col>
      </v-row>
    </v-container>
  </v-app>

while the methods that listens for changes is:

    inputSelect(val) {
      console.log(val);
      if (confirm(`Do you really want to change the value to ${val}?`)) {
        console.log("ok");
        return true;
      } else {
        console.log("ko");
        return false;
      }
    }

I created a pen to reproduce the behavior.

2 Answers

This may not the best solution but after trying to make it work, I found out that the v-select always changes the value although the value inside o.selected is not changed.

So the workaround is you could reset the o.selected first then set the old value back to o.selected. I added setTimeout() to give it a wait before the code set the old value back.

  inputSelect(val) {
      // store the old value to this variable first
      let oldVal = this.o.selected

      if (confirm(`Do you really want to change to ${val}?`)) {
        this.o.selected = val;
      } else {
        // reset value to whatever value you want
        this.o.selected = '';
        // set timeout here, if no set timeout so the code on the line above will be useless
        setTimeout(() => {
          this.o.selected = oldVal;
        }, 100)
      }
      this.$forceUpdate();  
  }

I think I've found a better way of preventing a change arbitrarily with something like so:

Remove the listener from the v-select it self and add it to the template

<v-select :value="o.selected" :items="values" ref="aRef">
   <template v-slot:item="props">
        <v-list-item v-bind="props.attrs" @click="inputSelect(props.item)">
            <v-list-item-content>
                <v-list-item-title>
                    <span>{{ props.item }}</span>
                </v-list-item-title>
            </v-list-item-content>
        </v-list-item>
    </template>
</v-select>

inputSelect(selectedVal) {
  if (confirm(`Do you really want to change the value to ${selectedVal}?`)) {
    this.o.selected = selectedVal; // set the value manually
    this.$refs.aRef.blur() // close the dropdown
  } else {
    this.$refs.aRef.blur() // just close the dropdown without setting the value
  }
}
Related