zestia / ember-select-box

:capital_abcd: A faux select box for Ember apps
MIT License
64 stars 14 forks source link

Q: extending native #14

Closed basz closed 6 years ago

basz commented 6 years ago

Hello,

I'm trying to create a ember-bootstrap form control type by extending your select-box/native, which would be used as follows;

            {{form.element controlType="select-one" label=(t 'model.address.country') property="consumer.address.country" showValidation=true
                           options=countriesCollection}}

by creating a component named select-one at pods/components/bs-form/element/control/select-one this will work.

import ControlValidationMixin from 'ember-bootstrap/mixins/control-validation';
import SizeClass from 'ember-bootstrap/mixins/size-class';
import SelectBoxControl from 'ember-select-box/components/select-box/native';

export default SelectBoxControl.extend({
  classTypePrefix: 'form-control',
  classNames: ['form-control'],
  actions: {
    select(value) {
      this.get('onChange')(value);
    }
  },
});

The component works as via;

                {{#bs-form/element/control/select-one as |sb|}}
                    {{#each countriesCollection as |option|}}
                        {{sb.option value=option.value label=option.label}}
                    {{/each}}
                {{/bs-form/element/control/select-one}}

However with the form.element controlType='select-one' there is now 'block'. This works thus far as I have a native select tag, which validates and has the correct classes...

Looking through your code it seems that {{sb.option ..}} registers itself as option component in the select-box via its template that has a yield statement. Since there is no hasBlock this seems not ok?

Can that be done programmatically? Am I approaching this correctly?

amk221 commented 6 years ago

I'm not familiar with ember-bootstrap, but I think what you're asking is how to create a custom component, that renders a select box, but does not have a block? If so, I think the answer would be something like this:

{{! pods/components/bs-form/element/control/select-one.hbs }}
{{label}}:
{{#select-box/native value=value on-select=(action 'onChange') as |sb|}}
  {{#each options as |option|}}
    {{#sb.option value=(get option valueKey)}}
      {{get option labelKey}}
    {{/sb.option}}
  {{/each}}
{{/select-box/native}}
{{! Usage in general }}
{{select-one
  value="France"
  onChange=(action 'selectedCountry')
  valueKey="name"
  labelKey="name"
  options=countriesCollection}}
{{! Usage with ember-bootstrap }}
{{#bs-form onSubmit=(action "submit") as |form|}}
  {{form.element
    controlType="select-one"
    label=(t 'model.address.country')
    property="consumer.address.country"
    showValidation=true
    valueKey="id"
    labelKey="name"
    options=countriesCollection}}
{{/bs-form}}

I don't think you need to extend the select box, or use any javascript at all. But I've not tested this code, and I may not understand the problem sufficiently to help.

basz commented 6 years ago

Yes, that approach I have used and it works partially. It is actually the currently recommended approach by ember-bootstrap. The problem is validation and sizing control.

With the approach above I would need to set the tagName to '' on the component and proxy many attributes to select-box. form element.disabled, readonly. classes such as form-control-sm, form-control-lg and is-valid need to be added on the