Knockout.js extender for dates in ISO 8601 format

Asp.net web api is switching to json.net for data serialization, and it seems like everyone has finally decided to support the ISO 8601 date format. Since the json spec itself doesn’t specify a particular dates format, this has historically been quite a mess.

So if you are using knockout.js on the client, then you are likely to run into issues binding ISO 8601 dates to the UI. Unfortunately,  using ISO 8601 dates in knockout.js isn’t as straight-forward as it would seem. If you just shove the ISO 8601 data into your viewmodel, you’ll get the raw ISO 8601 string displayed on screen.

This is rarely what you want.

A better solution is to have knockout.js bind the date field to the UI in a human readable and writable form, but then also expose that date in ISO 8601 format when talking to the server.

This is a perfect job for a custom knockout extender.

This fiddle shows such an extender, along with an example of  it in use.

View the full fiddle here

 

 

In this case, I decided to extend the date field itself with a computed observable called formattedDate which exposes a read/write human readable value for the date. The original date field itself is left alone to track the ISO date value. Writing to either will update the other. I’ve seen other examples that show adding the computed observable to the model itself, but I felt that it was cleaner to extend the actual field rather than have two fields on the model itself representing the same data in different ways.

Note that in producing this fiddle I grabbed a good bit of helper code from around the web (why re-invent the wheel):

  • date-format.js : this is a little script by Steven Levithan that adds a format function to the date object so you can easily convert javascript dates to various human readable formats. There are dozens of similar scripts around the net, but I personally like this one for it’s simplicity, and ability to deal with ISO 8601.
  •  Date.toISOString:  is an ECMAScript 5 method. Since not all browsers support this yet, I’ve included a tiny extension that will add this to the date object on those browsers (code taken from Mozilla).
  • Date.parse:  is an extension by Colin Snover to the standard javascript parse function that just adds support for parsing ISO 8601 formats.

For any of the functionality added by these parsing and formatting extensions, you can choose other scripts or libraries to handle those jobs.

4 Replies to “Knockout.js extender for dates in ISO 8601 format”

  1. This is a great piece of code. I seem to have troubles though. I can’t seem to be able to use the format string ‘dd/mm/yyyy’? The date is correctly formatted, but when trying to edit the date, something goes very wrong and it begins to subtract days and months, etc. Acting up really strange. Is there any workaround for this?

    Best Regards
    – Nikolaj

    1. I’d have to see the code, but it sounds like your code is interpreting the parts of the date as numbers and doing numeric operations on them. Setup an example in jsfiddle, and share the link and I can take a look.

  2. function ViewModel(now) {
    var self = this;
    self.dateOfBirth = ko.observable( now ).extend({
    isoDate: ‘m/dd/yyyy’
    });
    }
    A typing mistake.

    First name:

    Now me I have:
    self.dateOfBirth = ko.observable(now).extend({ isoDate: ‘dd-mmm-yyyy’ });

    As such when I edit my date “09-May-2012” to say “09-May-2013”:
    write: function(value) {
    if (value) {
    target(new Date(Date.parse(value)).toISOString());
    }
    }
    is bound to choke.

    Or have I got hold of the wrong end of the stick?

    1. thx, fixed it. Also fixed up the fiddle; the ko reference was a broken link.

      I’m not sure how relevant this article is. I use moment.js with knockout these days, which works out really well.

Leave a Reply

Your email address will not be published. Required fields are marked *