Asle G
Asle G

Reputation: 588

How to handle date format with DateTimePicker and knockout-observable?

I am struggling with datetimepicker and data formatting. My date time is stored in this format: "yyyy-mm-ddTHH:MM:ss.000".

If I'm not formatting, my date datetimepicker misprints it. If I do format it, I get an error from my bindingHandlers:

[Error] TypeError: 09.04.2016 19:24:48 is not a function (evaluating 'observable($(element).val())')

I feel like I'm catching some deadlock here, but surely there must be a way around it?

HTML:

<input  type="text" data-bind="datetimepicker:viewWhenDateTime,datetimepickerOptions:{dateFormat:'dd.mm.yy',timeFormat:'HH:mm:ss',addSliderAccess:true,sliderAccessArgs:{touchonly:false}}" />

JavaScript:

function ViewModel() {
   var self = this;
   self.whenDateTime = ko.observable("2016-04-09T19:24:48.000");
   self.viewWhenDateTime = self.whenDateTime().parseDate();
}

BindingHandlers:

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

        //handle the field changing
        ko.utils.registerEventHandler(element, "change", function () {
            var observable = valueAccessor();
            observable($(element).val());
        });

        //handle disposal (if KO removes by the template binding)
        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            $(element).datetimepicker("destroy");
        });

    },
    update: function (element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor()),
        current = $(element).val();
        if (value - current !== 0) {
            $(element).datetimepicker("setDate", value);
        }
    }
};

Fiddle here: http://jsfiddle.net/AsleG/nrsathdg/

Upvotes: 2

Views: 852

Answers (1)

Jeroen
Jeroen

Reputation: 63810

Your binding handler is two-way: it'll try to update the thing passed to it as if it were an observable. However, your viewWhenDateTime bound to it is not observable.

Given that

  1. viewWhenDateTime is dependent on another observable; and
  2. viewWhenDateTime will be bound using a two-way binding handler

you'll probably need a writeable observable.

Something along these lines:

function ViewModel() {
   var self = this;
   self.whenDateTime = ko.observable("2016-04-09T19:24:48.000");
   self.viewWhenDateTime = ko.computed({
     read: function() { return self.whenDateTime().parseDate(); },
     write: function(newVal) {
       // Do the inverse of `parseDate` here
       // and set it to self.whenDateTime(....)
     }
   });
}

Upvotes: 1

Related Questions