Cannot reinitialise DataTable - javascript

I'm following this link to implement server side pagination in jquery datatable.
I have index view which load partial view with jquery data table. This partial view calls asp.net-mvc controller and return json data which should be injected into jquery datatable. But on initial render of my index view I'm getting following error
DataTables warning: table id=dataTables-table - Cannot reinitialise DataTable
so I tried to add into partial view where jquery datatable is initialized
"bRetrieve": true,
but that not helped.
partial view jq. data table initialization looks like this
<script type="text/javascript">
$(document).ready(function () {
$('#dataTables-table').dataTable({
"bRetrieve": true,
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": "/MyController/MyAction",
"sServerMethod": "POST",
"aoColumns": [
{ "mDataProp": "String A" },
{ "mDataProp": "String B" },
{ "mDataProp": "String C" }],
"fnRowCallback": function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
var birthday = new Date(parseInt(aData.Birthday.replace("/Date(", "").replace(")/", ""), 10));
$('td:eq(3)', nRow).html(birthday.getMonth() + 1 + "/" + birthday.getDate() + "/" + birthday.getFullYear());
}
});
});
</script>
What I'm missing here?
Update:
[HttpPost]
public JsonResult MyAction(JQueryDataTablesModel model)
{
int totalRecordCount;
int searchRecordCount;
var data = GetMyData(model.iDisplayStart, model.iDisplayLength, model.GetSortedColumns(),
out totalRecordCount, out searchRecordCount, model.sSearch);
return Json(new JQueryDataTablesResponse<MyObject>(data, totalRecordCount, searchRecordCount, model.sEcho));
}

Try adding option:
"destroy": true.

Related

DataTable refresh button with local data not ajax

i'm using DataTables in a coldfusion project so i want to create a refresh button for my table without using ajax but by using the sent data from my CFC.
$.fn.dataTable.ext.buttons.refresh = {
text: 'Refresh'
, action: function ( e, dt, node, config ) {
dt.clear().draw();
dt.ajax.reload();
}}
var table = $(divname).dataTable({
data: data,
columns: columns,
dom: 'Bfrtip',
buttons: ['refresh'],
"oLanguage": language_datatable,
});
return table;
}

Call fnRowCallback on table redraw in datatable

I am doing some post processing in datatable in fnRowCallback. But they are not being called when the table is redrawn. (i.e, when some event like changing the number of displayed rows are called from UI, the table is redrawn)
$(document).ready(function () {
var oTable = $('#data').dataTable({
"bJQueryUI": true,
"bProcessing": true,
"bServerSide": true,
"bSort": false,
"sAjaxSource": "query.php",
"sPaginationType": "full_numbers",
"aoColumns": [
null,
null,
null,
],
"fnRowCallback": function (nRow, aData, iDisplayIndex) {
$(nRow).attr("id", aData[4]);
return nRow;
},
"fnDrawCallback": function( oSettings ) {
// How do I call fnRowCallback here?
// losing post processing because it is not being called after a redraw
}
});
I think your attempt to look up the actual row via jquery in $(nRow) does not work. nRow contains the whole row. You should just is as namespace for the jquery selector (second parameter) to restrict it to this particular row.
Like so:
$("selector",nRow).jqueryaction()
This works for me:
Html:
<tr>
<td>a</td>
<td class="boldmetight">b</td>
</tr>
<tr>
<td class="boldmetight">c</td>
<td>d</td>
</tr>.. etc
And the table definition with a rowcallback that bolds every cell with a specific class (just for example):
var otable = $("#datatable").dataTable({
"fnRowCallback": function(nRow, aData, iDisplayIndex) {
$('.boldmetight', nRow).html('<b>' + $('.boldmetight', nRow).text() + '</b>');
}
});
Look at this working Plunker

ng-click not working AngularJS and dataTables

I wrote a dataTables directive for AngularJS. Its working fine except that i trying to add an button to the row that removes an row with an ng-click.
In my opinion is that the problem occurs because the table row doesn't now the scope.
Can somebody help me out solving this problem.
jsFiddle Example: http://jsfiddle.net/A5Zvh/7/
My directive looks like this.
angular.module('DataTables', [])
.directive('datatable', function() {
return {
restrict: 'E',
transclude: true,
replace: true,
require: 'ngModel',
template: '<table></table>',
link: function(scope, element, attrs, model) {
var dataTable = null,
options;
var buttons = jQuery.parseJSON(attrs['buttons']) || null;
options = {
"bJQueryUI": false,
"sDom": "<'row-fluid'<'span4'l><'span8 filter' <'pull-right'T> <'pull-right'f>>r>t<'row-fluid'<'span6'i><'span6'p>>",
"sPaginationType": "bootstrap",
"oTableTools": {
}
};
if(_.has(attrs, 'datatableOptions')) {
jQuery.extend(true, options, scope.$eval(attrs['datatableOptions']));
}
scope.$watch(attrs.ngModel, function(data) {
if(data && _.size(data.aaData) > 0 && _.size(data.aoColumns) > 0) {
_.extend(options, scope.$eval(attrs.ngModel))
dataTable = $(element).dataTable(options);
dataTable.fnClearTable();
dataTable.fnAddData(data.aaData);
}
});
}
}
})
I'm using Angular-datatbles, and I was trying to dynamically add, Edit & Remove links to the datatble rows and display modal on ng-click;
This was the solution for my case;
$scope.dtOptions.withOption('fnRowCallback',
function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
$compile(nRow)($scope);
});
All the datatable binding code;
$scope.reloadData = function () {
$scope.dtOptions.reloadData();
};
$scope.dtColumnDefs = [
DTColumnDefBuilder.newColumnDef(2).renderWith(function (data, type, row) {
var html = '<i class="fa fa-pencil hidden-xs"></i> Edit' +
'<i class="fa fa-times hidden-xs"></i> Remove';
return html;
})
];
$scope.dtColumns = [
DTColumnBuilder.newColumn('name').withTitle('Name'),
DTColumnBuilder.newColumn('type').withTitle('Type'),
DTColumnBuilder.newColumn('id').withTitle(''),
];
$scope.dtOptions.withOption('fnRowCallback',
function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
$compile(nRow)($scope);
});
I solved this by going through each td and calling $compile. Using the datatable row callback function. Hope this helps.
options.fnCreatedCell = function (nTd, sData, oData, iRow, iCol) {
$compile(nTd)($scope);
}
//or row
options.fnCreatedRow = function( nRow, aData, iDataIndex ) {
$compile(nRow)($scope);
}
The delete function in your controller isn't called because AngularJS doesn't know anything about DataTables's insertion of those elements to the DOM, thus ngClick directive within those elements isn't compiled and linked. So change:
dataTable.fnAddData(data.aaData);
To
dataTable.fnAddData(data.aaData);
$compile(element)(scope);
And to inject $compile service:
.directive('datatable', function () {
To
.directive('datatable', function ($compile) {
And your delete function is broken in the jsFiddle, hope that's not the case in your actual project!
You might want to give a look at the first couple of Zdam's post on this Google Groups thread, especially to his/her two linked jsFiddles. I basically copied them and they work at a basic level. I have not tried yet to get some action starting from a click on a row.
I see that you implemented a slightly different approach, recreating the <table> HTML node altogether. Not sure if this is causing issues.
By the way, on the scope.$watch call I had to make sure there was a third parameter set to true, in order to make value comparison (instead of reference comparison) on the returned resource$ object. Not sure why you don't need that.
fnCreatedCell be supplied in aoColumns or fnCreatedRow supplied to mRender
1 )fnCreatedCell is column based
ex :
tableElement.dataTable({
"bDestroy": true,
oLanguage : {
sLengthMenu : '_MENU_ records per page'
},
aoColumnDefs: [
{
bSortable: false,
aTargets: [ -1,-2,-3 ],
"fnCreatedCell": function (nTd, sData, oData, iRow, iCol)
{
$compile(nTd)($scope)
}
}
],
2 ) fnCreatedRow is a 'top level' callback
tableElement.dataTable({
"bDestroy": true,
oLanguage : {
sLengthMenu : '_MENU_ records per page'
},
aoColumnDefs: [
{
bSortable: false,
aTargets: [ -1,-2,-3 ]
}
],
"fnCreatedRow": function( nRow, aData, iDataIndex ){
compile(nRow)(scope);
},

DataTables add column dynamically to table

I'm using DataTables (datatables.net) to display data from an Ajax source and having trouble customizing it. One thing I would like to do is add a column so I can have for example an 'edit' button for each row.
The closest thing to that in the examples is here but I can't get that to work with an ajax source.
Currently, I'm using the following code to display my table:
fnServerObjectToArray = function ( aElements ){
return function ( sSource, aoData, fnCallback ) {
$.ajax( {
"dataType": 'json',
"type": "POST",
"url": sSource,
"data": aoData,
"success": function (json) {
var a = [];
for ( var i=0, iLen=json.aaData.length ; i<iLen ; i++ ) {
var inner = [];
for ( var j=0, jLen=aElements.length ; j<jLen ; j++ ) {
inner.push( json.aaData[i][aElements[j]] );
}
a.push( inner );
}
json.aaData = a;
fnCallback(json);
}
} );
}
}
$(document).ready(function() {
$('#example').dataTable( {
"bProcessing": true,
"sAjaxSource": 'get_data.php',
"fnServerData": fnServerObjectToArray( [ 'username', 'email' ] )
} );
});
Why don't you use fnRenderFunction in the aoColumns? As an example:
aoColumns: [ { "bVisible": false} , null, null, null, null,
{ "sName": "ID",
"bSearchable": false,
"bSortable": false,
"fnRender": function (oObj) {
return "<a href='EditData.php?id=" + oObj.aData[0] + "'>Edit</a>";
}
}
]
You can use it to format the value from the server side.
See similar example on the http://jquery-datatables-editable.googlecode.com/svn/trunk/ajax-inlinebuttons.html (ignore specific settings for the editable plugin)
I've created columns with edit button and links and so on, but usually i do everything server side by custominzg the data i return and then show/hide them with the aoColumns option. I don't really understand what you are tring to achieve: display server side data as a link?
Had the same problem a few months back. This is what I did.
By no means an elegant slution, but this worked.
As you might already know, DataTables do have an overload to accept Javascript Arrays.
So I made by $.ajax call. got my json, parsed it to a javascript array and then while parsing I created an extra element (an anchor tag) with href="edit.php?email=passed_email" Then on the column headers and added a column called Edit. Those values were fed to "aaData" and "aoColumns". And then the table was populated.
And BTW, if you looking for inline editing, check the following link.
DataTables editing example - with jEditableplugin
i have some RND on this problem and get this hope this will help you out.

jQuery Datatables fnRender row change

I want to add some class to row when I render a table, sample code:
$("#id").dataTable({
bProcessing: true,
sAjaxSource: com.mycompany.path.api.message[component],
aoColumns: [
{}, {},
{
sWidth: "37px",
fnRender: function(obj) {
return "<span>" + myData + "</span>";
}
}
]
});
In this example I could only control "td" tags, but I want to add some class for "tr" tag based on data that I get in fnRender() in cycle.
How I can do it with datatables?
Thanks,
Looks like in 1.7.3 available new functionality:
http://www.datatables.net/examples/advanced_init/row_callback.html

Categories