Search code examples
knockout.jskendo-uiknockout-kendo

Change kendoDatePicker value from kendoNumeric control


I have been struggling with KendoUI/Knockout integration.

My requirement:

  1. Have two KendoUI DatePicker elements (Start and End date). End date should be readonly and should be a calculated value
  2. A KendoUI NumericTextBox element(Period) to capture month values
  3. When NumericTextBox value is inserted, it should automatically add on to the month value of the End date

My Attempt(please ignore use of tables):

HTML

<table>
    <tr>
        <td>Start Date:</td>
        <td>
            <input name="StartDate" id="StartDate" data-bind="kendoDatePicker: eventStartDate" />
        </td>
    </tr>
    <tr>
        <td>End Date:</td>
        <td>
            <input name="EndDate" id="EndDate" data-bind="kendoDatePicker: computedEndDate" />
        </td>
    </tr>
    <tr>
        <td>Event Period(months) :</td>
        <td>
            <input id="EventtPeriod" name="EventPeriod" data-bind="kendoNumericTextBox: eventPeriod" />
        </td>
    </tr>
</table>

JavaScript/ViewModel(with my dysfunctional code commented out):

    var ViewModel = function () {
        var now = new Date();

        this.eventStartDate = ko.observable(now);
        this.eventPeriod = ko.observable();
        this.computedEndDate = ko.observable( );

        /* //DOES NOT WORK
        this.computedEndDate = ko.computed(function () {
            var start = $('#StartDate').data('kendoDatePicker').value();
            var period = $('#EndDate').data('kendoNumericTextBox').value()
            var end = $('#EndDate').data('kendoDatePicker')
            end.value.setMonth(start.getMonth() + period);
            //var eventPe
            //return end;
        });
        */
    };

var vm = new ViewModel();
ko.applyBindings(vm);

JSFiddle: http://jsfiddle.net/user919426/JkgY6/4/


Solution

  • Because you are using Knockout there is no need to manually get the values from the controls you can just use the values presented in the viewmodel to calculate the end date with:

    this.computedEndDate = ko.computed(function () {
        var period = this.eventPeriod();
        var newMonth = this.eventStartDate().getMonth() + period;
        var endDate = new Date(this.eventStartDate());
        endDate.setMonth(newMonth);
        return endDate;
    }, this);
    

    Demo JSFiddle.

    Anyway your original approach wouldn't work because the KO change tracking only works with observables so your original computed does not get updated when you change the inputs.

    In order to also trigger the change also with the spinner buttons is not supported out of the box by KO-Kendo. However you can recreate the kendoNumericTextBox which can also listen to the spin event:

    Demo JSFiddle.