svelte
svelte copied to clipboard
Text input not updating when only the case changes
Describe the bug
If you change only the case of the first letter of the value of a textbox, it fails to update. For example if you have "Bob" and you manually type "bob" but programmatically change back to Bob, the change never appears.
Reproduction
https://svelte.dev/repl/bdb30ab3c1dd4e0bb3afd97265a03e68?version=3.49.0
Logs
No response
System Info
System:
OS: macOS 12.4
CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Memory: 3.41 GB / 32.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.14.0 - ~/.nvm/versions/node/v16.14.0/bin/node
Yarn: 1.22.17 - /opt/brew/bin/yarn
npm: 8.3.1 - ~/.nvm/versions/node/v16.14.0/bin/npm
Browsers:
Chrome: 103.0.5060.114
Firefox: 99.0.1
Safari: 15.5
Safari Technology Preview: 15.4
npmPackages:
svelte: ^3.44.0 => 3.48.0
Severity
annoyance
In your exemple you capitalise the first letter on every change so the value won't update if you upper/lower the first letter in the input.
I see what's happening, it's setting to the same value it already is, so the input.value =
gets optimized away. One workaround is to set to raw updated value first, then the programmatically altered value, as in:
https://svelte.dev/repl/435add48355b45ecba561fc9440e60c5?version=3.49.0
I guess this isn't actually a bug. Let me resolve.
You are right this is not a bug as name
never changes, you can also add a $: console.log(name)
in the script to make it even more obvious (it will only log once).
Unsetting the value first is a workaround but it will trigger unnecessary rerenders where you use that variable, it is likely better to force the input element's value itself:
<script>
let name = 'World';
function capitalize(e) {
let newName = e.currentTarget.value;
e.currentTarget.value = name = newName.slice(0, 1).toUpperCase() + newName.slice(1);
}
</script>
<h1>Hello {name}!</h1>
<input value={name} on:change|preventDefault={capitalize}>