Click here to Skip to main content
Click here to Skip to main content
Go to top

Bootstrap datepicker and Knockout Model Binding

, 30 May 2014
Rate this:
Please Sign up or sign in to vote.
Bootstrap datepicker and Knockout Model Binding

Introduction

Now a days, client side MVVM is a popular pattern using knockout.js. But the problem comes when we try to deal with date-time pickers and View Model binding. We can solve such problems using custom blinding handlers for knockout.

Background

I am working new with Knockout and MVVM. Everything was just fine except the date binding from a bootstrap date-time picker/ date time object send from server end. After Googling for sometime, I got a solution, which I am going to demonstrate here. Before we start, we need some .js libraries like:

  1. jquery
  2. bootstrap-datepicker
  3. knockout
  4. moment (really a good and simple js lib to deal with date time objects)

Using the Code

Let's start with the basic HTML to hold our date-time picker. Here two things are quite important:

  1. data-date-format: to point format of the date picker
  2. datepicker: which is a custom binding handler work for data binding, like value: in regular knockout
<!--date inputed from client-->       
<div>
    <label class="control-label">Date From Client</label>
    <input type="text" readonly="readonly" data-date-format="dd-mm-yyyy" class="datepicker" data-bind="datepicker: dateFromClient" />
    <span class="help-block">Date with Formate of (dd-mm-yyyy)</span>
</div>
    
<!--date from server end-->       
<div>
    <label class="control-label">Date From server</label>
    <input type="text" readonly="readonly" data-date-format="dd-mm-yyyy" class="datepicker" data-bind="datepicker: dateFromServer" />
    <span class="help-block">ClientDate - 5 days, (dd-mm-yyyy)</span>
</div> 

The custom binding handler datepicker is declared like this. We can customize it even for the jquery date time picker if we want to.

/*Date picker value binder for knockout*/
ko.bindingHandlers.datepicker = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var options = allBindingsAccessor().datepickerOptions || {};
        $(element).datepicker(options).on("changeDate", function (ev) {
            var observable = valueAccessor();
            observable(ev.date);
        });
    },
    update: function (element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        $(element).datepicker("setValue", value);
    }
}; 

Now we are going to use some utility functions to use moment.js to get current date time or to convert a server side datetime object to a given date format for client end.

/*Datetime issues with moment =>*/
function currentDate() {
    return moment();                             //sends current datetime
};

function clientDateStringFromDate(date) {
    return moment(date).format('DD-MM-YYYY');   //converts a date object to a given formate
}; 

Now here is the View model for our view:

/*View model*/
function ViewModel() {
    var self = this;
    self.dateFromClient = ko.observable(currentDate());      //set current date to date picker
    self.dateFromServer = ko.observable(currentDate());      //set current date to date picker

    self.init = function() {
        self.getServerDate();
    };

    self.getServerDate = function () {
        var json = JSON.stringify({ date: self.dateFromClient()});     //serialize json to post 
        $.ajax({
            url: '../../Services/DateTestService.asmx/GetDate',
            dataType: "json",
            contentType: 'application/json; charset=utf-8',
            type:"POST",
            data:json,
            async: true,
            processData: false,
            cache: false,
            success: function (data) {
                //alert(data.d);                                //see what type of data we get   
                var date = clientDateStringFromDate(data.d);    //convert datetime object to date string.
                self.dateFromServer(date);
            },
            error: function (xhr) {
                alert('Error to connect to server.');
            }
        });
    };

    /*date inputed from client, change event*/
    self.dateFromClient.subscribe(function(newValue) {
        self.getServerDate();
    });
}  

Now let's finish with date picker wrapper and model binding.

$(document).ready(function () {   
    //apply the datepicker to field
    $('.datepicker').datepicker();

    //model binding
    var vm = new ViewModel();
    vm.init();                       //initialize the view model
    ko.applyBindings(vm);
}); 

I have demonstrated the basic date binding here. You can find more details in the project attachment, which is a Visual Studio 2010 solution.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

diponsust

Bangladesh Bangladesh
No Biography provided

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web04 | 2.8.140926.1 | Last Updated 30 May 2014
Article Copyright 2014 by diponsust
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid