4

I am playing with knockout.js to add and remove fields in a form. So far it works okay, however i need a datepicker option, so i used jQuery's UI datepicker. This works, but only on the very first datepicker, not anywhere else. So whenever i click 'Add' i get new fields, but no datepicker.

I googled and seached StackExchange, but didn't find a solution on copying fields.

HTML

<table data-bind='visible: beschikkingen().length > 0'> <thead> <tr> <th>Beschikkingsdatum</th> <th>Beschikkingsnr</th> <th /> </tr> </thead> <tbody data-bind='foreach: beschikkingen'> <tr> <td><input name="beschikkingsdatum[]" type="text" class="beschikkingsdatum" value="" data-bind='value: beschikkingsdatum, uniqueName: true' /> </td> <td><input class='required number' data-bind='value: beschikkingsnummer, uniqueName: true' /></td> <td><a href='#' data-bind='click: $root.removebeschikking'>Delete</a></td> </tr> </tbody> </table> 

Knockout.JS

var beschikkingModel = function(beschikkingen) { var self = this; self.beschikkingen = ko.observableArray(beschikkingen); self.addbeschikking = function() { self.beschikkingen.push({ beschikkingsdatum: "", beschikkingsnummer: "" }); }; self.removebeschikking = function(beschikking) { self.beschikkingen.remove(beschikking); }; self.save = function(form) { alert("Could now transmit to server: " + ko.utils.stringifyJson(self.beschikkingen)); // To actually transmit to server as a regular form post, write this: ko.utils.postJson($("form")[0], self.beschikkingen); }; }; var viewModel = new beschikkingModel([ { beschikkingsdatum: "", beschikkingsnummer: "" } ]); ko.applyBindings(viewModel); // Activate jQuery Validation $("form").validate({ submitHandler: viewModel.save }); //]]> 

Datepicker

$(window).load(function(){ $('.beschikkingsdatum').datepicker({ dateFormat: 'dd-mm-yy', constrainInput: false }); }); 
1

1 Answer 1

11

Using a custom binding handler can solve your problem:

ko.bindingHandlers.datepicker = { init: function (element, valueAccessor, allBindingsAccessor) { var options = allBindingsAccessor().datepickerOptions || {}; $(element).datepicker(options); //handle the field changing ko.utils.registerEventHandler(element, "change", function () { var observable = valueAccessor(); observable($(element).datepicker("getDate")); }); //handle disposal (if KO removes by the template binding) ko.utils.domNodeDisposal.addDisposeCallback(element, function () { $(element).datepicker("destroy"); }); } }; 

And in HTML:

<input data-bind='datepicker: beschikkingsdatum' /> 

Here is the working fiddle: http://jsfiddle.net/QUxyy/

Sign up to request clarification or add additional context in comments.

6 Comments

You would likely want to also handle the update function so that changes on the view model side would be reflected in the field like in the answer to the question that he linked
Thanks! I am going to check this out. I upvoted and accepted.
The script works, thanks for that, but now two issues appear: 1. Validation acts weird. For example, it only works on the initial fields. 2. The datepicker keeps active when i click outside the field.
This works by removing the console.log It has no negative side effects.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.