5 Comments

Ember.js Date Pickers – It’s Easy!

Ember.js can be an extremely polarizing framework. If the stars align, you can accomplish astonishing volumes of work in a short period. When you start exploring the boundaries of what’s known practice, sometimes you can get buried under a mountain of yaks that need shaving.

The application I’m currently working on has quite a few form pages. This has lead me to look some of the tougher problems in Ember like radio boxes and modal dialogs. While I’ve had exceptionally poor luck trying to get radio buttons working properly and am not unsatisfied with my current solution for modals, I had a really awesome experience adding a calendar date-picker widget with Ember.

Since we aren’t using Twitter Bootstrap, I couldn’t use the work that other people have done. Instead, I found a nice library called Pikaday that provides a relatively light-weight and dependency-free date picker. It’s even nicely style-able with CSS. I set about integrating it into Ember.js.

Since I want to bind the date picker to a form element, I chose Ember’s TextField View as a base class. This gives me all the binding magic I need, so the only thing that’s needed is to attach the picker. The perfect place for this is the “didInsertElement” event.

App.CalendarDatePicker = Ember.TextField.extend({
  _picker: null,
 
  modelChangedValue: function(){
    var picker = this.get("_picker");
    if (picker){
      picker.setDate(this.get("value"));
    }
  }.observes("value"),
 
  didInsertElement: function(){
    currentYear = (new Date()).getFullYear();
    formElement = this.$()[0];
    picker = new Pikaday({
      field: formElement,
      yearRange: [1900,currentYear+2]
    });
    this.set("_picker", picker);
  },
 
  willDestroyElement: function(){
    picker = this.get("_picker");
    if (picker) {
      picker.destroy();
    }
    this.set("_picker", null);
  }
});

You can play around with the completed example here. Despite the straightforward interface into Ember, it seems to cooperate quite well. You can manually enter dates and even paste dates. Just by adding an observer to the value property, setting properties on the model even works. If you need a custom date format out of the widget, you can use Pikaday’s excellent Moment.js support and add a “format” parameter to the Pikaday initialization.

This method of binding a standard javascript library to an ember-controlled element can be extended to other form elements. Many common jQuery libraries appear to be a glance, it should be easy to use on any number of jQuery libraries. Do you have any neat HTML form tricks to show off in Ember.js?