Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why do I need to explicitly set <input>.value to make the user-showing text in an input change?

In the following component (range.svelte) why do I have to do inputElement.value = valueToSet; at line 24 when the input element value is bound to value (<input value={value}...)? Why isn’t the assignment to value just before at line 27 sufficient?

Some more context: the idea is for the user not to be able to enter a number outside of the range in the "number" type input.

<script lang="ts">
    import { RangeSlider } from '@skeletonlabs/skeleton';

    export let value: number;
    export let suffix: string;
    export let min: number;
    export let max: number;

    export let name: string;
    export let step: number = 1;

    let clazz: string = ""

    export {clazz as class};

    function onInputChanged(event: Event): void {
        const inputElement = event.target;

        const newValue = inputElement.value;

        const valueToSet = computeValueToSet(newValue);

        value = valueToSet
        inputElement.value = valueToSet;
    }

    function computeValueToSet(newValue: string): number {
        if (newValue === "") {
            return value;
        }

        const newInt = parseInt(newValue, 10);

        const isInRange = min <= newInt && newInt <= max;
        if (!isInRange) {
            return value;
        }

        return newInt;
    }
</script>

<div class="flex flex-row gap-4 {clazz}" {...$$restProps}>
    <RangeSlider name={name} class="basis-3/4" bind:value {min} {max} {step}>
        <span class="flex justify-between">
            <span class="text-xs">{min}{suffix}</span>
            <span class="text-xs">{max}{suffix}</span>
        </span>
    </RangeSlider>
    <span class="basis-1/4 flex flex-row gap-1 items-center">
        <input
            class="input text-sm w-auto"
            type="number"
            value={value}
            on:input={onInputChanged}
            {min}
            {max}
            {step}
        />
        <span>{suffix}</span>
    </span>
</div>

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Svelte updates the DOM on change. If the new value is outside the valid range, you effectively set value to value, hence the state is determined to have not changed and no update is performed.

You could force an update by first invalidating the variable via a completely different value, e.g.

value = null;
value = valueToSet;

(This might only work with the reactivity model of Svelte 3/4.)

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading