I have a view model that is bound to a modal popup via knockout. The modal has a button that fetches data (ajax from the server in reality but just from some static code for this example) then binds that data to a table and converts it to a DataTable. Knockout adds the DataTable.
The data gets fetched and the data table is rendered correctly. However, I need the ability to select rows by clicking on them and it seems like those databind statements aren't getting processed after fetching the data.
Here is the HTML:
<a href="#" class="btn btn-default" data-bind="click: initArray">Init Table</a>
<a href="#" class="btn btn-default" data-bind="click: swapArray">Swap Table Array</a>
<div id="datatablescontainer" style="border: 1px solid green;"></div>
<div id="datatableshidden" style="display:none;" >
<table class="datatable">
<thead>
<tr>
<th>first</th>
<th>last</th>
</tr>
</thead>
<tbody data-bind="foreach: rows">
<tr data-bind="click: $parent.testAlert">
<td align="center" data-bind="text: firstName"></td>
<td align="center" data-bind="text: lastName"></td>
</tr>
</tbody>
</table>
</div>
Here is the script:
// Here's my data model
var ViewModel = function() {
this.rows = ko.observable(null);
this.datatableinstance = null;
this.initArray = function() {
var rowsource1 = [
new ChildVM({ "firstName" : "John", "lastName" : "Smith"}),
new ChildVM({ "firstName" : "Mary", "lastName" : "Smith" })
];
this.redraw(rowsource1);
}
this.swapArray = function() {
var rowsource2 = [
new ChildVM({ "firstName" : "James", "lastName" : "Smith" }),
new ChildVM({ "firstName" : "Alice", "lastName" : "Smith" }),
new ChildVM({ "firstName" : "Doug", "lastName" : "Smith" })
];
this.redraw(rowsource2);
}
this.redraw = function(rowsource) {
this.rows(rowsource);
var options = { paging: false, "order": [[0, "desc"]], "searching":true };
var datatablescontainer = $('#datatablescontainer');
var html = $('#datatableshidden').html();
//Destroy datatable
if (this.datatableinstance) {
this.datatableinstance.destroy();
datatablescontainer.empty();
}
//Recreate datatable
datatablescontainer.html(html);
this.datatableinstance = datatablescontainer.find('table.datatable').DataTable(options);
}
this.testAlert = function() {
alert('test');
}
};
var ChildVM = function(data) {
var self = this;
if(data != null)
{
self.firstName = data.firstName;
self.lastName = data.lastName;
}
this.testAlert = function() {
alert('test');
}
}
ko.applyBindings(new ViewModel()); // This makes Knockout get to work
Here is a fiddle (customized from another post for this issue).
*Updating fiddle https://jsfiddle.net/websitewill/rgsw2odp/17/
I have testClick on the main VM and on ChildVM. I've tried with $parent.testClick and just testClick in the table row databind. Neither are called (but no errors reported either).
Thanks for any help. Will
Figured it out. Looks like calling cleanNode before applyBindings after loading the new results and creating the DataTable does the trick.Like this.
Updated fiddle here: https://jsfiddle.net/websitewill/rgsw2odp/35/
Thanks, Will