I have a current jQuery DataTable in place that is functioning properly:
var $dataTable = $('#example1').DataTable({
"ajax": 'api/tableSearch.php',
"iDisplayLength": 25,
"order": [[ 6, "desc" ]],
"scrollY": 600,
"scrollX": true,
"bDestroy": true,
"columnDefs": [{
"targets": 0,
"render": function (data, type, full, meta){
return '<a class="editLink" href="#">Edit</a><a class="deleteLink" href="#">Del</a>':
}
}]
});
As stated, the above code works accordingly...the search filter works, the sorting works, everything works.
What I would like to do is add a column search to this datatable, as shown here:
https://www.datatables.net/release-datatables/examples/api/multi_filter_select.html
I attempted to add the code from the link above to my current code, as follows:
var $dataTable = $('#example1').DataTable({
"ajax": 'api/tableSearch.php',
"iDisplayLength": 25,
"order": [[ 6, "desc" ]],
"scrollY": 600,
"scrollX": true,
"bDestroy": true,
"columnDefs": [{
"targets": 0,
"render": function (data, type, full, meta){
return '<a class="editLink" href="#">Edit</a><a class="deleteLink" href="#">Del</a>':
}
}], // begin here
initComplete: function(){
this.api().columns().every(function(){
var column = this;
var select = $('<select><option value=""></option></select>')
.appendTo( $(column.footer()).empty() )
.on( 'change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search( val ? '^'+val+'$' : '', true, false )
.draw();
} );
column.data().unique().sort().each( function ( d, j ) {
select.append( '<option value="'+d+'">'+d+'</option>' )
} );
} );
}
} );
});
I have not received any errors, and the DataTable still loads, but the column search is not there.
I am using jQuery-2.1.3.min, so it should be up to date.
Does anyone see what I am doing wrong and what I can do to correct this issue?
Add a <tfoot> to your table. The expression referencing column.footer() expects it to exist.
Related
Referring to the Individual column searching (text inputs) and Individual column searching (select inputs) to use multiple filters on jQuery DataTable, I mixed them up in order to allow text inputs searches on some columns and select inputs searching on others.
It almost works, but select inputs don't work correctly: the first select input on the third column shows values of the first column, the second select input shows the second column, and so on.
$( document ).ready(function() {
$('#wbe_table tfoot th.search_th').each( function () {
var title = $(this).text();
$(this).html( '<input type="text" placeholder="Search '+title+'" />' );
} );
var oTable = $('#wbe_table').DataTable( {
orderCellsTop: true,
fixedHeader: true,
responsive: true,
lengthChange: true,
autoWidth: true,
pageLength: 50,
order: [[7, "desc"]],
columnDefs: [
{
targets: [4],
orderable: false
},
{
type: "currency",
targets: [7,8,9,10]
},
],
dom: 'Bfrtip',
buttons: [
'copy', 'csv', 'excel', 'pdf', 'print'
] ,
//Select input search
initComplete: function () {
var api = this.api();
$('.filterhead', api.table().footer()).each( function (i) {
var column = api.column(i);
var select = $('<select><option value=""></option></select>')
.appendTo( $(this).empty() )
.on( 'change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search( val ? '^'+val+'$' : '', true, false )
.draw();
} );
column.data().unique().sort().each( function ( d, j ) {
select.append( '<option value="'+d+'">'+d+'</option>' );
} );
} );
}
});
// Text input search
oTable.columns().every( function () {
var that = this;
$( 'input', this.footer() ).on( 'keyup change', function () {
if ( that.search() !== this.value ) {
that
.search( this.value )
.draw();
}
} );
} );
});
I am using Datatable pipeline for generating table. My table has dynamic column means it has no fixed column. The column column number changes with the change of a month. Suppose, during current month the table has 4 column but for november it has 32 columns. When I changes month to november,it gives me Cannot read property 'style' of undefined this error.
My datatable initilization function:
function monthlyAttendanceStatusDatatableInit(tableIdOrCss, url, columns, sortArr, pageLength, year, month) {
console.log(columns);
var param = {
"responsive": false,
// "columnDefs": [
// {responsivePriority: 1, targets: -1},
// {responsivePriority: 2, targets: 0}
// ],
"aLengthMenu": [[10, 20, 50, -1], [10, 20, 50, 'All']],
"pageLength": pageLength || 10,
"iDisplayLength": pageLength || 10,
//"language": { search: "" },
"sPaginationType": "simple_numbers", // you can also give here 'simple','simple_numbers','full','full_numbers'
"oLanguage": {
"sSearch": "Search:",
"sProcessing": "Loading..."
},
"ajax": $.fn.dataTable.pipeline( {
url: url,
data: {
'month': month,
'year': year
},
pages: 2 // number of pages to cache
}),
"processing": true,
"serverSide": true,
"searching": true,
// "bPaginate": true,
// "fnDrawCallback":function(){
// if(typeof callBack == 'function'){
// callBack();
// }
// },
"destroy": true,
"paging": true,
"retrieve": false,
"aoColumns": columns,
"aaSorting": sortArr, //[[ 0, "asc" ],[ 1, "desc" ]] // Sort by first column descending
// "scrollX": true,
// "createdRow": function( row, data, dataIndex ) {
// $(row).attr('id', 'employee-'+data.id);
// }
};
// $(tableIdOrCss).remove();
var table = $(tableIdOrCss).DataTable(param);
return table;
}
I genrating column using server side data.
Columndefinition function:
function getColumnDefinition(year, month) {
var columns = [
{"sTitle": "ID", "mData": "e_id", "bSortable": true},
{"sTitle": "Employee Name", "mData": "employee_name", "bSortable": true},
];
var totalDay = getDayCount(year, month);
var monthS = month.slice(0, 3);
for (var i = 1; i <= totalDay; i++) {
if (i < 10) {
var date = '0' + i.toString();
}else {
var date = i.toString();
}
var dateColumn = {"sTitle": date + "-" + monthS, "mData": date, "bSortable": true};
columns.push(dateColumn);
}
return columns;
}
I am unable to find any solution
As you can see on DataTable documentation for destroy() method, in the case of column change, you should destroy datatable instance and remove all child nodes of the table element with jQuery#empty() call before adding new columns.
var table = $('#myTable').DataTable();
$('#submit').on( 'click', function () {
$.getJSON( 'newTable', null, function ( json ) {
table.destroy();
$('#myTable').empty(); // empty in case the columns change
table = $('#myTable').DataTable( {
columns: json.columns,
data: json.rows
} );
} );
} );
Here it is the working example.
<script>
$(document).ready(function() {
$('#sortable').DataTable( {
initComplete: function () {
this.api().columns([0,1,2,3]).every( function () {
var column = this;
var select = $('<select><option value=""></option></select>')
// var select = $('<select><option value="">' + $(this.header()).html() + '</option></select>')
.appendTo( $(column.header()).empty() )
.on( 'change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search( val ? '^'+val+'$' : '', true, false )
.draw();
} );
column.data().unique().sort().each( function ( d, j ) {
//select.append( '<option value="'+d+'">'+d+'</option>' )
select.append( '<option>'+d+'</option>' )
} );
} );
}
} );
} );
$(document).ready(function() {
$('#sortable').DataTable({
"order": [[1, "asc"],[0, "asc"]],
"columns": [
null,
null,
null,
{"orderable": false},
{"orderable": false},
{"orderable": false},
],
"searching": true,
"paging": false,
"ordering": true,
"info": false
});
} );
</script>
These 2 separate blocks work well individually if the other is commented out, but I don't know how I can combine them to be one block so I can achieve default sorting and drop-down filters.
The aim is to have drop-down filters on columns [0,1,2,3], default sorting and have defaults number of rows shown = 50.
//like so:
<script>
$(document).ready(function() {
$('#sortable').DataTable( {
sort by default;
set default rows shown to 50;
put filter on first 4 colmuns;
})
})
</script>
Thanks in advance for your help.
Your "two blocks" are two initializations of a DataTables object made from the same table, which is why they don't work together. The good news is that you can just combine the two into a single block and they should work together, since none of the options you're using conflict with each other (as far as I can tell). It should look like this:
<script>
$(document).ready(function() {
$('#sortable').DataTable( {
pageLength: 50, //This is the option which will give you 50 rows by default
order: [[1, "asc"],[0, "asc"]],
columns: [
null,
null,
null,
{"orderable": false},
{"orderable": false},
{"orderable": false},
],
searching: true,
paging: false,
ordering: true,
info: false,
initComplete: function () {
this.api().columns([0,1,2,3]).every( function () {
var column = this;
var select = $('<select><option value=""></option></select>')
// var select = $('<select><option value="">' + $(this.header()).html() + '</option></select>')
.appendTo( $(column.header()).empty() )
.on( 'change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search( val ? '^'+val+'$' : '', true, false )
.draw();
} );
column.data().unique().sort().each( function ( d, j ) {
//select.append( '<option value="'+d+'">'+d+'</option>' )
select.append( '<option>'+d+'</option>' )
} );
} );
}
} );
} );
</script>
You'll note that all I did was put the options selected in the second block into the first block and add the pageLength option to start the number of rows at 50. You can optionally surround the names of the options with "" if you want, but it's unneccessary, just a preference thing (e.g. "order" vs order).
You should only ever have one DataTables initialization .DataTable() call in your code per page.
I have been trying to follow this approach of row grouping described in the following link. http://www.datatables.net/examples/advanced_init/row_grouping.html
However while implementing the drawCallback function I had to change the name to "fnDrawCallback" for my datatable to recognize this function and also declare var api as var api = this.oApi._fnGetTrNodes( settings ); instead of the way described in the example (var api = this.api();) as otherwise I was getting an error. However now I am still getting a similar error while defining the rest of function if I follow the syntax and keywords given in the example. That is ,
var rows = api.rows( {page:'current'} ).nodes();
var last=null;
api.column(2, {page:'current'} ).data().each( function ( group, i ) {
if ( last !== group ) {
$(rows).eq( i ).before(
'<tr class="group"><td colspan="5">'+group+'</td></tr>'
);
The error I get is "undefined is not a function " for the drawCallback function. I tried a lot trying to find a different way of writing the same function but I cannot understand why this doesn't work and why I had to change the api declaration too.
I am very new to this , so if someone could explain what the correct format would be to write this function without this error I would really appreciate it !
Please find my Jquery part listed below. Thanks in advance !!
$(document).ready(function(){
var oTable = $("#tableTenants").dataTable({
"bProcessing": true,
"sAjaxSource": "/api/alltenantstatistic.json?iDisplayStart=0&iDisplayLength=${totalCount}&sSortDir_0=asc",
"aoColumns": [
{ "mDataProp": "state","sClass": "student_rows" , "sWidth":"1%" },
{ "mDataProp": "name","sClass": "student_rows" , "sWidth":"20%"},
{ "mDataProp": "testAdmin","sClass": "student_rows" , "sWidth":"70%"},
{ "mDataProp": "totalStudentCount","sClass": "select_rows" , "sWidth":"2%", "bSortable": false },
{ "mDataProp": "totalPnPStudentCount","sClass": "select_rows" , "sWidth":"2%", "bSortable": false }
],
"aoColumnDefs": [
{ "fnRender": function(oObj) {
return '' + oObj.aData.state + '';
},
"bUseRendered": false,
"aTargets": [0]
},
{
"aTargets": [1],
"bVisible": false
},
],
"iDisplayLength": 10,
"order": [[ 1, 'asc' ]],
"fnDrawCallback": function ( settings ) {
console.log("hello");
var api = this.oApi._fnGetTrNodes( settings ); // Had to change this from this.api();
var rows = api.rows({page:'current'}).nodes(); // Giving an error
var last=null;
api.column(1, {page:'current'} ).data().each( function ( group, i ) {
if ( last !== group ) {
$(rows).eq( i ).before(
'<tr class="group"><td colspan="4">'+group+'</td></tr>'
);
last = group;
}
} );
},
"bLengthChange": true,
"bFilter": true,
"bAutoWidth": false,
//"bStateSave": true,
"sDom": "<'row-fluid'<'span5'l><'span7'f><'span2'>r>t<'row-fluid'<'span6'i><'span6'p>>",
"sPaginationType": "bootstrap",
"oLanguage": {
"sLengthMenu": "_MENU_",
"sEmptyTable": "No Organization Uploads available for this Tenant",
"sInfoEmpty": "",
"sProcessing": "Loading..."
}
});
Its due to jquery datatable version problem. use below libraries and code
<script src="//cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js"></script>
<script src="//cdn.datatables.net/plug-ins/725b2a2115b/integration/bootstrap/3/dataTables.bootstrap.js"></script>
<script src="//datatables.net/release-datatables/extensions/ColReorder/js/dataTables.colReorder.js"></script>
"drawCallback": function (settings) {
var api = this.api();
var rows = api.rows({ page: 'current' }).nodes();
var last = null;
api.column(1, { page: 'current' }).data().each(function (group, i) {
if (last !== group) {
$(rows).eq(i).before(
'<tr class="group"><td colspan="3">' + group + '</td></tr>'
);
last = group;
}
});
},
I'm trying to create a row inside my datatable that increments +1 each row. I've been told the easiest way to do this would be using fnRender. Now I've used fnRender to change data that's already in a column from the serverside processor, but never to create a new column alone.
Any help would be awesome!
Here's my current code:
oTable = $('#testingz').dataTable({
"bProcessing": true,
"bServerSide": true,
"bJQueryUI": true,
"sPaginationType": "full_numbers",
"aaSorting": [ [1,'desc'] ],
"sDom": '<""l>rt<"F"fp>',
"sAjaxSource": "server_processing.php",
"aoColumnDefs": [
{
"fnRender": function ( o, val ) {
return '' + o.aData[0] + '';
},
"aTargets": [ 0 ]
}
]
});
Do you mean something like this: http://datatables.net/release-datatables/examples/api/counter_column.html