I've recently ported my company's project to Durandal using Knockout and JQuery. Straight to the problem: I need to initialize JQuery UI's datepicker using two HTML inputs. JQuery, however, is unable to locate the inputs when I do this:
view:
<div data-bind="if: !CurrentUser()">
<h1 data-bind="html: DisplayName"></h1>
<div data-bind="compose: 'users/_UsersList.html'"></div>
</div>
<div data-bind="with: CurrentUser(), visible: CurrentUser()">
<h1>User detail</h1>
<div data-bind="compose: 'users/_UserDetail.html'"></div>
</div>
viewmodel - SelectUser() function is called when a user is selected in the first div, then the second div and also users/_UserDetail.html is loaded:
users.SelectUser = function (user) {
users.CurrentUser(user);
/* ... */
$(function () {
$("#datepickerFrom").datetimepicker({
dateFormat: "d. m. yy",
timeFormat: "HH:mm:ss",
defaultDate: null
});
$("#datepickerTo").datetimepicker({
dateFormat: "d. m. yy",
timeFormat: "HH:mm:ss"
});
});
}
The important part of _UserDetail.html
<div class="control-group">
<label class="control-label">Active from</label>
<div class="controls">
<input type="text" data-bind="value: ActiveFrom" id="datepickerFrom" />
</div>
</div>
<div class="control-group">
<label class="control-label">Active to</label>
<div class="controls">
<input type="text" data-bind="value: ActiveTo" id="datepickerTo" />
</div>
</div>
Then the two HTML inputs come as undefined. If I change the div
with the compose
binding to the actual users/_UserDetail.html content, it works just fine, but then the view quickly becomes a mess - the html file isn't exactly small. If someone could point me to the right direction, I would be grateful. Thanks!
In this scenario you need a Knockout Binding Handler.
In some scenarios the binding handlers can have issues with the Composition lifecycle, if thats the case and you are using Durandal 2 you can use the method
composition.addBindingHandler
. Otherwise just useko.bindingHandlers
.You will need to create the bindings in the
shell.js
ormain.js
so they are available in all the application. Use the following code:And in your UI:
NOTE:
This code might not work, but you should definitely use this approach to create this kind of controls and use Durandal's composition lifecycle.
Pretty sure the problem is with this:
You have your jQuery datepicker init code inside a function. That means that it will only run when the
SelectUser
function gets called. Try moving that outside of any functions.