Search code examples
sveltesvelte-3

Bind more than one property in an element?


I'd like to have a radio button select group, with the last option being "Other:" and a text input to specify another option. I thought I would be able to do this:

<script>
    let options = ['a','b','c'];
    let selectedOption = 'a';
    let otherOption = ''
</script>

{#each options as option}
    <label>
        <input type=radio bind:group={selectedOption} name="selectedOption" value={option}>
        {option}
    </label>
{/each}
<label>
    <input type=radio name="selectedOption" 
           bind:group={selectedOption} 
           bind:value={otherOption} 
    />
    Other: 
    <input type=text bind:value={otherOption} />
</label>

{selectedOption}
<br/>
{otherOption}

The predefined options work well, the text input binds correctly to the otherOption variable, but when I select the last radio button selectedOption is undefined.

I suspect that this is because the bind:value directive is stepping over the bind:group one.

Is there an elegant way to bind both the group and the value attributes of a radio input?


Solution

  • It will be selected if you drop the unnecessary bind: of the value:

    <input type=radio name="selectedOption" 
           bind:group={selectedOption} 
           value={otherOption} />
    

    But note that the value will not be updated when you edit the field after the selection.

    A better method would be to specify a concrete value for the "other" option and just resolve the selected value differently, e.g.

    $: selected = selectedOption == 'other' ? otherOption : selectedOption;
    
    <input type=radio name="selectedOption" 
           bind:group={selectedOption} 
           value="other" />
    <!-- ... -->
    {selected}
    

    REPL