While building your SPA application in Durandal or Knockout
you may need your users to enter dates, such of Date Of Birth. Would it be nice
to provide a DatePicker control for the user to pick the date. In this blog I
will show you how to include a DatePicker in your durandal app and do knockout
binding.
First of all identify what DatePicker JQuery control you
want to use in your SPA application. I typically use Zurb Foundation in my
applications, hence I decided to use foundation’s DatePicker, which is based on
Bootstrap’s DatePicker. Instead of this you can use Bootstrap’s DatePicker,
JQueryUI’s DatePicker or any other DatePicker.
Once you finalized the
DatePicker, include that javascript file into the code by any mechanism, such
as script tags, bundleconfig in MVC, require AMD etc. For simplicity I am using
script tags
<script src="/Scripts/foundation/foundation-datepicker.js"></script>
Also include the
corresponding styles
<link href="/content/foundation-datepicker.css" rel=="stylesheet"></script>
In addition to the
datepicker javascript, I also use moment javascript for formatting dates. So
let’s include that script file as well
After doing this minimal
work, let’s move to Knockout where we have to tell knockout to attach our
DatePicker controller. This is done by defining our own binding attribute.
Similar to the built-in binding let’s define a custom binding called
datepicker. In this custom binding we will do the following steps
- Attach the DatePicker control to the textbox element on the init method
- Define format of the date (if needed)
- Register the change event and in that change event update the model value
- Whenever the model is updated, change the value of the DatePicker control
- Format the date using moment (if needed)
Here is the code that does
the all the above steps
ko.bindingHandlers.datepicker = {
init: function (element, valueAccessor) {
$(element).fdatepicker({ format: 'mm/dd/yyyy' });
var value = valueAccessor();
ko.utils.registerEventHandler(element,
"change", function () {
value(element.value);
});
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel)
{
var value = valueAccessor();
var mmt = moment(value());
if (mmt.isValid() === false) {
value("");
element.value = "";
}
else {
element.value = mmt.format('L');
}
}
};
As I am doing this in my
Durandal SPA, I can use composition to define the knockout binding handler as shown
below
composition.addBindingHandler('datepicker', {
//init
& update code as above
});
The above configuration is
a onetime process. After setting up the datepicker binding attribute we can use
it anyplace in our application by using the datepicker databinding attribute as
shown below
<input type="text" placeholder="" data-bind="datepicker:
DateOfBirth" />
Here is the output of our
knockout DatePicker control