I have a simple HTML table which is bound using knockoutJS. However, I've added a custom binding which applies the jquery datatable plugin on the table.
When I click the headers, the table disappears. Any idea how I can get it working with knockoutJS?
I have a simple HTML table which is bound using knockoutJS. However, I've added a custom binding which applies the jquery datatable plugin on the table.
When I click the headers, the table disappears. Any idea how I can get it working with knockoutJS?
Share Improve this question asked Mar 23, 2012 at 9:27 jaffajaffa 27.4k51 gold badges180 silver badges293 bronze badges 2- 1 I think you need to provide some code if you expect help on this. – Mikael Östberg Commented Mar 23, 2012 at 9:30
- Its ok I figured it ok. Most examples of using dataTables with knockoutJs are not progressively enhancing existing tables. They work by using KnockoutJs to attach the dataTables data source to an ajax end-point. See my solution below. – jaffa Commented Mar 23, 2012 at 11:08
2 Answers
Reset to default 3Its actually unnecessary to use knockoutJs to carry out the binding of the dataTable. As knockoutJs already binds the HTML table to the model, just use the following:
$(function() {
var dtOptions = {
"bPaginate": false,
"bLengthChange": false,
"bFilter": false,
"bInfo": false,
bJQueryUI: true
}
var dt = $("#leadsTable").dataTable(dtOptions);
$("#searchButton").click(function() {
//... set url with search terms...
$.get(url, function (data) {
// destroy existing table
dt.fnDestroy();
ko.mapping.fromJS(data, vm.model);
// re-created AFTER ko mapping
dt.dataTable(dtOptions);
});
})
});
var serialisedModel = @Html.Raw(new JavaScriptSerializer().Serialize(Model));
var vm = {
data: ko.toJSON(serialisedModel),
}
ko.applyBindings(vm);
The crucial part is to destroy the existing dataTable before the mapping, and re-create after mapping. I had to keep a reference to the initial dataTable for later destroying...
This is the way to do it... I have made a jsfiddle showing this:
Here is a knockout custom binding solution for jQuery datatables.
ko.bindingHandlers.dataTablesForEach = {
page: 0,
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var options = ko.unwrap(valueAccessor());
ko.unwrap(options.data);
if(options.dataTableOptions.paging){
valueAccessor().data.subscribe(function (changes) {
var table = $(element).closest('table').DataTable();
ko.bindingHandlers.dataTablesForEach.page = table.page();
table.destroy();
}, null, 'arrayChange');
}
var nodes = Array.prototype.slice.call(element.childNodes, 0);
ko.utils.arrayForEach(nodes, function (node) {
if (node && node.nodeType !== 1) {
node.parentNode.removeChild(node);
}
});
return ko.bindingHandlers.foreach.init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
},
update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var options = ko.unwrap(valueAccessor()),
key = 'DataTablesForEach_Initialized';
ko.unwrap(options.data);
var table;
if(!options.dataTableOptions.paging){
table = $(element).closest('table').DataTable();
table.destroy();
}
ko.bindingHandlers.foreach.update(element, valueAccessor, allBindings, viewModel, bindingContext);
table = $(element).closest('table').DataTable(options.dataTableOptions);
if (options.dataTableOptions.paging) {
if (table.page.info().pages - ko.bindingHandlers.dataTablesForEach.page == 0)
table.page(--ko.bindingHandlers.dataTablesForEach.page).draw(false);
else
table.page(ko.bindingHandlers.dataTablesForEach.page).draw(false);
}
if (!ko.utils.domData.get(element, key) && (options.data || options.length))
ko.utils.domData.set(element, key, true);
return { controlsDescendantBindings: true };
}};
JSFiddle w/ jqueryUI
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742310158a4419728.html
评论列表(0条)