1

Using the jQuery/jQueryUI datepicker, how do I set the date format for a knockout observable that is has a data-bind on the [aforementioned] datepicker?

I have already set the format using:

<input type="text" data-bind="datepicker: ExampleDate, datepickerOptions: { datePattern: 'DD-MM-YYYY', .... }" />

But this does not reflect on the knockout variable. The date remains as the JavaScript format which cannot be interpreted by the backend, like C# .Net.

goamn
  • 1,939
  • 2
  • 23
  • 39

1 Answers1

2

Creating a knockout custombinding for datepicker will allow for this date formatting.

Amending this answer (fixing the "changeDate" error and adding the observable setter) https://stackoverflow.com/a/6613255/712700, the following will do it:

ko.bindingHandlers.datepicker = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        //initialize datepicker with some optional options
        var options = allBindingsAccessor().datepickerOptions || {},
            $el = $(element);

        $el.datepicker(options);

        //handle the field changing by registering datepicker's changeDate event
        ko.utils.registerEventHandler(element, "change", function () {
            var observable = valueAccessor();
            observable($el.datepicker("getDate"));
        });

        //handle disposal (if KO removes by the template binding)
        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            $el.datepicker("destroy");
        });
        var dateValue = $el && $el.length > 0 ? $el[0].value : undefined;
        if (dateValue) {
            valueAccessor()(dateValue);
        }
    },
    update: function (element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor()),
            $el = $(element);

        //handle date data coming via json from Microsoft
        if (String(value).indexOf('/Date(') == 0) {
            value = new Date(parseInt(value.replace(/\/Date\((.*?)\)\//gi, "$1")));
        }

        var current = $el.datepicker("getDate");

        if (value - current !== 0) {
            $el.datepicker("setDate", value);
        }
        var dateValue = $el && $el.length > 0 ? $el[0].value : undefined;
        if (dateValue) {
            valueAccessor()(dateValue);
        }
    }
};

The part which sets the knockout observable is this:

var dateValue = $el && $el.length > 0 ? $el[0].value : undefined;
if (dateValue) {
   valueAccessor()(dateValue);
}

Note also, if you are using C# .Net and you have some dates coming in (initially) from the backend to JS land, you can format your date at that time so it doesn't become the JavaScript one, and instead it will be a friendly one that the backend will accept if you happen to pass it back. This is how you would do it for Newtonsoft:

var backendSerialisedModel = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model, new Newtonsoft.Json.Converters.IsoDateTimeConverter() { DateTimeFormat = "dd-MM-yyyy" }));
goamn
  • 1,939
  • 2
  • 23
  • 39