Format dates using Knockout JS Custom Bindings with Moment.js

I have spent the past 5 years predominantly within the Xaml arena and whilst I have appreciated the new skills I have learnt in terms of the specific technology, one of the greatest benefits to me has been the coupled approach towards design patterns synonymous with xaml. I’m talking about MVVM, composite applications, and how these, in turn, introduced me to the concepts of IOC, Repository and Unit Of work patterns. Whilst I realise these have been around for a lot longer than Xaml, the prevalence of them in the web forms arena was non-existent, at least for me at the time.

Fast forward 5 years and with MVC, I am fast rekindling my love of Not only is the base framework a significant improvement on web forms, but the explosion of complementary JS frameworks from JQuery to Knockout have really enriched the choice for web developers to pick the right tools for the job at hand.

Recently, I have been looking at Knockout and Web Api with view to minimising the number of repeated page or partial page refreshes when updating data. Using JQuery Ajax to grab data is a great way to remove the overhead of returning page details on top of the actual data itself. Coupled with knockoutjs to provide a intuitive workflow is a natural choice but my first pass demonstrated immediately the need for some formatting:


These came about from the following Knockout syntax:

   1: <tbody data-bind="foreach: companies">

   2:     <tr>

   3:         <td data-bind="text: name"></td>                    

   4:         <td data-bind="text: dateCreated"></td> 

   5:     </tr>

   6: </tbody>


In xaml, where databinding is (relatively) automatic, a simple StringFormat would provide the option here to mould the date required but using knockoutjs, one way I found to manipulate data bindings is using the custom bindings feature coupled with a suitable 3rd party framework if required. Moment.js is an excellent library for manipulating dates. Using the custom binding with knockout and providing the option to pass in a custom format string, I came up with the following:

   1: = {

   2:     update: function (element, valueAccessor, allBindingsAccessor, viewModel) {

   3:         var value = valueAccessor();

   4:         var formatString = allBindingsAccessor().formatString;

   5:         var date = moment(value());

   6:         if (formatString == null) {

   7:             $(element).text(date.format('DD/MM/YY'));

   8:         }

   9:         else {

  10:             $(element).text(date.format(formatString));

  11:         }

  12:     }

  13: };

This will look for the formatString parameter and will default to the english format of dd/mm/yy if it is not present. In my markup, I now have the following:

   1: <td data-bind="date: dateCreated, formatString: 'MM-DD-YY'"></td>                    

   2: <td data-bind="date: dateModified"></td>    

Which gives me the following output:

imageMuch cleaner, although just a start as the next step would be to think about auto-detecting current UI culture for the browser and being able to apply that as the default.

leave your comment