Hoa
Hoa

Reputation: 20438

In Vue.js, how can I get an event to fire in a select when the displayed element is chosen?

Here is an example fiddle:

https://jsfiddle.net/40fxcuqd/

Initially, it displays "Carl"

If I select Carol, Clara etc, then an event will fire and data will print to the console.

But if I click the dropdown and choose "Carl", no event will fire, and nothing will print to the console.

The event I'm using is @input:

<select v-model="selectedPerson" @input="myEvent()">

How can I get an event to fire every time something is selected, even if it's the same value?

Edit:

To clarify, when "Carl" is initially selected:

enter image description here

and then the dropdown is opened:

enter image description here

and then Carl is selected again, I would like an event to be triggered and a print to the console. My issue at the moment is no event is triggered, and nothing prints to the console.

Upvotes: 3

Views: 1403

Answers (4)

shrys
shrys

Reputation: 5940

Really hacky but does the job, I've used @click and event.detail or event.which:

new Vue({
  el: '#app',
  template: `
        <div>
            <select v-model="selectedPerson" @input="myEvent($event)" @click="myEvent($event)">
                <option v-for="person in people" :value="person.key" :selected="person.key == selectedPerson">{{person.name}}</option>
            </select>
        </div>
    `,
  data: {
    people: [{
        key: 1,
        name: "Carl"
      },
      {
        key: 2,
        name: "Carol"
      },
      {
        key: 3,
        name: "Clara"
      },
      {
        key: 4,
        name: "John"
      },
      {
        key: 5,
        name: "Jacob"
      },
      {
        key: 6,
        name: "Mark"
      },
      {
        key: 7,
        name: "Steve"
      }
    ],
    selectedPerson: 1
  },
  methods: {
    myEvent: function(e) {
      if (e.detail == 0)//if (e.which == 0)
        console.log(e.type, this.selectedPerson);
    }
  }
});
body {
  margin: 20px;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.as-console-wrapper {
  height: 39px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
<div id="app"></div>

A less hacky way using data:

new Vue({
  el: '#app',
  template: `
        <div>
            <select v-model="selectedPerson" @input="myEvent($event)" @click="myEvent($event)">
                <option v-for="person in people" :value="person.key" :selected="person.key == selectedPerson">{{person.name}}</option>
            </select>
        </div>
    `,
  data: {
    people: [{
        key: 1,
        name: "Carl"
      },
      {
        key: 2,
        name: "Carol"
      },
      {
        key: 3,
        name: "Clara"
      },
      {
        key: 4,
        name: "John"
      },
      {
        key: 5,
        name: "Jacob"
      },
      {
        key: 6,
        name: "Mark"
      },
      {
        key: 7,
        name: "Steve"
      }
    ],
    selectedPerson: 1,
    prev: 0,
    isChanged: false
  },
  methods: {
    myEvent: function(e) {
      if (e.type == "input" || (e.type == "click" && !this.isChanged && (this.prev == this.selectedPerson || this.prev == 0))) {
        this.isChanged = true;
        this.prev = 0;
      } else if (e.type == "click" && this.isChanged) {
        console.log(e.type, this.selectedPerson);
        this.prev = this.selectedPerson;
        this.isChanged = false;
      }
    }
  }
});
body {
  margin: 20px;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.as-console-wrapper {
  height: 39px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
<div id="app"></div>

Upvotes: 1

Jay Li
Jay Li

Reputation: 747

one workaround is to set selected to a not used value when focus, then change event will fire no matter which option is selected.

<select 
    v-model="selectedPerson" 
    ref="s" 
    @focus="selectedPerson = 0" 
    @change="myEvent()"
>

see fiddle: https://jsfiddle.net/tne1wp3q/

it's not perfect though, the change event will be fired multiple times with each click, and if no options were selected, it could left blank. Need more code to filter these behaviour.

Upvotes: 0

Christian Carrillo
Christian Carrillo

Reputation: 2761

That is because the selected option by default is 1, then nothing change when you click on Carl, you must use @change event and if you want to get Carl value when you do click should use placeholder on select option.

new Vue({
    el: '#app',
    template: `
        <div>
            <select v-model="selectedPerson" @change="myEvent()">
                <option :value="null" disabled hidden>Select option</option>
                <option v-for="person in people" :value="person.key" :selected="person.key == selectedPerson">{{person.name}}</option>
            </select>
        </div>
    `,
    data: {
        people: [
            {key: 1, name: "Carl"},
            {key: 2, name: "Carol"},
            {key: 3, name: "Clara"},
            {key: 4, name: "John"},
            {key: 5, name: "Jacob"},
            {key: 6, name: "Mark"},
            {key: 7, name: "Steve"}
        ],
        selectedPerson: null
    },
    methods: {
    myEvent: function() {
    console.log(this.selectedPerson);
    }
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>

Upvotes: 1

Anis
Anis

Reputation: 1220

when you change the dropdown you will get the index of people array and you can do something like this to get value

    myEvent: function() {
    console.log(this.people[this.selectedPerson].name);
    }
   }

Upvotes: 0

Related Questions