Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Select value is not updated correctly when input handler triggers class change #6690

Closed
Frizi opened this issue Sep 25, 2017 · 4 comments

Comments

@Frizi
Copy link

@Frizi Frizi commented Sep 25, 2017

Version

2.4.4
Current chrome, safari

Reproduction link

https://jsfiddle.net/6dupwfpf/6/

Steps to reproduce

  • open provided JSFiddle
  • change select box value to "Alpha"

What is expected?

Value should be changed and "green" class applied.

What is actually happening?

"green" class is applied, but value stays unchanged.


Provided fiddle runs on version 2.4.0, but I tested it locally on 2.4.4 and it behaves exactly the same.

This report is linked to vuelidate/vuelidate#192

@LinusBorg

This comment has been minimized.

Copy link
Member

@LinusBorg LinusBorg commented Sep 26, 2017

I printed $data into the document to see what changed

https://jsfiddle.net/Linusborg/6dupwfpf/7/

  • test1 is correctly changed by v-model to 'alpha'
  • inputEvaluated correctly switches to true
  • green class is correctly applied

... what am I missing?

@posva

This comment has been minimized.

Copy link
Member

@posva posva commented Sep 26, 2017

@LinusBorg The data changes but not the DOM (if we print it in a pre tag): https://jsfiddle.net/vkrjspxy/
However, using a change event instead makes it work: https://jsfiddle.net/tec1gqv3/1

@chriscasola

This comment has been minimized.

Copy link
Contributor

@chriscasola chriscasola commented Oct 3, 2017

@LinusBorg @posva

I took a look at what's happening here.

Simpler fiddle: https://jsfiddle.net/ert66j1x/1/

I think the flow of events leading to the bug is:

  1. User changes selection
  2. input event fires (because of v-on:input)
  3. The componentUpdated function is called because the input handler updates the value of data.inputEvaluated, which reverts the selection back to the original value of the v-model binding, since vue hasn't received the change event yet
  4. The change event fires and we loop over the select options which have been reset in step 3, so we don't update the vue instance to the correct value

As far as a solution, I think we want to make sure that the v-model change event is handled before any other user added event handlers. I was thinking we could do this in normalizeEvents but I think it's only possible to reorder handlers for the same event there.

I can create a pull request but a little guidance would be helpful.

NOTE: this is not replicable in firefox unless you put breakpoints in actuallySetSelected and in the listener callback that Vue adds for input element events.

Unit test for this issue:

it('should work on an element with an input binding', done => {
  const vm = new Vue({
    data: {
      test1: '',
      inputEvaluated: ''
    },
    template:
      `<select v-model="test1" v-on:input="inputEvaluated = 'blarg'" v-bind:name="inputEvaluated">` +
        '<option value="">test1 Please Select</option>' +
        '<option value="alpha">Alpha</option>' +
        '<option value="beta">Beta</option>' +
      '</select>'
  }).$mount()
  document.body.appendChild(vm.$el)

  vm.$el.children[1].selected = true

  triggerEvent(vm.$el, 'input')

  waitForUpdate(() => {
    triggerEvent(vm.$el, 'change')
  }).then(() => {
    expect(vm.$el.value).toBe('alpha')
  }).then(done)
})
chriscasola added a commit to chriscasola/vue that referenced this issue Oct 5, 2017
Use the "input" event instead of "change" when listening for
changes to the selection state since the "input" event will
always fire before the "change" event.

This avoids an issue where a user binds to the "input" event
with "v-bind" and causes the component to update and set its
model value back to the value of the select before it has
received the new selection value.

Fixes vuejs#6690
@yyx990803

This comment has been minimized.

Copy link
Member

@yyx990803 yyx990803 commented Oct 5, 2017

FYI IE and Edge do not trigger input on <select> elements, so you should probably use change instead anyway...

yyx990803 added a commit that referenced this issue Oct 5, 2017
fix #6566, #6690
@yyx990803 yyx990803 closed this Oct 5, 2017
ztlevi added a commit to ztlevi/vue that referenced this issue Feb 14, 2018
@sodatea sodatea referenced this issue Jul 4, 2018
6 of 13 tasks complete
f2009 pushed a commit to f2009/vue that referenced this issue Jan 25, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.