2

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.

alessmar
  • 4,689
  • 7
  • 43
  • 52
  • this might answer you https://stackoverflow.com/questions/42197822/vuejs-get-old-value-when-on-change-event – kusiaga Nov 19 '20 at 10:17
  • I updated my [pen](https://codepen.io/alessmar/pen/xxONOdZ), now I'm able to get the old value but I'm not able to prevent the v-select to update the new value (when the user denies to confirm the update), so the model has the old value but the v-select display the new value – alessmar Nov 20 '20 at 07:45

2 Answers2

2

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();  
  }
kusiaga
  • 673
  • 1
  • 7
  • 18
0

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
  }
}
dari0h
  • 867
  • 3
  • 10
  • 21