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

Allow object/reference values #31

Open
pzuraq opened this issue Mar 14, 2021 · 2 comments
Open

Allow object/reference values #31

pzuraq opened this issue Mar 14, 2021 · 2 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@pzuraq
Copy link

pzuraq commented Mar 14, 2021

Is your feature request related to a problem? Please describe.

It's fairly common to want to be able to select an object or reference to an object from a select. For instance, you may be wanting to associate a relationship with an Ember Data model. Currently, this requires a lot of boilerplate with this component, because <option> serializes the value passed to it as a string always. So, you would have to do something like:

<SelectLight
  @value={{this.selected.id}}
  @options={{this.options}}
  @valueKey="id"
  @displayKey="name"
  @change={{this.handleChange}} 
/>
class MyComponent extends Component {
  options = [{
    id: 1,
    name: "turtle",
  }, {
    id: 2,
    name: "mako",
  }];

  @tracked selected = this.options[0];

  handleChange = (event) => {
    let selectedId = event.target.selectedOptions[0].value;
    this.selected = this.options.find(option => option.id === selectedId);
  };
}

IMO this isn't as much of a performance worry because setting is not super common, but it's a lot to write for something that is pretty common in my day-to-day use cases.

Describe the solution you'd like

Ideally, it would be possible to get the selected value by reference some how. So you could do something like:

<SelectLight
  @value={{this.selected}}
  @options={{this.options}}
  @displayKey="name"
  @change={{this.handleChange}} 
/>
class MyComponent extends Component {
  options = [{
    id: 1,
    name: "turtle",
  }, {
    id: 2,
    name: "mako",
  }];

  @tracked selected = this.options[0];

  handleChange = (event) => {
    this.selected = event.target.selectedOptions[0].value;
  };
}

Or ideally, combined with #30, it could become:

<SelectLight
  @value={{this.selected}}
  @options={{this.options}}
  @displayKey="name"
  @change={{set this "selected"}} 
/>

As far as I can tell, however, this would mean that the current ability to use <option> directly wouldn't work any longer, because option values always get serialized to strings 😕 this is definitely annoying, it would mean that the API would have to pass a closure component like:

<SelectLight as |s|>
  <s.option></s.option>
</SelectLight>

This would in my opinion be worth it though, because the ability to handle references is really important, and the common use case wouldn't require using this form (you would just pass in @options instead).

Describe alternatives you've considered

We could possibly support both option and a curried component, and option could be used for string values:

<SelectLight as |s|>
  <option value="foo">Foo</option>
  <s.option @value={{this.someObj}}>Bar</s.option>
</SelectLight>

I'm not sure about this API, whether it would be more or less confusing. Also, I think it would complicate the internal logic a lot.

I'll keep thinking about if there is a way to somehow pass a reference directly into an attribute on an <option>.

@hergaiety hergaiety added help wanted Extra attention is needed enhancement New feature or request labels Mar 19, 2021
@rtablada
Copy link

We're coming from https://github.com/adopted-ember-addons/emberx-select and this is the main missing feature we're running into.

Is there any contributions out there to help move this along?

We heavily use the yielded component style API so that would be a nice API to keep available for people looking to migrate

@hergaiety
Copy link

We're coming from https://github.com/adopted-ember-addons/emberx-select and this is the main missing feature we're running into.

Is there any contributions out there to help move this along?

We heavily use the yielded component style API so that would be a nice API to keep available for people looking to migrate

Hey there @rtablada ! I'd happily welcome a PR and some assistance, I've been pretty heavily in the React world lately but I'm quite happy to review PR's and bump npm for new releases etc.

If there is no time for that, I'll see if I have time to dig into this in the future. <3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants