Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to clear v-model used with a select when options change

I have a cascading select (two part select) where the options in the second dropdown are determined by the value of the first dropdown. I do this by having a computed property which is based off of the first select. This then feeds the options into the second select. This mostly works fine.

The problem I'm having is if I have selected an option in the second select (which through v-model sets the value of the bound variable in Vue), and then I change the value of the first select. The options for the second select then update, and in that second select I appear to be selected to the empty option. However, the bound variable still has the previously selected value. I'm assuming this is because updating the option values for the second select doesn't actually trigger an input or change event so v-model doesn't respond to anything. I suppose I could fix this with a watcher, but I was hoping for a more elegant solution.

Coded example is here: https://codepen.io/Slotheroo/pen/ajwNKO/

JS/Vue:

new Vue({
  el: '#app',
  data: {
    selectedFruit: null,
    selectedVariety: null,
    fruits: {
      "apples": [
        {
          name: "honeycrisp",
          madeBy: "applebees",
        },
        {
          name: "macintosh",
          madeBy: "the steves",
        },
        {
          name: "gala",
          madeBy: "ac/dc",
        },
        {
          name: "pink lady",
          madeBy: "Alecia Beth Moore",
        },
      ],
      "pears": [
        {
          name: "d'anjou",
          madeBy: "Maya D'Anjoulou",
        },
        {
          name: "bartlett",
          madeBy: "Anton Yelchin",
        }
      ],
    },
  },
  computed: {
    fruitVarieties: function() {
      return this.fruits[this.selectedFruit]
    }
  },
});

HTML:

<div id="app">
  <div>
    <select v-model="selectedFruit">
      <option value=""></option>
      <option v-for="fruitName in Object.keys(fruits)" :value ="fruitName">{{fruitName}}</option>
    </select>
  </div>
  <select v-model="selectedVariety">
      <option value=""></option>
      <option v-for="fruitVariety in fruitVarieties" :value="fruitVariety">{{ fruitVariety.name }}</option>
    </select>
  <div>
  </div>
  <p>Selected variety: {{ selectedVariety }}</p>
</div>

Steps to reproduce:

  1. Select 'apples' in the first select
  2. Select 'honeycrisp' in the second select
  3. Select 'pears' or 'blank' in the first select

Hoped for result

selectedVariety returns to null

Actual result

selectedVariety still equals honeycrisp

like image 244
Slotheroo Avatar asked Jul 26 '18 03:07

Slotheroo


1 Answers

I'd add an on-change handler to the first <select> to empty the selectedVariety when the selection changes...

<select v-model="selectedFruit" @change="selectedVariety = null">

https://codepen.io/anon/pen/JByEwy


Another option would be to add a watch on selectedFruit but Vue generally recommends using event handlers.

like image 87
Phil Avatar answered Nov 15 '22 01:11

Phil