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>

setupValidations

private

Setup validation properties. This method acts as a hook for external validation libraries to overwrite. In case of failed validations the errors property should contain an array of error messages.

showValidationOnHandler

private

Parameters:

  • event Event

_element null | HTMLElement private

_showValidationOn array private

ariaDescribedBy string private

ID of the helpText, used for aria-describedby attribute of the control element

controlComponent unknown private

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.

errors array protected

The array of error messages from the model's validation.

errorsComponent {String} private

feedbackIconComponent {String} private

formElementId string private

ID for input field and the corresponding label's "for" attribute

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.

hasCustomError boolean private

hasCustomWarning boolean private

hasErrors boolean private

hasValidationMessages boolean private

hasWarnings boolean private

helpText {string} public

Show a help text next to the control

helpTextComponent {String} private

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.

isValidating boolean protected

Set a validating state for async validations

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.

labelComponent {String} private

layoutComponent {String} private

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.

showAllValidations boolean private

showModelValidations boolean private

showMultipleErrors {Boolean} public

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

showOwnValidation boolean private

showValidation boolean private

If true form validation markup is rendered (requires a validatable model).

showValidationMessages boolean private

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)

validation string private

The validation ("error" (BS3)/"danger" (BS4), "warning", or "success") or null if no validation is to be shown. Automatically computed from the model's validation state.

validationMessages array private

The array of validation messages (either errors or warnings) from either custom error/warnings or , if we are showing model validation messages, the model's validation

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.

warnings array protected

The array of warning messages from the model's validation.

_onChange

private

Private duplicate of onChange event used for internal state handling between form and it's elements.

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