0

I am trying to set up a simple system that lets the user choose one of two options or neither of them. The options are both stored on the same complex object, which holds all the settings (not just those two).

I already looked at similar questions like this one: How to do something when an attribute changes in svelte
But unfortunately they don't work for my case - they react to changes of the entire object instead of just the one attribute. And even using the && syntax, as described below, works almost, but not fully. It seems perfect, as it only reacts to the value being truthy, which is what I need, but it only works one way.

Here is a simplified version of my problem:

<script>
    let object = {a: false, b: false};
    
    $: object.a && aActivated();
    $: object.b && bActivated();
    
    function aActivated(){
        object.b = false;
    }
    function bActivated(){
        object.a = false;
    }
    
</script>

<label for="a">a</label>
<input type="checkbox" bind:checked={object.a} id="a">
<label for="b">b</label>
<input type="checkbox" bind:checked={object.b} id="b">

REPL here

As you can see when you run this, a is able to deactivate b, but not the other way around.

I also tried replacing && with || and ,, but in both cases the functions would run whenever anything on the object changed, making it impossible to select either one of the options.

And no, I cannot switch to using radio buttons, because I want the users to be able to deselect both options, too.

Plagiatus
  • 360
  • 2
  • 12

1 Answers1

3

Handling the event instead of binding and reactive statements would be an option REPL

<script>
    let object = {a: false, b: false};

    function handleInput(event) {
        const checked = event.target.checked
        const key = event.target.id
        if(checked) {
            Object.keys(object).forEach(k => {
                object[k] = false               
            })
            object[key] = true  
        }else {
            object[key] = false 
        }
    }
</script>

<label for="a">a</label>
<input type="checkbox" id="a"
             checked={object.a}
             on:input={handleInput}
             >
<label for="b">b</label>
<input type="checkbox" id="b"
             checked={object.b}
             on:input={handleInput}
             >

But since switching checkboxes feel strange I would consider radio buttons with an additional one for the 'none of the others' option

Corrl
  • 6,206
  • 1
  • 10
  • 36
  • I guess that would be a way indeed. Iterating over the entire object is not really helpful in this case as it would change unrelated settings, too, but that's not a big fix. But yeah, maybe you're right and I need to re-think my selection process - radiobuttons might as well be the better choice with an additional, pre-selected option for "none of the above". – Plagiatus Apr 06 '23 at 07:27