Components.Form public
Render a form with the appropriate Bootstrap layout class (see formLayout
).
Allows setting a model
that nested Components.FormElement
s can access, and that can provide form validation (see below)
You can use whatever markup you like within the form.
However, to benefit from features such as automatic form markup, validations and validation markup, use Components.FormElement
as nested components. See below for an example.
Submitting the form
The form yields a submitButton
component, which is a preconfigured <BsButton>
with @type="primary"
and type="submit"
.
The button is disabled while a form submission is pending. Additionally, the button state is bound to the form submission state.
<BsForm as |form|>
<form.submitButton>Submit</form.submitButton>
</BsForm>
When the form is submitted (e.g. by clicking the submit button), the event will be intercepted and the onSubmit
action
will be sent to the controller or parent component.
In case the form supports validation (see "Form validation" below), the onBefore
action is called (which allows you to
do e.g. model data normalization), then the available validation rules are evaluated, and if those fail, the onInvalid
action is sent instead of onSubmit
.
Use with Components.FormElement
When using Components.FormElement
s with their property
set to property names of the form's validation enabled
model
, you gain some additional powerful features:
- the appropriate Bootstrap markup for the given
formLayout
and the form element'scontrolType
is automatically generated - markup for validation states and error messages is generated based on the model's validation (if available), when submitting the form with an invalid validation, or when focusing out of invalid inputs
<BsForm @formLayout="horizontal" @model={{this}} @onSubmit={{action "submit"}} as |form|>
<form.element @controlType="email" @label="Email" @placeholder="Email" @property="email" />
<form.element @controlType="password" @label="Password" @placeholder="Password" @property="password" />
<form.element @controlType="checkbox" @label="Remember me" @property="rememberMe" />
<form.submitButton>Submit</form.submitButton>
</BsForm>
See the Components.FormElement API docs for further information.
Form validation
All version of ember-bootstrap beginning from 0.7.0 do not come with built-in support for validation engines anymore. Instead, support is added usually by additional Ember addons, for example:
- ember-bootstrap-validations: adds support for ember-validations
- ember-bootstrap-cp-validations: adds support for ember-cp-validations
- ember-bootstrap-changeset-validations: adds support for ember-changeset
To add your own validation support, you have to:
- extend this component, setting
hasValidator
to true if validations are available (by means of a computed property for example), and implementing thevalidate
method - extend the Components.FormElement component and implement the
setupValidations
hook or simply override theerrors
property to add the validation error messages to be displayed
When validation fails, the appropriate Bootstrap markup is added automatically, i.e. the error classes are applied and the validation messages are shown for each form element. In case the validation library supports it, also warning messages are shown. See the Components.FormElement documentation for further details.
See the above-mentioned addons for examples.
The novalidate
HTML attribute is set by default for forms that have validation.
Submission state
A isSubmitting
property is yielded, which is true
after submit has been triggered and before the Promise returned
by onSubmit
is fulfilled. It could be used to show a loading spinner instead of the form while it's submitting for example:
<BsForm @onSubmit={{action "save"}} as |form|>
{{#if form.isSubmitting}}
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
Logging in...
{{else}}
<form.element @property="email" @label="email" />
<form.element @property="password" @label="password" @controlType="password" />
<form.submitButton>Login</form.submitButton>
{{/if}}
</BsForm>
Additionaly isSubmitted
and isRejected
properties are yielded. isSubmitted
is true
if last submission was successful.
isRejected
is true
if last submission was rejected due to validation errors or by an action bound to onSubmit
event, returning a rejected promise.
It could be used for visual feedback about last submission:
<BsForm @onSubmit={{action 'save}} as |form|>
<form.submitButton @type={{if form.isRejected "danger" "primary"}}>
Save
</form.submitButton>
</BsForm>
The submission state is reset as soon as any value of a form element changes. Additionally, it can be reset programmatically by
calling the yielded resetSubmissionState
function.
Note that only invoking the component in a template as shown above is considered part of its public API. Extending from it (subclassing) is generally not supported, and may break at any time.
Item Index
Properties
submit
privateSubmit handler that will send the default action ("action") to the controller when submitting the form.
If there is a supplied model
that supports validation (hasValidator
) the model will be validated before, and
only if validation is successful the default action will be sent. Otherwise, an "invalid" action will be sent, and
all the showValidation
property of all child Components.FormElement
s will be set to true, so error state and
messages will be shown automatically.
validate Promise
publicValidate hook which will return a promise that will either resolve if the model is valid or reject if it's not. This should be overridden to add validation support.
Parameters:
-
model
Object -
form
HTMLFormElement
Returns:
_element null | HTMLFormElement private
_showAllValidations boolean private
disabled boolean public
If set to true the disabled
property of all yielded form elements will be set, making their form controls disabled.
elementComponent {String} private
formLayout string public
Set the layout of the form to either "vertical", "horizontal" or "inline". See http://getbootstrap.com/css/#forms-inline and http://getbootstrap.com/css/#forms-horizontal
hasValidator boolean protected
Check if validating the model is supported. This needs to be implemented by another addon.
hideValidationsOnSubmit {Boolean} public
If true, after successful validation and upon submitting the form, all current element validations will be hidden. If the form remains visible, the user would have to focus out of elements of submit the form again for the validations to show up again, as if a fresh new form component had been rendered.
horizontalLabelGridClass string public
The Bootstrap grid classes for form labels. This is used by the Components.FormElement
class as a default for the
whole form.
isRejected {Boolean} private
isRejected
is true
if last submission was rejected.
A submission is considered as rejected if form is invalid as well as if onSubmit
rejects.
A change to any form element resets its value to false
.
If not using Components.FormElement
, resetSubmissionState
action must be triggered on each change to reset
form's submission state.
isSubmitted {Boolean} private
isSubmitted
is true
if last submission was successful.
A change to any form element resets its value to false
.
If not using Components.FormElement
, resetSubmissionState
action must be triggered on each change to reset
form's submission state.
isSubmitting {Boolean} private
isSubmitting
is true
after submit
event has been triggered and until Promise returned by onSubmit
is
fulfilled. If validate
returns a Promise that one is also taken into consideration.
If multiple concurrent submit events are fired, it stays true
until all submit events have been fulfilled.
layoutClass string protected
Bootstrap form class name (computed)
model object public
Set a model that this form should represent. This serves several purposes:
- child
Components.FormElement
s can access and bind to this model by theirproperty
- when the model supports validation by using the ember-validations mixin,
child
Components.FormElement
s will look at the validation information of theirproperty
and render their form group accordingly. Moreover, the form'ssubmit
event handler will validate the model and deny submitting if the model is not validated successfully.
<BsForm>
yields the form's model as form
property:
<BsForm @model= as |form|>
</BsForm>
pendingSubmissions {Integer} private
Count of pending submissions.
preventConcurrency Boolean public
Controls if onSubmit
action is fired concurrently. If true
submitting form multiple
times will not trigger onSubmit
action if a Promise returned by previous submission is
not settled yet.
Dropping a submission also prevents rerunning validation and onBefore
hook.
readonly boolean public
If set to true the readonly
property of all yielded form elements will be set, making their form controls read-only.
showValidations Boolean|null public
Controls visibility of validation errors. If null
(default) validation errors are shown after user
interactions like form submission, focus out event of input fields etc. If true
all validation errors are shown
immediately independently of user interactions. If false
validation errors are not shown in any case (but
prevent form submission if form is invalid).
submitButtonComponent {String} private
submitButtonState {String} private
State of the form expressed as state values expected by <BsButton>
.
submitOnEnter boolean public
If set to true pressing enter will submit the form, even if no submit button is present
onBefore
public
Action is called before the form is validated (if possible) and submitted.
Event Payload:
-
model
ObjectThe form's
model
onInvalid
public
Action is called when validation of the model has failed.
Event Payload:
-
model
ObjectThe form's
model
-
error
Object
onSubmit
public
Action is called when submit has been triggered and the model has passed all validations (if present).
Event Payload:
-
model
ObjectThe form's
model
-
result
ObjectThe returned result from the validate method, if validation is available