KnockoutJS custom binding to handle ISO to UK dates


Date’s are a nightmare in code- especially when crossing technology boundaries when posting data from C# to Javascript using JSON- the ambiguity caused by the UK date format (dd/mm/yyyy… or is it mm/dd/yyyy) so I stick to using the ISO 8601 format (yyyy-mm-dd hh:mm:ss) however user’s hate this. To overcome this problem I wrote a knockout binder which keeps the view model in the ISO format but renders the date in UK format and allows the user to interact with it in this format.

Here’s the code..


ko.bindingHandlers.isoToUKDate = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var underlyingObservable = valueAccessor();

        var interceptor = ko.computed({
            read: function () {
                var momentDate = null;

                if (typeof (underlyingObservable) !== 'function')
                {
                    momentDate = moment(underlyingObservable, 'YYYY-MM-DD');
                    console.log(underlyingObservable);
                }
                else
                {
                    momentDate = moment(underlyingObservable(), 'YYYY-MM-DD');
                    console.log(underlyingObservable());
                }

                if (momentDate !== null && momentDate.isValid())
                    return momentDate.format('DD/MM/YYYY');
            },

            write: function (newValue) {
                var current = underlyingObservable(),
                    valueToWrite = moment(newValue, 'DD/MM/YYYY').format('YYYY-MM-DD');

                if (valueToWrite !== current) {
                    underlyingObservable(valueToWrite);
                    underlyingObservable.valueHasMutated();
                }
            }
        });

        ko.applyBindingsToNode(element, { value: interceptor, text: interceptor });
    }
};

It’s usage is easy…


<input data-bind="isoToUKDate: MyDate" /> <!-- A writeable form field -->
<span data-bind="isoToUKDate: MyDate" /> <!-- A read only piece of html -->

  1. No comments yet.
(will not be published)