I am using knockout to bind my data to table and on page startup everything is working fine as expected. When i changed the underlying data by calling getDataByFilter() function, datatable data get refresh by knockout and everything is working fine as well.
Thing started to corrupt when i added paging and sorting by using $('#datatable_requirement').DataTable(). Everytime when i trigger getDataByFilter() function to retrieve new data, New data keep on stack on top of the existing data and sorting and searching is not functioning anymore. Google around still can't find any solution :(
Here is my View and Viewmodel
HTML:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<a href="javascript:void(0);" data-bind="click: getDataByFilter('pass some filter set')">Get new data</a>
<table id="datatable_requirement" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th class="hasinput" style="width:17%">
<input type="text" class="form-control" placeholder="Filter Id" />
</th>
<th class="hasinput" style="width:17%">
<input type="text" class="form-control" placeholder="Filter Name" />
</th>
<th class="hasinput" style="width:16%">
<input type="text" class="form-control" placeholder="Filter Status" />
</th>
</tr>
<tr>
<th data-class="expand">Id</th>
<th>Name</th>
<th data-hide="phone">Status</th>
</tr>
</thead>
<tbody>
<!-- ko foreach: requirements -->
<tr>
<td><span data-bind="text: ReqEtpDispIdPrefix() + '-' + ReqDispId()"></span></td>
<td><span data-bind="text: ReqName"></span></td>
<td><span data-bind="text: ReqSttName"></span></td>
</tr>
<!-- /ko -->
</tbody>
</table>
</body>
</html>
JavaScript:
<script type="text/javascript">
$(document).ready(function () {
$.getJSON("/api/GetAllRequirementByFilter/", function (data){
var VM = new ViewModel(data);
ko.applyBindings(VM);
var responsiveHelper_datatable_requirement = undefined;
var otable = $('#datatable_requirement').DataTable({
"sDom": "<'dt-toolbar'<'col-xs-12 col-sm-6 hidden-xs'f><'col-sm-6 col-xs-12 hidden-xs'l>r>" +
"t" +
"<'dt-toolbar-footer'<'col-sm-6 col-xs-12 hidden-xs'i><'col-xs-12 col-sm-6'p>>",
"autoWidth": true,
"preDrawCallback": function () {
// Initialize the responsive datatables helper once.
if (!responsiveHelper_datatable_requirement) {
responsiveHelper_datatable_requirement = new ResponsiveDatatablesHelper($('#datatable_requirement'), breakpointDefinition);
}
},
"rowCallback": function (nRow) {
responsiveHelper_datatable_requirement.createExpandIcon(nRow);
},
"drawCallback": function (oSettings) {
responsiveHelper_datatable_requirement.respond();
}
});
// custom toolbar
$("div.toolbar").html('<div class="text-right"><img src="/Content/img/logo.png" alt="SmartAdmin" style="width: 111px; margin-top: 3px; margin-right: 10px;"></div>');
// Apply the filter
$("#datatable_requirement thead th input[type=text]").on('keyup change', function () {
otable
.column($(this).parent().index() + ':visible')
.search(this.value)
.draw();
});
});
})
</script>
ViewModel:
var ViewModel = function (data) {
var self = this;
self.requirements = ko.observableArray([]);
self.requirements = ko.mapping.fromJS(data);
function ajaxHelper(uri, method, data) {
self.error(''); // Clear error message
return $.ajax({
type: method,
url: uri,
dataType: 'json',
contentType: 'application/json',
data: data ? JSON.stringify(data) : null
}).fail(function (jqXHR, textStatus, errorThrown) {
self.error(errorThrown);
});
}
self.getDataByFilter = function (item)
{
ajaxHelper('/api/someapi/'+ item, 'GET').done(function (data) {
ko.mapping.fromJS(data, self.requirements);
});
}