BLACKBELT

Ember.js

Authored by Corey Ballou

2 Comments

Adding Custom Attributes to Ember.js Form Elements

The Problem

Ember.js has a limited set of user definable attributes that can be passed in to their form controls by default. Below you will find a list of supported attributes for each form element control:

  • Ember.Button
    type, disabled, href, tabindex, id, class
  • Ember.Checkbox
    type, checked, disabled, tabindex, id, class
  • Ember.Select
    multiple, tabindex, id, class
  • Ember.TextArea
    rows, cols, id, class (as well as placeholder, disabled, maxlength, and tabindex via the Ember.TextSupport mixin)
  • Ember.TextField
    type, value, size, id, class (as well as placeholder, disabled, maxlength, and tabindex via the Ember.TextSupport mixin)

Some of the things missing include file upload attributes and the newer HTML5 form attributes which are becoming a necessity for mobile compatible websites:

  • accept
  • autocomplete
  • autofocus
  • name
  • required

For the curious, you can view the full source-code for each Ember view control via their github page in packages/ember-handlebars/lib/controls. For the rest of you, continue reading.

The Solution

Ember has made their controls easily extensible. Below you will find some common scenarios for extending the existing form controls. Please note that you should be replacing App with whatever namespace you have given your Ember application.

Ember.Button

// Method #1
Ember.Button.reopen({
    attributeBindings: ['autofocus', 'name', 'required']
});

// Method #2
App.Button = Ember.Button.extend({
    attributeBindings: ['autofocus', 'name', 'required']
});

Ember.Checkbox

// Method #1
Ember.Checkbox.reopen({
    attributeBindings: ['autofocus', 'name', 'required']
});

// Method #2
App.Checkbox = Ember.Checkbox.extend({
    attributeBindings: ['autofocus', 'name', 'required']
});

Ember.Select

// Method #1
Ember.Select.reopen({
    attributeBindings: ['autofocus', 'name', 'required']
});

// Method #2
App.Select = Ember.Select.extend({
    attributeBindings: ['autofocus', 'name', 'required']
});

Ember.TextArea

// Method #1
Ember.TextArea.reopen({
    attributeBindings: ['autofocus', 'name', 'required']
});

// Method #2
App.TextArea = Ember.TextArea.extend({
    attributeBindings: ['accept', 'autocomplete', 'autofocus', 'name', 'required']
});

Ember.TextField

// Method #1
Ember.TextField.reopen({
    attributeBindings: ['accept', 'autocomplete', 'autofocus', 'name', 'required']
});

// Method #2
App.TextField = Ember.TextField.extend({
    attributeBindings: ['accept', 'autocomplete', 'autofocus', 'name', 'required']
});

Example Usage

After you have added the necessary extension code to your JS file(s), you’ll need to tie in the form elements into your view files. Here’s a quick example:

{{view App.TextField 
    viewName="myTextField"
    name="firstname" 
    autocomplete="off" 
    valueBinding="App.content.firstname"
}}

Note that this is using the second example. If you had modified Ember.TextField directly via Ember.TextField.reopen(), you would replace App.TextField with Ember.TextField.

Author: Corey Ballou

Corey Ballou is the CEO of POP.co. Whether you're a student, young professional, entrepreneur, startup, or small business, you can be up and online fast with your own custom domain, email, and webpage on POP. Corey is a professional PHP developer by trade, specializing in custom web applications development for startups, small businesses, and agencies. Follow Corey on Twitter @cballou.

  • james

    Good writeup but Emberjs changes fast, so kindly put a dat on your Post, so that people can gauge if this might have changed baed on how far it is from the current release.

  • Tim

    Do you know the proper way of accessing one of these attribute variables from the controller? I have a ‘disabled’ attributeBinding on one of my checkboxes. I’m observing another related property in one of my controllers, and I’d like to put some logic in there that disables the checkbox. I’ve tried Ember.set(App.Checkbox, ‘disabled’, ‘disabled’) but this doesn’t seem to work.