Example: Building a date input field


#1

Here is an example for a input field with type=“date”. The goal/problem was to bind the value of the input field directly to a non-String value. In this case it’s a normal Date object.

The gist:

App.DateField = Ember.TextField.extend({
  type: 'date',
  valueBinding: 'dateValue',
  dateValue: (function(key, value) {
    if (value) {
      return this.set('date', new Date(value));
    } else {
      return (this.get('date') || new Date()).toISOString().substring(0, 10);
    }
  }).property('date')
});

It looks like sometimes there are several ways to implement stuff like this in Ember. Can you come up with another way to do this (better or worse)?

I just want to learn about different ways to do stuff.


#2

Yes, better, or at least simpler:

App.DateField = Ember.TextField.extend({
  type: 'date',
  date: function() {
    var value = this.get('value');
    if (value) {
      return new Date(value)); //You probably want to validate the date in some way
    } else {
      return null;
    }
  }.property('value')
});

#3

Nah, this way the binding does not work both ways. Or does it? http://jsbin.com/ulapuf/4/edit


#4

Missed that you wanted to be able to set date. Then try this:

App.DateField = Ember.TextField.extend({
  type: 'date',
  date: function(key, date) {
    if (date) {
      this.set('value', date.toISOString().substring(0, 10));
    } else {
      value = this.get('value');
      if (value) {
        date = new Date(value);
      } else {
        date = null;
      }
    }
    return date;
  }.property('value')
});

See example at http://jsbin.com/ulapuf/6/edit


#5

Sweet! Using the date method directly feels much better. Thanks.


#6

Here’s is another version.

I wanted something that does only change the date if the text value can be parsed by Date.parse(). As a side effect, now you can also type “2012” and it yields to “2012-01-01” on blur, which is kinda cool. – Of course this only comes into effect on browsers that do not support date input fields (like Firefox).


#7

This worked perfectly for me, thanks for the guide.