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

<b-form-input> becoming out of sync with value if using formatter #2657

Closed
kalvenschraut opened this issue Feb 19, 2019 · 17 comments · Fixed by #3172
Closed

<b-form-input> becoming out of sync with value if using formatter #2657

kalvenschraut opened this issue Feb 19, 2019 · 17 comments · Fixed by #3172

Comments

@kalvenschraut
Copy link

kalvenschraut commented Feb 19, 2019

When a form-input has a formatter on it stripping out characters in the case of trying to only allowing numerial values in a text input, the input value can sometimes not match up with the emitted value.

codepen: https://codepen.io/Kalvens/pen/Lqabrj (type any nonnumerical character in the input)
browser: Chrome Version 69.0.3497.100 (Official Build) (64-bit)
OS: linux

I believe the issue comes from

updateValue(value) {
value = this.stringifyValue(value)
if (this.localValue !== value) {
// keep the input set to the value before modifiers
this.localValue = value
if (this.number) {
// Emulate .number modifier behaviour
const num = parseFloat(value)
value = isNaN(num) ? value : num
} else if (this.trim) {
// Emulate .trim modifier behaviour
value = value.trim()
}
// Update the v-model
this.$emit('update', value)
}
},

the value is already formatted at that point so if the formatter strips out all of the characters leaving the value to be an empty string, nothing will happen even though the input still has a value set for it

I was playing around with your source code and doing

if (this.localValue !== value) {
    ...
} else if (this.$el.value !== value)  {
  this.$el.value = value;
}

seems to fix my issue, but I am not sure if that would be affecting anything else using the mixin.

@tmorehouse
Copy link
Member

Is this occurring on a browser that supports autocomplete or predictive text?

There is an issue with how some browsers handle these features. Some emit and I put for every character, while others will wait and emit a change once an autocomplete is completed or a space is entered (and inpput event may or may not be emitted with the change.

@kalvenschraut
Copy link
Author

kalvenschraut commented Feb 19, 2019

I am using chrome 69 right now, but I am typing into the input without using any autocomplete. The updateValue function is being fired correctly on key press.

The localValue could potentially not be different then the value passed into updateValue due to the formatter function. If that is the case the input's value needs to be updated to match the localValue/value param so they stay in sync.

@jacobmllr95
Copy link
Member

@tmorehouse I've looked into this a bit and I don't know why the input's value isn't changed.

@kalvenschraut
Copy link
Author

@tmorehouse is my proposed fixed as outlined earlier not what you guys are want to do? I see you added a test that seems to be similar to this issue at

it('does not update value when non-lazy formatter returns false', async () => {
const wrapper = mount(Input, {
propsData: {
value: 'abc',
formatter(value) {
return false
}
},
attachToDocument: true
})
const input = wrapper.find('input')
input.element.value = 'TEST'
input.trigger('input')
expect(wrapper.emitted('input')).not.toBeDefined()
expect(wrapper.emitted('update')).not.toBeDefined()
// value in input should remain the same as entered
expect(input.element.value).toEqual('TEST')
expect(wrapper.vm.localValue).toBe('abc')
})

Where it is asserting that the value TEST is still set as the input value. Although I am not sure if that is something you are specifically handling for when formatters return false. My issue is mainly coming from when my formatter is returning an empty string, which I think should force the input's value to also be an empty string and not to keep any characters the user may have typed into the input.

@tmorehouse
Copy link
Member

Yeah, there may need to be a few tweaks to the formatter. Lazy formatting works best (as it doesn't cause issues with cursor positioning while the user types... even google libphonenumber has dropped as you type formatting).

Typically, one could use the non lazy formatter to prevent certain characters to be type, by preventing default on the passed input event (although change events are not preventable), and then returning false so that the v-model isn't updated.

@jacobmllr95 jacobmllr95 changed the title Form Input becoming out of sync with value if using formatter <b-form-input> becoming out of sync with value if using formatter Apr 9, 2019
@skourismanolis
Copy link

I just want to point out that this bug did not exist on version 2.0.0-rc.12, I updated from that yesterday and it broke, so I'm not exactly sure what version change caused it.

jacobmllr95 added a commit that referenced this issue Apr 23, 2019
…3172)

* fix(form-input): properly handle out-of-sync values

* Update form-text.js

* Update form-text.js

* Update form-text.js
@guicapanema
Copy link

I opened a new issue but then realized this is exactly the same. This hasn't been released yet, right?

@kalvenschraut
Copy link
Author

This has not been released yet, it will when @tmorehouse is done preparing the next release candidate.
#3168

@nevadavid
Copy link

nevadavid commented Feb 3, 2020

The issue is still here, because the input's isn't change the value on predictive text.

@tmorehouse
Copy link
Member

tmorehouse commented Feb 3, 2020

@nevadavid Are you using v2.4.0?

v2.4.0 includes PR #4701 to handle out of sync values

@nevadavid
Copy link

nevadavid commented Feb 3, 2020

@tmorehouse Yes, I use this version. The input's will changes just when I press space.
Do I have to set any other property on component?

@tmorehouse
Copy link
Member

tmorehouse commented Feb 3, 2020

@nevadavid can you create a minimal reproduction (jsFiddle, CodePen, or CodeSandBox - you can export from the docs playground) to illustrate what you are experiencing and open a new issue?

@nevadavid
Copy link

@tmorehouse this is what I experience on official website: https://bootstrap-vue.js.org/docs/components/form-input
(Huawei, Android 5.1, Chrome)

@tmorehouse
Copy link
Member

I do not understand the issue you are having... can you explain more? i can type without problem into the inputs.

@nevadavid
Copy link

nevadavid commented Feb 4, 2020

@tmorehouse So when you enable the "Show correction suggestions" or similar function on your phone and type any characters on <b-form-input>, the input will changes after when I push space.

But here is my solution: https://codepen.io/nevadavid/pen/mdJbmgJ
(This is a very lightweight example, focus on the solution. For test I added a native input.)
It works well.

@tmorehouse
Copy link
Member

@nevadavid could you please open a new ticket with your issue, so we can track it?

@nevadavid
Copy link

@tmorehouse I created a new issue: #4724

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants