Components.FormElement public

Subclass of Components.FormGroup that adds automatic form layout markup and form validation features.

Form layout

The appropriate Bootstrap markup for the given formLayout and controlType is automatically generated to easily create forms without coding the default Bootstrap form markup by hand:

<BsForm @formLayout="horizontal" @model={{this}} @onSubmit={{this.submit}} as |form|>
  <form.element @controlType="email" @label="Email" @value={{this.email}} />
  <form.element @controlType="password" @label="Password" @value={{this.password}} />
  <form.element @controlType="checkbox" @label="Remember me" @value={{this.rememberMe}} />
  <BsButton @defaultText="Submit" @type="primary" type="submit" />
</BsForm>

Control types

The following control types are supported out of the box:

  • Inputs (simple text, or any other HTML5 supported input types like password, email etc.)
  • Checkbox (single)
  • Radio Button (group)
  • Textarea
  • Switch (BS4 Only)

Radio Buttons

For a group of mutually exclusive radio buttons to work, you must supply the options property with an array of options, each of which will be rendered with an appropriate radio button and its label. It can be either a simple array of strings or objects. In the latter case, you would have to set optionLabelPath to the property, that contains the label on these objects.

<BsForm @model={{this}} @onSubmit={{this.submit}} as |form|>
  <form.element @controlType="radio" @label="Gender" @options={{this.genderOptions}} @optionLabelPath="title" @property="gender" />
</BsForm>

The default layout for radios is stacked, but Bootstrap's inline layout is also supported using the inline property of the yielded control component:

<BsForm @model={{this}} @onSubmit={{this.submit}} as |form|>
  <form.element @controlType="radio" @label="Gender" @options={{this.genderOptions}} @property="gender" as |el|>
    <el.control @inline={{true}} />
  </form.element>
</BsForm>

Custom controls

Apart from the standard built-in browser controls (see the controlType property), you can use any custom control simply by invoking the component with a block template. Use whatever control you might want, for example a <PikadayInput> component (from the ember-pikaday addon):

<BsForm @model={{this}} @onSubmit={{this.submit}} as |form|>
  <form.element @label="Select-2" @property="gender" as |el|>
    <PikadayInput @value={{el.value}} @onSelection={{el.setValue}} id={{el.id}} />
  </form.element>
</BsForm>

The component yields a hash with the following properties:

  • control: the component that would be used for rendering the form control based on the given controlType
  • id: id to be used for the form control, so it matches the labels for attribute
  • value: the value of the form element
  • setValue: function to change the value of the form element
  • validation: the validation state of the element, null if no validation is to be shown, otherwise 'success', 'error' or 'warning'

If you just want to customize the existing control component, you can use the aforementioned yielded control component to customize that existing component:

<BsForm @model={{this}} @onSubmit={{this.submit}} as |form|>
  <form.element @label="Email" @property="email" as |el|>
    <el.control class="input-lg" placeholder="Email" />
  </form.element>
</BsForm>

If you are using the custom control quite often, you should consider writing an integration plugin like ember-bootstrap-power-select. To do so, you need to provide a component {{bs-form/element/control/my-custom-control}} which extends Components.FormElementControl.

Form validation

In the following example the control elements of the three form elements value will be bound to the properties (given by property) of the form's model, which in this case is its controller (see model=this):

<BsForm @formLayout="horizontal" @model={{this}} @onSubmit={{this.submit}} as |form|>
  <form.element @controlType="email" @label="Email" @property="email" />
  <form.element @controlType="password" @label="Password" @property="password" />
  <form.element @controlType="checkbox" @label="Remember me" @property="rememberMe" />
  <form.submitButton>Submit</form.submitButton>
</BsForm>

By using this indirection in comparison to directly binding the value property, you get the benefit of automatic form validation, given that your model has a supported means of validating itself. See Components.Form for details on how to enable form validation.

In the example above the model was our controller itself, so the control elements were bound to the appropriate properties of our controller. A controller implementing validations on those properties could look like this:

import Ember from 'ember';
import EmberValidations from 'ember-validations';

export default Ember.Controller.extend(EmberValidations,{
  email: null,
  password: null,
  rememberMe: false,
  validations: {
    email: {
      presence: true,
      format: {
        with: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/
      }
    },
    password: {
      presence: true,
      length: { minimum: 6, maximum: 10}
    },
    comments: {
      length: { minimum: 5, maximum: 20}
    }
  }
});

If the showValidation property is true (which is automatically the case if a focusOut event is captured from the control element or the containing Components.Form was submitted with its model failing validation) and there are validation errors for the model's property, the appropriate Bootstrap validation markup (see http://getbootstrap.com/css/#forms-control-validation) is applied:

  • validation is set to 'error', which will set the has-error CSS class
  • the errorIcon feedback icon is displayed if controlType is a text field
  • the validation messages are displayed as Bootstrap help-blocks in BS3 and form-control-feedback in BS4

The same applies for warning messages, if the used validation library supports this. (Currently only ember-cp-validations)

As soon as the validation is successful again...

  • validation is set to 'success', which will set the has-success CSS class
  • the successIcon feedback icon is displayed if controlType is a text field
  • the validation messages are removed

In case you want to display some error or warning message that is independent of the model's validation, for example to display a failure message on a login form after a failed authentication attempt (so not coming from the validation library), you can use the customError or customWarning properties to do so.

HTML attributes

To set HTML attributes on the control element provided by this component when using the modern angle bracket invocation, you can pass them to the yielded control component:

<BsForm @formLayout="horizontal" @model={{this}} @onSubmit={{this.submit}} as |form|>
<form.element @controlType="email" @label="Email" @property="email" as |el|>
  <el.control
    placeholder="Email"
    tabindex={{5}}
    multiple
    required
  />
</form.element>
...
</BsForm>

controlType string public

The type of the control widget. Supported types:

  • 'text'
  • 'checkbox'
  • 'radio'
  • 'switch'
  • 'textarea'
  • any other type will use an input tag with the controlType value as the type attribute (for e.g. HTML5 input types like 'email'), and the same layout as the 'text' type

customError string public

Show a custom error message that does not come from the model's validation. Will be immediately shown, regardless of any user interaction (i.e. no focusOut event required)

customWarning string public

Show a custom warning message that does not come from the model's validation. Will be immediately shown, regardless of any user interaction (i.e. no focusOut event required). If the model's validation has an error then the error will be shown in place of this warning.

doNotShowValidationForEventTargets ?array public

Controls if validation should be shown for specified event targets.

It expects an array of query selectors. If event target is a children of an event that matches these selectors, an event triggered for it will not trigger validation errors to be shown.

By default, events fired on elements inside an input group are skipped.

If null or an empty array is passed validation errors are shown for all events regardless of event target.

formLayout string public

The form layout used for the markup generation (see http://getbootstrap.com/css/#forms):

  • 'horizontal'
  • 'vertical'
  • 'inline'

Defaults to the parent form's formLayout property.

helpText {string} public

Show a help text next to the control

horizontalLabelGridClass string public

The Bootstrap grid classes for form labels within a horizontal layout form. Defaults to the value of the same property of the parent form. The corresponding grid classes for form controls are automatically computed.

invisibleLabel boolean public

Controls label visibility by adding 'sr-only' class.

label string public

Text to display within a <label> tag.

You should include a label for every form input cause otherwise screen readers will have trouble with your forms. Use invisibleLabel property if you want to hide them.

model unknown public

The model used for validation. Defaults to the parent Components.Form's model

optionLabelPath {String} public

Property path (e.g. 'title' or 'related.name') to render the label of a selection option. See options.

options {Array} public

Array of options for control types that show a selection (e.g. radio button groups) Can be an array of simple strings or objects. For objects use optionLabelPath to specify the path containing the label.

property string public

The property name of the form element's model (by default the model of its parent Components.Form) that this form element should represent. The control element's value will automatically be bound to the model property's value.

Using this property enables form validation on this element.

showMultipleErrors {Boolean} public

Only if there is a validator, this property makes all errors to be displayed at once inside a scrollable container.

showValidationOn string|array public

Event or list of events which enable form validation markup rendering. Supported events: ['focusout', 'change', 'input']

size String public

Property for size styling, set to 'lg', 'sm' or 'xs' (the latter only for BS3)

value unknown public

The value of the control element is bound to this property:

<form.element @controlType="email" @label="Email" @value= />
            

Note two things:

  • the binding is uni-directional (DDAU), so you would have to use the onChange action to subscribe to changes.
  • you lose the ability to validate this form element by directly binding to its value. It is recommended to use the property feature instead.

onChange

public

The action is called whenever the input value is changed, e.g. by typing text

Event Payload:

  • value String

    The new value of the form control

  • model Object

    The form element's model

  • property String

    The value of property