svelte

Why value property on input element on svelte is not working?


I want to manage the value of a state (to make custom validations, so I won't use bind:value) to pass into my input, but the value displayed in the input is not the value I have in the a state, why happend that?

enter image description here

<script lang="ts">
  let a = "";
  const onChange = (e: any) => {
    const nv = e.target.value;
    if (nv.length <= 4) {
      a = nv;
    }
  };
</script>

<div>value:{a}</div>

<input type="text" value={a} on:input={onChange} />

Solution

  • They become out of sync since you are not using a binding and a is not being changed. The input value is only updated whenever a actually changes.

    This also means that you cannot just set a = a to force an update since no change would be detected. There are ways to work around this, e.g. setting a different intermediary value (though you then have to wait a tick for that to have an effect, which may have unintended consequences).

    If you use keydown instead of input, you could cancel that using preventDefault(). However, the input's value at the time of the event will not include the effect of the key press, yet.

    Length restriction can also be done via plain HTML:

    <input maxlength="4" />
    

    The easiest solution is probably to just set the input value manually in the event along the lines of:

    if (/* validation check */) {
      a = e.target.value;
    }
    else {
      e.target.value = a;
    }