jQuery datatables - Index Column print/download issue - javascript

I am using a jquery datatables api index column. I've managed to make the table work by following the documentation shown on the page.
I also used the Buttons plugin to print the table, but in the "index" -- or in my case I named it "Bil" -- column, the numbers are not printed out.
The same problem occurs when I want to view the data after downloading the table in Excel and PDF.
The output when I wanted to print the table:
I don't know if it is a bug or not since I can't find the issue raised else where. I suspect the index value was only loaded to the page but is not inserted into the table. Is there a workaround to maybe use javascript to insert the value inside the table's ?
Here is the datatable's javascript that is responsible for the indexing:
//Datatable
var t = $('#tablePelajarLama').DataTable({
dom: 'lBfrtip',
buttons: [
'copy', 'excel', 'pdf', 'print'
],
"columnDefs": [ {
"searchable": false,
"orderable": false,
"targets": 0
} ],
"order": [[ 1, 'asc' ]]
});
//index counter
t.on( 'order.dt search.dt', function () {
t.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {
cell.innerHTML = i+1;
} );
} ).draw();
On a side note, I use PHP to load the data into the table if it in any way affects the process. Thanks.

SOLUTION
You need to use cell().invalidate() API method to tell DataTables to re-read the information from the DOM for the cell holding the index.
t.on( 'order.dt search.dt', function () {
t.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {
cell.innerHTML = i + 1;
t.cell(cell).invalidate('dom');
} );
} ).draw();
DEMO
See this jsFiddle for code and demonstration.

Related

How to add rows when exporting data into excel in Datatable?

I try to export my datatable into Excel.
Every time when exporting the table I want to add 3 default rows at the very top.
I saw a datatable message option but that might not help me because I want 3 rows.
Actual
Now I have this data (without any extra rows):
Expected
But I want to export data with these extra rows :
I have this code right now. and i have tried adding header with message but that didn't work for me because i need 3 header rows.
$(document).ready(function() {
var table = $('#example').DataTable( {
lengthChange: false,
buttons: [{ extend: 'pdf', className: 'btn-success' },
{ extend: 'print', className: 'btn-success' },
{ extend: 'excel', className: 'btn-success' } ]
}
}
);
table.buttons().container()
.appendTo( '#example_wrapper .col-md-6:eq(0)' );
} );
Assumed you use the button for Excel export.
You thought about the excelHtml5, Option named messageTop ?
I would rather add the 3 additional header rows via buttons.exportData( [ options ] ).
There you have an option key customizeData:
function customizeData (since Buttons 1.5.2) - Function that can be used to modify the data used for the export, after all of it has been gathered and pre-processed by the above formatting options. A single argument is passed in and no return parameter is expected (mutate the object passed in to alter the data):
Data for export. This is an object with the following properties:
header - Array of data for the header
footer - Array of data for the footer
body - 2D array of data for the body.
For example add the 3 rows to this header array:
var table = $('#myTable').DataTable();
var data = table.buttons.exportData( {
customizeData: function(dataForExport) {
dataForExport.header.push("Header line 1");
dataForExport.header.push("Header line 2");
dataForExport.header.push("Header line 3");
}
} );
// Do something with the 'data' variable

Single check box selection with jquery datatable

In jquery datatable, single check box should be selected.
This link is working fine.
But above link is using jquery.dataTables 1.10.16 version. And I am using jquery.dataTables 1.9.4.
Can the same functionality as listed in example given above be possible with jquery.dataTables 1.9.4 instead of jquery.dataTables 1.10.16?
In the same page which you give the link, there are many explanation about to using "single check" oparetion.
At the end of the listed attachment, you can see the referanced .js file is
https://cdn.datatables.net/select/1.2.5/js/dataTables.select.min.js
In your page, you should add this file referance after dataTable.js.
I think, the version of jquery is not important. The important file is "dataTables.select.js"!
Secondly, you must update your dataTable maker codes like the sample below;
$(document).ready(function() {
$('#example').DataTable( {
columnDefs: [ {
orderable: false,
className: 'select-checkbox',
targets: 0
} ],
select: {
style: 'os',
selector: 'td:first-child' // this line is the most importan!
},
order: [[ 1, 'asc' ]]
} );
} );
UPDATES :
Why dont you try to write your own selector function?
for example;
$(document).ready(function() {
$('#example').DataTable( {
/// put your options here...
} );
$('#example').find("tr").click(function(){ CheckTheRow(this); });
} );
function CheckTheRow(tr){
if($(tr).find("td:first").hasClass("selected")) return;
// get the pagination row count
var activePaginationSelected = $("#example_length").find("select").val();
// show all rows
$("#example_length").find("select").val(-1).trigger("change");
// remove the previous selection mark
$("#example").find("tr").each(function(i,a){
$(a).find("td:first").removeClass("selected");
$(a).find("td:first").html("");
});
// mark the picked row
$(tr).find("td:first").addClass("selected");
$(tr).find("td:first").html("<i class='fa fa-check'></i>");
// re turn the pagination to first stuation
$("#example_length").find("select")
.val(activePaginationSelected).trigger("change");
}
Unfortunately, legacy data table does not support or have that select extension.
Workaround:
Create checkbox element inside 'mRender' callback.
Bind action to the checkbox. (This can be done inside the fnRowCallback or outside as in my example in below fiddle
https://jsfiddle.net/Rohith_KP/dwcatt9n/1/
$(document).ready(function() {
var userData = [
["1", "Email", "Full Name", "Member"],
["2", "Email", "Full Name", "Member"]
];
var table = $('#example').DataTable({
'data': userData,
'columnDefs': [{
'targets': 0,
'className': 'dt-body-center',
'mRender': function(data, type, full, meta) {
return '<input type="checkbox" value="' + $('<div/>').text(data).html() + '">';
}
}],
'order': [1, 'asc']
});
$('#example tr').click(function() {
if ($(this).hasClass('row_selected'))
$(this).removeClass('row_selected');
else
$(this).addClass('row_selected');
});
});
Also, I suggest you to upgrade your datatable version. Then you can use that select extension.
Can the same functionality as listed in example given above be possible with jquery.dataTables 1.9.4 instead of jquery.dataTables 1.10.16?
Yes.
But, not using the Select Extension since it requires at least version 1.10.7.
For 1.9.4, a possible solution would be:
$(document).ready(function() {
$('#example').find("td input[type='checkbox']").click(function() {
selectRow(this);
});
var table = $('#example').DataTable();
function selectRow(clickedCheckBox) {
var currentPage = table.fnPagingInfo().iPage;
// Being unchecked
if (!$(clickedCheckBox).is(':checked')) {
$(clickedCheckBox).removeAttr('checked');
getRow(clickedCheckBox).removeClass('selected');
return;
}
var selectEntries = $("#example_length").find("select");
var showEntriesCount = selectEntries.val();
var totalRows = table.fnGetData().length;
// If show entries != totalRows append total rows opiton that can be selected
if (totalRows != showEntriesCount)
selectEntries.append($('<option>', {
value: totalRows,
text: totalRows
}));
// Display all rows
selectEntries.val(totalRows).trigger("change");
// Removes all checked attribute from all the rows
$("#example").find("td input[type='checkbox']").each(function(value, key) {
getRow(key).removeClass('selected');
$(key).removeAttr('checked');
});
// Check the clicked checkBox
$(clickedCheckBox).prop('checked', true);
getRow(clickedCheckBox).addClass('selected');
// Re set the show entries count
selectEntries.val(showEntriesCount).trigger("change");
// If added, Remove the additional option added to Show Entries
if (totalRows != showEntriesCount)
selectEntries.find("[value='" + totalRows + "']").remove();
// Go to the page on which the checkbox was clicked
table.fnPageChange(currentPage);
}
function getRow(element) {
return $(element).parent().parent();
}
});
The above will require fnPagingInfo to take the user back to initial page. I haven't tested the solution on large dataset, tested it on a table with 150 rows, but should work fine on larger datasets too.
JSFiddle
Have you tried below code and I checked and it is working fine, you need to update styles and scripts:
You havr to update the latest styles and scripts to achieve latest functionality.
Single check box selection with jquery datatable

jquery datatable add class to row

I have a datatable which when I click on a row, it highlights the row. I want to save the row index and use it to re-highlight that row when the page is reloaded.
var table = $('#example').DataTable( {
"ajax": "DataQueries/FetchOpenJobs.asp",
stateSave: true,
"aLengthMenu": [[10, 25, 50, 100], [10, 25, 50, 100]],
"iDisplayLength": 25,
"order": [[ 0, "desc" ]],
columnDefs: [
{"visible": false, "targets": [2,3]},
{"type": 'date-uk', "targets": [1,9,10] },
{"type": 'title-string', "targets": [11] }
],
} );
I am able to get the row index using the below:
var selectedRowIndex = table.row(this).index();
However, I am unsure as to how to re-highlight using the row index.
I think this question deserves a more thorough example.
I would save the selected id('s) in the localStorage as an stringified array. When the page is (re)loaded then retrieve the array and if it contains any stored indexes, highlight the corresponding rows. Below a code example in explanatory order :
Sample code of highlightning rows when they are clicked :
$('#example').on('click', 'tr', function() {
$(this).toggleClass('highlight');
processSelected(table.row(this).index(), $(this).hasClass('highlight'));
});
Basic code for maintaining an array of highlighted row indexes in the localStorage :
function processSelected(id, selected) {
if (selected) {
selectedRows.push(id);
} else {
selectedRows.splice(selectedRows.indexOf(id), 1);
}
localStorage.setItem('selectedRows', JSON.stringify(selectedRows));
}
When the page is loaded, retrieve the array from localStorage :
var selectedRows = JSON.parse(localStorage.getItem('selectedRows'));
Finally, re-highlight stored row indexes when the dataTable is initialised :
var table = $('#example').DataTable({
initComplete : function() {
if (!Array.isArray(selectedRows)) {
//selectedRows does not exists in localStorage or is messed up
selectedRows = [];
} else {
var _table = this.api();
selectedRows.forEach(function(index) {
//for some reason to$() doesnt work here
$(_table.row(index).node()).addClass('highlight');
})
}
}
});
demo -> http://jsfiddle.net/f3ghvz4n/
Try the demo, highlight some rows and then reload the page. Notice that this works on a paginated dataTable as well!
Update. When you are using a AJAX datasrc reloaded each 30 secs, I think you could skip the initComplete and just rely on the draw.dt event :
var table = $('#example').DataTable();
$('#example').on('draw.dt', function() {
if (!Array.isArray(selectedRows)) {
selectedRows = [];
} else {
selectedRows.forEach(function(index) {
$(table.row(index).node()).addClass('highlight');
})
}
})
Completely untested, but cannot see why it shouldnt work.
This should do the trick:
$('#id tbody > tr').eq(rowindex)
or
$('#id tbody > tr').eq(rowindex).children().addClass('myClass');

compare two columns using datatables

My goal is to highlight a row if two columns contain the same string within a row using datatables
I am not sure how would I compare two columns. I want to do something like this.
This is part of my code
"columnDefs":[
{
"targets":[3,4],
"render": function ( data, type, full, meta ) {
if value of 3 = 4 {
//highlight the row
}
}
} ],
Thanks in advance.
SOLUTION
Use rowCallback option to define a callback function that will be called when row would be drawn.
$('#example').dataTable({
"rowCallback": function(row, data, index){
if (data[3] === data[4]) {
$(row).addClass('selected');
}
}
});
DEMO
See this jsFiddle for code and demonstration.

Move (add/delete) tr rows between datatables table and plain DOM table

There are quite some answers to be found about moving rows between two datatables.
(DataTables move rows between tables).
However, doing that between one datatable and one plain DOM table has proven to be quite the struggle.
I have one Datatable:
var colcount = $("#uitschrdiv").children("thead > tr:first").children().length;
dtable = $("#uitschrdiv").dataTable({
"oLanguage": {
"sUrl": "/css/datatables/nl.txt"
},
"aoColumnDefs": [
{ "bSortable": false, "aTargets": [colcount - 1] }
],
"iDisplayLength": 25,
"aLengthMenu": [[25, 50, 100, -1], [25, 50, 100, "Alles"]],
"sPaginationType": "full_numbers",
"bStateSave": true,
"iCookieDuration": 60 * 30 /* 30min */
});
I have one normal DOM table named #inschrdiv
each of them has a button in the last td to move the row to the other table.
How to switch tr's between the two of them?
before I switched one of the tables to a datatables, this was the jQuery that would move the TR's
$(".uitschrbut").live("click", function () {
if ($(this).hasClass("inactivebtn")) {
//werkt niet
return false;
} else {
$(this).removeClass("uitschrbut").addClass("inschrbut").val("inschrijven");
$("#uitschrdiv").append($(this).parent().parent());
checkInEnUitschrMax();
}
});
$(".inschrbut").live("click", function () {
if ($(this).hasClass("inactivebtn")) {
//werkt niet
return false;
} else {
$(this).addClass("uitschrbut").removeClass("inschrbut").val("uitschrijven");
$("#inschrdiv").append($(this).parent().parent());
checkInEnUitschrMax();
}
});
this does not at all work with Datatables.
The solution took me a while before I understood that Datatables can only work with DOM objects on removing/adding and doesn't handle jQuery objects.
This is what I ended up with:
$(".uitschrbut").live("click", function () {
if ($(this).hasClass("inactivebtn")) {
//werkt niet
return false;
} else {
$(this).removeClass("uitschrbut").addClass("inschrbut").val("inschrijven");
var jrow = $(this).parents("tr");
jrow.detach(); //you need to detach this because if the datatable has a filter applied in search, it will stay in this table until the filter fits the data in this row. It would only then be moved to the datatable.
dtable.fnAddTr(jrow[0]); //used plugin, see below, jrow[0] gets the DOM of jrow
checkInEnUitschrMax();
}
});
$(".inschrbut").live("click", function () {
if ($(this).hasClass("inactivebtn")) {
//werkt niet
return false;
} else {
$(this).addClass("uitschrbut").removeClass("inschrbut").val("uitschrijven");
var row = $(this).parent().parent()[0]; //the [0] gets the native DOM elem
$("#inschrdiv tbody").append(row); //append the DOM element to the other table
dtable.fnDeleteRow(row); //delete this row from the datatable
checkInEnUitschrMax();
}
});
You will need the plugin fnAddTr which can be found here: http://datatables.net/plug-ins/api#fnAddTr
If you want to add more than one row at once you can use this plugin that allows you to apparently add whole DOM tables at once into a datatable: http://datatables.net/forums/discussion/comment/31377#Comment_31377

Categories