Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Easily build semantic forms in Ember
JavaScript Ruby
branch: master

Ember EasyForm

Build Status

EasyForm for Ember

Development on this library will be on-going until 1.0. We follow Semantic Versioning so expect backwards incompatible changes between minor version bumps. Patch version bumps will not introduce backwards incompatible changes but older minor version will not be actively supported.

Getting a build

Please choose from our list of builds for Ember-EasyForm

Building yourself

You will require Ruby to be installed on your system. If it is please run the following:

gem install bundler
git clone git://
cd ember-easyForm
bundle install
bundle exec rake dist

The builds will be in the dist/ directory.

Looking for help?

If it is a bug please open an issue on GitHub.


The form-for helper is used like so:

{{#form-for model}}
  {{input firstName}}
  {{input lastName}}
  {{input bio as="text"}}
  {{input country as='select'
       prompt="Select Country"

This will result in the following semantic structure:

  <div class="input string">
    <label for="ember1">First name</label>
    <input id="ember1" type="text"/>
    <span class="error"></span>
  <div class="input string">
    <label for="ember2">Last name</label>
    <input id="ember2" type="text"/>
    <span class="error"></span>
  <div class="input string">
    <label for="ember3">Bio</label>
    <textarea id="ember3"></textarea>
    <span class="error"></span>
  <div class="input string">
    <label for="ember4">Country</label>
    <select id="ember4">
    <span class="error"></span>

Customizing Inputs

You can customize your input by passing certain options.

{{input secret as="hidden"}}

ember-easyForm will also try to determine the type automatically based upon the property name:

{{input email}}
{{input password}}

This will set the first input with type="email" and the second with type="password"

Pass the label option to set the label text:

{{input firstName label="Your Name"}}

label could be pass as binding as well:

{{input firstName labelBinding="label"}}

where label could be a computed property defined in your controller.

label could be pass as i18n key. see i18n section.

Pass the placeholder option to set a placeholder:

{{input firstName placeholder="Enter your first name"}}

placeholder could be pass as binding as well:

{{input firstName placeholderBinding="placeholder"}}

where placeholder could be a computed property defined in your controller. prompt for select can be pass as a binding as well.

placeholder could be pass as i18n key. see i18n section.

Pass the hint option to set a hint:

{{input firstName hint="Enter your first name"}}

hint could be pass as binding as well:

{{input firstName hintBinding="hint"}}

where hint could be a computed property defined in your controller.

hint could be pass as i18n key. see i18n section.

Input Blocks

Inputs can be used in the default inline form as already seen or they can be used as blocks such as:

{{#input firstName}}
  {{input-field firstName}}{{label-field firstName}}
  {{error-field firstName}}

Inside the block you can add any markup you'd like and everything will be wrapped inside the container div that is created by the original input. You can should use the following helpers:


Renders the label field used by input. The first paramater is the property, the remainder paramaters are options.

  • text - the text for the label
{{label-field firstName text="Your first name"}}


Renders the input field used by input. The first parameter is the property, the remaining properties are options. The input itself will default a type of password if the property contains "password", likewise for "email".

  • placeholder - sets the placeholder attribute
  • as - accepts the following:
    • text - renders a textarea input
    • email
    • password
    • url
    • color
    • tel
    • search
    • hidden
    • checkbox
{{input-field bio as="text"}}
{{input-field email}}


Renders the error span used by input where the first available validation error message will be rendered. The first parameter will be the property.

{{error-field firstName}}


Renders a text containing instructions to the user. The first parameter is the property, the remaining properties are options.

  • text - the text for the hint
{{hint-field firstName text="Your first name"}}

Custom Input Types

You can register custom input types used in the as option of input. To register the custom input, use the method Ember.EasyForm.Config.registerInputType passing the name of the custom input, and its view.

Ember.EasyForm.Config.registerInputType('my_input', Ember.EasyForm.TextField);

To use the custom input, define the as option:

{{input name as=my_input}}


To customize how the form will be rendered you can use wrappers. A wrapper defines the classes used by controls, errors, labels and hints.


  • formClass - class used by the form
  • fieldErrorClass - class used by the field containing errors
  • inputClass - class used by the div containing all elements of the input (label, input, error and hint)
  • errorClass - class used by the error message
  • hintClass - class used by the hint message
  • labelClass - class used by the label
  • inputTemplate - template used by {{input}}
  • labelTemplate - template used by {{label-field}}
  • errorTemplate - template used by {{error-field}}
  • hintTemplate - template used by {{hint-field}}

Registering a wrapper

To register a wrapper, use the method Ember.EasyForm.Config.registerWrapper passing the wrapper name and its options. You can define many wrappers, using each one when appropriate.

Ember.EasyForm.Config.registerWrapper('my-wrapper', {
  formClass: 'my-form',
  errorClass: 'my-error',
  hintClass: 'my-hint',
  labelClass: 'my-label'

You can replace the default wrapper simple by registering a wrapper named default.

When you register a wrapper, you don't have to inform all options. If some option is not defined, the default value will be used.

Using a wrapper

To use a wrapper, define the wrapper option in the form. All elements inside the form will use the values defined in this wrapper.

{{#form-for controller wrapper="my-wrapper"}}
  {{input firstName}}

Default wrapper

The default wrapper contains the following values:

  • formClass - "" (empty)
  • fieldErrorClass - "fieldWithErrors"
  • inputClass - "input"
  • errorClass - "error"
  • hintClass - "hint"
  • labelClass - "" (empty)
  • inputTemplate - "easyForm/input"
  • labelTemplate - "easyForm/label"
  • errorTemplate - "easyForm/error"
  • hintTemplate - "easyForm/hint"

Custom templates

It's possible to define the templates used by inputs, labels, errors and hints. Here is an example of inputTemplate for the Bootstrap Framework v2.

First, you must register a custom wrapper or register it with the name default to replace the default wrapper:

Ember.EasyForm.Config.registerWrapper('twitter-bootstrap', {
  // Define the custom template
  inputTemplate: 'bootstrap-input',

  // Define a custom config used by the template
  controlsWrapperClass: 'controls',

  // Define the classes for the form, label, error...
  formClass: 'form-horizontal',
  fieldErrorClass: 'error',
  errorClass: 'help-inline',
  hintClass: 'help-block',
  labelClass: 'control-label',
  inputClass: 'control-group'

And then, you have to define the template used by this wrapper. In this example, the template name is bootstrap-input.

{{label-field propertyBinding="" textBinding="view.label"}}
<div class="{{unbound view.wrapperConfig.controlsWrapperClass}}">
  {{partial "easyForm/inputControls"}}

Your custom templates probably are going to be based on the templates defined by the ember-easyForm library, here you can see them.


When the focusOut event is triggered on input elements the associated model will run the validations for that property. Any error messages will appear in the associated span.error element. The containing div will also have the class .fieldWithErrors applied. When the validation passes the error message and classes are removed.

It is expected the controller have access to an errors objects (if directly defined on the controller itself or on the content object) and each key should correspond to the property in question. The value of each key can be a string or an array. If an array the first value in the array will be used for display.


When you use ember-i18n you can pass your options with a Translation suffix and ember-i18n will handle your translation.

The following options are translatable:

  • placeholder
  • label
  • hint
  • text


{{input firstName placeholderTranslation="users.attributes.firstname"}}
{{input firstName labelTranslation="users.attributes.firstname"}}
{{input firstName hintTranslation="users.hints.firstname"}}
{{input-field firstName placeholderTranslation="users.attributes.firstname"}}
{{label-field firstName textTranslation="users.attributes.firstname"}}
{{hint-field firstName textTranslation="users.hints.firstname"}}

where users.attributes.firstname is the path to the translated string.


This is partially influenced by Ember FormBuilder by Luan Haddad Ricardo dos Santos

We are very thankful for the many contributors


This library follows Semantic Versioning

Want to help?

Please do! We are always looking to improve this gem. Please see our Contribution Guidelines on how to properly submit issues and pull requests.


DockYard Inc. © 2014


Licensed under the MIT license

Something went wrong with that request. Please try again.