Norbert
Norbert

Reputation: 2771

Updating bootstrap datepicker after initialization using KnockoutJS

I'm using Bootstrap datepicker with the following custom KnockoutJS binding, which worked fine for me until now:

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

    $(element).datepicker(options);

    //when a user changes the date, update the view model
    ko.utils.registerEventHandler(element, "changeDate", function(event) {
      var value = valueAccessor();
      if (ko.isObservable(value)) {
        value(event.date);
      }                
    });
  },
  update: function(element, valueAccessor)   {
    var widget = $(element).data("datepicker");
    //when the view model is updated, update the widget
    if (widget) {
      widget.date = ko.utils.unwrapObservable(valueAccessor());
      widget.setValue();            
    }
  }

};

Now, I have a situation where I get the startDate and endDate values after the datepicker initialization takes place. I've set up an example here:

http://jsfiddle.net/6WR5r/

The datepicker is initialized with the correct dates, but when I hit the "Change Date" button, the datepicker is not updated, even though the update function on the custom binding is fired.

I've tried different versions of the update function, with no success:

update: function(element, valueAccessor, allBindingsAccessor)   {
  var options = allBindingsAccessor().datepicker || {};
  $(element).datepicker(options);
}

update: function(element, valueAccessor, allBindingsAccessor)   {
  $(element).datepicker('update');
}

The only thing that worked was using the setStartDate and setEndDate methods, like this:

update: function(element, valueAccessor, allBindingsAccessor) {
  var options = allBindingsAccessor().datepicker || {};

  $(element).datepicker('setStartDate', options.startDate);
  $(element).datepicker('setEndDate', options.endDate);
}

But I'm looking for a better approach. Is there a way to use the update function to update the datepicker with the new values, without having to specify which options to update?

Upvotes: 1

Views: 4953

Answers (1)

GôTô
GôTô

Reputation: 8053

So in two questions you make me write two ugly solutions...

Apparently you need to remove the plugin and re-create it when you want to change startDate or endDate :(

Your update function becomes:

update: function(element, valueAccessor, allBindingsAccessor) {
    console.log("update fired");

     //when the view model is updated, update the widget
    if ($(element).data("datepicker")) {
        $(element).datepicker("remove");
        var options = allBindingsAccessor().datepicker || {};
        $(element).datepicker(options);
        $(element).data("datepicker").date = ko.utils.unwrapObservable(valueAccessor());
        $(element).data("datepicker").setValue();            
    } 
}

Demo

Upvotes: 3

Related Questions