Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More two-way binding #10

Closed
Rich-Harris opened this issue Nov 21, 2016 · 8 comments
Closed

More two-way binding #10

Rich-Harris opened this issue Nov 21, 2016 · 8 comments
Milestone

Comments

@Rich-Harris
Copy link
Member

Currently only a few <input> types are supported – need to handle textareas, selects, contenteditable, etc etc...

@timdp
Copy link

timdp commented Jan 3, 2017

How would you handle radio buttons? Knockout has something like this:

<label><input type="radio" value="Alpha" data-bind="checked: radioSelectedOptionValue" />Alpha</label>
<label><input type="radio" value="Beta" data-bind="checked: radioSelectedOptionValue" />Beta</label>
<label><input type="radio" value="Gamma" data-bind="checked: radioSelectedOptionValue" />Gamma</label>

(source)

@Garrett-
Copy link

Garrett- commented Jan 3, 2017

I would suggest setting up click event handlers on each radio button. Then have a method to be used as an event callback, sending the input element to the event callback. Bellow is an example of this.

<label><input type="radio" name="signs" on:click="select({input: this})" value="Alpha"> Alpha</label>
<label><input type="radio" name="signs" on:click="select({input: this})" value="Beta"> Beta</label>
<label><input type="radio" name="signs" on:click="select({input: this})" value="Gamma"> Gamma</label>

<script>
  export default {
    data() {
      return {};
    },

    methods: {
      select({ input }) {

        if(input.checked) {
          // do something with the selected value

          // example: trigger a component event
          this.fire('select', { value: input.value });
        }

      }
    }
  };
</script>

I know it might be confusing having a method called select and triggering an event select. Just know that they're two different things. You could listen for the select event on the component and do some action with it.

import RadioButtons from './RadioButtons.js';

var radioButtons = new RadioButtons({
  target: document.querySelector('.radios')
});

radioButtons.on('select', function({ value }) {
  console.log('Selected radio button value is', value);
});

EDIT: If all you wanted to do with the radio buttons is trigger a component event you can remove the select method all together.

<label><input type="radio" name="signs" on:click="fire('select', {value: this.value})" value="Alpha"> Alpha</label>
<label><input type="radio" name="signs" on:click="fire('select', {value: this.value})" value="Beta"> Beta</label>
<label><input type="radio" name="signs" on:click="fire('select', {value: this.value})" value="Gamma"> Gamma</label>

<script>
  export default {
    data() {
      return {};
    }
  };
</script>

@timdp
Copy link

timdp commented Jan 3, 2017

That's not two-way binding, it's just MVC.

@Garrett-
Copy link

Garrett- commented Jan 3, 2017

@timdp You're right. There isn't any two-way bindings for radio button inputs. They're not supported at this time.

@timdp
Copy link

timdp commented Jan 3, 2017

Well, my question was more about how they will be supported, since that's what this issue is about. 😄

@Garrett-
Copy link

Garrett- commented Jan 3, 2017

You could create your own radio input component. I've played around with an idea of a <RadioGroup /> component. I have not built or tested this yet. It's just an idea, I might give it a go and report back.

RadioGroup.html

{{#if radios}}
  {{#each radios as radio}}
    <label>
      <input type="radio" name="{{groupName}}" value="{{radio.value}}" on:click="select({radio: this})">
      {{radio.label}}
    </label>
  {{/each}}
{{/if}}

<script>
  export default {
    data() {
      return {
        value: '',
        group: 'group',
        radios: []
      };
    },

    methods: {
      select({ radio }) {
        if(radio.checked) {
          // Sets the value property equal to the selected radios value
          this.set({value, radio.value});
        }
      }
    }
  }
</script>

App.js

<!--
sets up a two-way binding between the RadioGroup components internal `value`
property and the App components `selectedRadioValue` property

Source: https://svelte.technology/guide#nested-components
-->
<RadioGroup value="{{selectedRadioValue}}" group="signs" radios=signRadios />

<script>
import RadioGroup from './RadioGroup.js';

export default {
  data() {
    return {
      selectedRadioValue: '',
      signRadios: [
        {
          label: 'Alpha',
          value: 'Alpha'
        },
        {
          label: 'Beta',
          value: 'Beta'
        },
        {
          label: 'Gamma',
          value: 'Gamma'
        }
      ]
    };
  }
};
</script>

@PaulBGD
Copy link
Member

PaulBGD commented Feb 11, 2017

How about binding and requiring a name for the checkboxes/radios? Then we can use the name to indicate which one is selected.

@Rich-Harris Rich-Harris added this to the ASAP milestone Feb 28, 2017
Rich-Harris added a commit that referenced this issue Feb 28, 2017
use input events for two-way binding with textareas and non-checkbox/radio inputs
@Rich-Harris
Copy link
Member Author

I'm opening individual issues for different two-way binding cases. Particularly keen to hear feedback on #311 as it pertains to the discussion above. Will close this issue in favour of the new ones. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants