Knockout binding for datepicker with dynamic options

2.1k views Asked by At

I am using knockout binding for jQuery date picker.

Refer to jQuery UI datepicker change event not caught by KnockoutJS

The same code is working fine except I can't set datepicker options dynamically.

How to set datepicker option (like mindate max date etc) dynamically (button click) using the the above reference link?

1

There are 1 answers

0
haim770 On BEST ANSWER

First, you need to make the options object part of your view-model. Then, upon changes, update the datePicker with the new options.

This way, you can add any of the options (like dayNames and dateFormat etc) to your options object, and the binding handler will update the component automatically.

For example (changing minDate dynamically):

var viewModel = {
    myDate: ko.observable(new Date("12/01/2013")),
    setToCurrentDate: function() {
        this.myDate(new Date());
    },
    options: {
        // make sure you're using an observable to wrap the value
        minDate: ko.observable(new Date()) 
    },
    changeMinDate: function(){
        this.options.minDate(new Date('01/01/2015'));
    }
};

And in the binding-handler (adding subscription to changes on options):

ko.bindingHandlers.datepicker = {
    init: function(element, valueAccessor, allBindingsAccessor) {
        var $el = $(element);
        var opts = allBindingsAccessor().datepickerOptions;

        //initialize datepicker with some optional options
        var options = ko.mapping.toJS(opts) || {};
        $el.datepicker(options);

        //handle the field changing
        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");
        });

        // subscribe to all changes in the options object
        ko.computed(function(){
            var options = ko.mapping.toJS(opts) || {};

            for (var i in options)
                $el.datepicker('option', i, options[i]);
        });
    },
    update: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor()),
            $el = $(element),
            current = $el.datepicker("getDate");

        if (value - current !== 0) {
            $el.datepicker("setDate", value);   
        }
    }
};

See Fiddle