I am using DataTables to generate a table. There is a column containing order numbers.
For example:
...
I need every row in this column to have a hyperlink to view/order?id=? where ? is the contents of row in the Order No column. For example the first row would be a hyperlink to view/order?id=1321755 etc.
What is the simplest way I can do so?
Here is the code that I am using to initialize the DataTables:
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
$('#example').dataTable( {
"serverSide": true,
"ajax": {
"url": "../server_processing/orders.php",
"type": "POST"
},
"order": [[ 0, "desc" ]]
} );
} );
</script>
<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th>Order No</th>
...
</tr>
</thead>
<tbody>
</tbody>
</table>
Check this out:
http://datatables.net/reference/option/columns.render
You can add a column render callback when you specify columns definition.
var columnsDef = [
...
{
"title": "Order No.",
"render": function (data, type, row, meta) {
return '' + data + '';
}
},
...
];
$("#table").dataTable({
...
"columns": columnsDef,
...
});
The data in that column will be changed to what the render function return.
I needed to use jQuery dataTables and turn a normal field to be a HREF field.
Here you have it all, including also dataTables error handling..
Enjoy..
Yosi Lev
1) The HTML part:
<!-- COMPANIES LIST start -->
<div id="compListDiv" style="visibility:hidden; position : absolute; left : 360px; top : 40px;">
<br>
<table id="compList" align="left" border="1">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>address</th>
</tr>
</thead>
</table>
</div>
<!-- COMPANIES LIST end -->
2) The javascript dataTables part:
When a button is clicked the following js function is called:
function companiesList(){
accountstable=$('#compList').dataTable({
sort : true,
bFilter: false,
bInfo: false,
paging:false,
autoWidth: true,
ajax: {
url: "http://localhost:8080/j112/rest-1/companies/list",
dataType: 'json',
dataSrc: "data",
error: function ( xhr, textStatus, error ) {
if ( textStatus === 'timeout' ) {
alert( 'Timout error. The server took too long to send back the data.\nPlease try again.' );
}
else {
alert( 'User Not In Session.' );
location.href = "login.html";
}
myDataTable.fnProcessingIndicator( false );
}//function
}/* ajax: */,
scrollCollapse: true,
bDestroy: true,
serverSide:true,
fnRowCallback : function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { // this function is called for each row, but I could not use it to add the link
// if ( aData[1] == "A" )
//var td0 = $('td:eq(0)', nRow)[0];
// $('td:eq(0)', nRow).html( 'A');
// $('td:eq(0)', nRow).html( '<b>A</b>' )
},// fnRowCallback
initComplete : function(settings, json) { // this function is called after table is populated
//$("#compListDiv").show(); // this did not work so I used regular js to show the DIV
var d1 = document.getElementById('compListDiv');
d1.style.visibility = 'visible';
}, //initComplete
"columnDefs": [
{ "width": "10%", "targets": 0 },
{ "width": "20%", "targets": 0 },
{ "width": "70%", "targets": 0 }
],
"columns":[
//{"data" : "id"},
{ // render
"data": function (data, type, row, meta) {
return '' + data.id + '';
}
},
{"data" : "name"},
{"data" : "address"}
]
}); // dataTable()
}// companiesList()
By Yosi Lev - Feb 22, 2016
Related
I'm developing with django and javascript with datatable.
I want to apply column filtering in my datatable
(https://datatables.net/extensions/fixedheader/examples/options/columnFiltering.html)
but it works fine without serverside option & ajax (in client side),
but it doesn't work with serverside option & ajax.
How can i FIX IT? Please help me..
this is my code.
<table id="sample_table" class="table table-bordered table-hover">
<thead>
<tr>
<th class="sample_id">ID</th>
<th>date</th>
<th>serial</th>
<th>name</th>
<th>birth</th>
</tr>
</thead>
<tbody id="sample_table_body">
</tbody>
<tfoot>
<tr>
<th>ID</th>
<th>date</th>
<th>serial</th>
<th>name</th>
<th>birth</th>
</tr>
</tfoot>
</table>
</div>
<!-- /.card-body -->
</div>
var column_list = [
{ "data" : "id" , "className": "sample_id"},
{ "data" : "receiving_at" },
{ "data" : "serialnumber" },
{ "data" : "name" },
{ "data" : "birthday" },
];
$('#sample_table tfoot th').each(function(){
var title = $("#sample_table thead th").eq( $(this).index() ).text();
$(this).html('<input type="text" placeholder="Search '+title+'" />' );
});
var sample_table = $('#sample_table').DataTable({
"paging": true,
"autoWidth": false,
"lengthChange": false,
"ordering": true,
"processing" : true,
"columns": column_list,
"order": [ [0, 'desc'] ],
"fixedHeader": true,
"orderCellsTop": true,
"ajax": {
url: '/view_datatable/',
type: 'POST'
},
"serverSide" : true, //get data from server
"initComplete": function() { // column filtering RUN after table loaded .
$( '#sample_table tfoot input' ).on( 'keyup change clear', function () {
if ( sample_table.search() !== this.value && this.value.length>0) {
search_result = sample_table.search( this.value );
search_result.draw();
}
} );
}
});
#view.py
def list_datatable(request, companyname):
context = {}
if(request.method == "POST"):
start_page = int(request.POST['start'])
order_direction = request.POST["order[0][dir]"] # direction of ordering(asc, desc)
order_col_no = request.POST["order[0][column]"] # number of index to sort
order_col_name = request.POST['columns[' + str(order_col_no) + '][data]'].strip() # name of colum of ordering
sample_list_all = Sample.objects.all().order_by(order_col_name)
sample_list_per_page = []
for idx, obj in enumerate(sample_list_all[start_page:start_page + 10]):
data = {}
data['id'] = obj.id
data['receiving_at'] = str(obj.receiving_at)
data['birthday'] = obj.birthday
data['serialnumber'] = obj.serialnumber
data['name'] = obj.name
sample_list_per_page.append(data)
#-- end of --#
datalist_to_json = json.dumps(
{"data": sample_list_per_page, "recordsFiltered": len(sample_list_all), "recordsTotal": len(sample_list_all)}
)
return HttpResponse(datalist_to_json, content_type="application/json")
I am using JQuery datatable, after loading the data from server, my table looks something like this:
As you can see my table has six columns. The last column which is Contracted product, has the same data inside, I want to get the value and display it outside the datatable so it becomes more reader friendly as shown in picture 2.
My code looks like this:
var table = $('#products').DataTable( {
"processing": true,
"serverSide": true,
"paging": true,
"scrollX":"true",
"ordering": [],
"stateSave": false,
"info": true,
"dom": 'lrtip',
"ajax":
{
url:"xxxxxx_fetch.php",
type:'POST'
},
"columns": [
{ data: "product_code_fk" },
{ data: "product_name" },
{ data: "start_date" },
{ data: "end_date" },
{ data: "pack_size" },
{ data: "contract_prod" }
],
} );
Through the use of the header and footer callback manipulation functions provided by DataTables (headerCallback and footerCallback).
in HTML, by exemple
<tfoot>
<tr>
<th colspan="4" style="text-align:right">CONTRAT PROD :</th>
<th></th>
</tr>
</tfoot>
DataTable
$('#example').DataTable( {
"footerCallback": function ( row, data, start, end, display ) {
let api = this.api(), data;
...
$( api.column( 4 ).footer() ).html(
your_DATA
);
I have a jquery datatable on my page. This datatable is gonna show data based on a request made to my api
The HTML that I have is like the following:
<table id="details" class="table table-bordered table-hover table-striped nowrap hidden display" cellspacing="0" width="100%">
<thead>
<tr>
<th> </th>
<th>Patient Full Name</th>
<th class="hidden">LF</th>
</tr>
</thead>
<tfoot>
<tr>
<th> </th>
<th>Patient Full Name</th>
<th class="hidden">LF</th>
</tr>
</tfoot>
<tbody>
<tr id="dummytr2"><td style="text-align:center;padding-top:20px;" colspan="7"><p><em>No Data Available</em></p></td></tr>
</tbody>
</table>
The first <th> is gonna be used to collapse the tr and get the facility (the third <th> or the hidden one) of this patient.
I have a dummy <tr> in the table because I don't want to initialize the datatable at the beginning so I don't get the error message that tells me that I can't initialize my datatable twice.
The request to my api is gonna be triggered through a bunch of buttons like the following:
$.ajax({
url: "https://" + window.myLocalVar + "/api/metrics/GetDetails?metricName=" + metric,
type: "GET",
dataType: 'json',
contentType: 'application/json',
success: function (requests) {
if (requests.length > 0) {
$("#dummytr2").remove();
for (var i = 0; i < requests.length; i++) {
var patient_name = requests[i].PatientFullName;
var lab_facility = requests[i].LabFacility;
tr = '<tr>\
<td class=" details-control"></td>\
<td>' + patient_name + '</td>\
<td class="hidden">' + lab_facility + '</td>\
</tr>';
$("#details > tbody").append(tr);
//click event for each tr
$('#details tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
} else {
// Open this row
row.child(format(row.data())).show();
tr.addClass('shown');
}
});
}
}
// NOT SURE WHY IT IS NOT WORKING
$('#details').dataTable().fnDestroy();
var table = $('#details').DataTable({
"scrollX": true,
stateSave: true,
"columns": [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data": "PatientFullName" },
{ "data": "LabFacility" }
],
"order": [[1, 'asc']]
});
},
error: function (err) {
if (err) {
console.log(err);
}
}
});
});
function format(d) {
// `d` is the original data object for the row
var lf = d.LabFacility;
if (lf == "") {
lf = "No Lab Facility"
}
// wrapping text is not working???
return '<div class="table-responsive"><table class="table display" cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">' +
'<tr>' +
'<td>Lab Facility:</td>' +
'<td>' + lf + '</td>' +
'</tr>' +
'</table></div>';
}
This ajax request is gonna get called each time a button is clicked. This means the content of my datatable is going to change each time a button was clicked. I tried to clear and refill it did not work.. I tried to destroy it .. it did not work.. each time I destroy my datatable and execute the script it won't change the content of the table.
I am not sure what's wrong with my code. My code works only for the first time.. the second time you click a button, it won't update my datatable.
Thanks!
You need to:
empty the table with empty()
remove $('#details').dataTable().fnDestroy();
add destroy: true option
For example:
if (requests.length > 0) {
// Empty table
$('#details').empty();
// ... skipped ...
var table = $('#details').DataTable({
destroy: true,
// ... skipped ...
});
// ... skipped ...
}
Please see sample of what I was saying in comments above:
var dataTable_ = null;
var init_ = false;
var initDataTable = function() {
dataTable_ = $('#table').DataTable({
preDrawCallback: function(settings) {
},
drawCallback: function(settings) {
if (init_ === false) {
init_ = true;
}
},
searching: true,
data: [],
fnCreatedRow: function(nRow, aData, iDataIndex) {
},
scrollY: true,
scrollX: true,
responsive: false,
serverSide: false,
autoWidth: false,
processing: false,
scrollCollapse: false,
lengthChange: false,
fixedColumns: false,
info: false,
select: {
info: false,
items: 'rows'
},
dom: '<"toolbar">Bfrtip',
orderMulti: false,
stripeClasses: ['dt-stripe-1', 'dt-stripe-2'],
columns: [{
name: 'test1',
data: 'test1',
title: 'Test1',
type: 'string',
orderable: true
},
{
name: 'test2',
data: 'test2',
title: 'Test2',
type: 'string',
orderable: true
},
]
});
};
var ajaxFunction = function() {
$.ajax({
url: "https://api.myjson.com/bins/7ed89",
type: "GET",
dataType: 'json',
contentType: 'application/json',
success: function(data) {
if (init_ === false) {
initDataTable();
}
if (typeof dataTable_ == 'object') {
dataTable_.rows().remove().draw();
dataTable_.rows.add(data);
dataTable_.draw();
}
//console.log(data);
}
});
};
$('#button').click(function() {
ajaxFunction();
});
<link href="https://cdn.datatables.net/1.10.15/css/jquery.dataTables.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>
<table id="table" class="cell-border hover call-list">
</table>
<button id="button">Click To Load Data</button>
I have a problem with responsive datatables. When I resize the window and button was hidden this code, used to know which row is selected, doesn't work:
$('#usersTable tbody').on( 'click', 'button', function () {
usernameSelected = (userTable.row( $(this).parents('tr') ).data().username);
} );
Maybe the problem is on parents('tr'), but how can I get information when table was resized? I use the returned value to recognize the button of which row is clicked. My table use ajax call like this:
if ( ! $.fn.DataTable.isDataTable( '#licensesTable' ) ) {
licenseTable = $('#licensesTable').DataTable({
responsive: true,
//disable order and search on column
columnDefs: [
{
targets: [4,5],
orderable: false,
searchable: false,
}
],
//fix problem with responsive table
"autoWidth": false,
"ajax": "table",
"columns": [
{ "data": "user" },
{ "data": "startDate",
"render": function (data) {
return (moment(data).format("DD/MM/YYYY"));
}
},
{ "data": "endDate",
"render": function (data) {
return (moment(data).format("DD/MM/YYYY"));
}
},
{ "data": "counter" },
{ data:null, render: function ( data, type, row ) {
return '<button type="button" class="btn btn-primary" id="updadteLicense" data-toggle="modal"'
+'data-target="#updateLicenseModal">Update</button>'
}
},
{ data:null, render: function ( data, type, row ) {
return '<button type="button" class="btn btn-danger" id="deleteLicense" data-toggle="modal"'
+'data-target="#deleteLicenseModal">Delete</button>'
}
}
],
});
}
else {
licenseTable.ajax.url("table").load();
}
This is the HTML code relative datatable:
<table id="licensesTable"
class="table table-bordered table-striped">
<thead>
<tr>
<th>User</th>
<th>Start date</th>
<th>Expire date</th>
<th>Max execution</th>
<th>Delete</th>
<th>Update</th>
</tr>
</thead>
</table>
I dont know if this is a good way, but i solved it by adding id to the button.
in Laravel
->addColumn('Datalist',function($loadData){
return '<center><button id='.$loadData->rowID.' type="button" class="btn-showdata"><i class="fa fa-list"></i></button></center>';
})
in javascript:
$(this).on('click','#tableid .btn-showdata',function(){
console.log(this.id);
});
I use JQuery DataTable to bind and show my data. However, I can't add row number to generated grid from client side. Here my code:
HTML
<table id="applications_list" class="table table-bordered datagrid">
<thead>
<tr>
<th><?php echo __('No.'); ?></th>
<th><?php echo __('Application Code'); ?></th>
<th><?php echo __('Application Name'); ?></th>
<th><?php echo __('Created By'); ?></th>
<th><?php echo __('Created Date'); ?></th>
<th><?php echo __('Action'); ?></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Javascript
$('#applications_list').dataTable({
"bLengthChange": false,
"bFilter": true,
"bFilter": false,
"bProcessing": true,
"bServerSide": true,
"sPaginationType": "full_numbers",
"sAjaxSource": config.siteURL + "/applications/ajax_index",
"sServerMethod": "POST",
"aoColumns": [
{ "mData": null, "bSortable": false },
{ "mData": "app_applicationcode", "sName": "app_applicationcode" },
{ "mData": "app_applicationname", "sName": "app_applicationname" },
{ "mData": "app_createdby", "sName": "app_createdby" },
{ "mData": "app_createddate", "sName": "app_createddate" },
{ "mData": "app_applicationcode", "bSortable": false, "mRender": function(data) {
return '<i class="">x</i>'
}},
],
"aaSorting": [[ 0, 'asc' ]],
});
I read documentation here, but it won't work. Can anyone help me to solve this problem?
Best solution:
"columns": [
{ "data": null,"sortable": false,
render: function (data, type, row, meta) {
return meta.row + meta.settings._iDisplayStart + 1;
}
},
......
]
For DataTables 1.10.4,
"fnCreatedRow": function (row, data, index) {
$('td', row).eq(0).html(index + 1);
}
Add following code in "fnRowCallback":
For Datatables 1.10
"fnRowCallback": function (nRow, aData, iDisplayIndex) {
var info = $(this).DataTable().page.info();
$("td:nth-child(1)", nRow).html(info.start + iDisplayIndex + 1);
return nRow;
}
The guide from official documentation didn't work on server side tables. The best answer I can get is from this answer (from another question), just to write a render function:
{
"data": "id",
render: function (data, type, row, meta) {
return meta.row + meta.settings._iDisplayStart + 1;
}
}
Go upvote that answer.
Since none of the solutions here worked for me, here is my solution for a server-side.
add the extra <th></th> in your table, this is to mark where the number is to be inserted.
add the following right after initiating the table, the same way you would add "ajax": {"url":"somepage"},
"fnCreatedRow": function (row, data, index) {
var info = table.page.info();
var value = index+1+info.start;
$('td', row).eq(0).html(value);
},
3.At the location where the variables are defined for the table columns, add this column { "data": null,"sortable": false },
so it looks like this:
"columns": [
{ "data": null,"sortable": false },
......]
4. To get rid of the sorting icon (up-down arrow), select the second column by adding , "order": [[ 1, 'asc' ]], the same way you would add "ajax"....
This is possible by make use of fnPagingInfo api in the rowCallback to get the page and the display length and use it to calculate the row number like this:
For DataTables < 1.10
$('#example').dataTable({
"fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
var page = this.fnPagingInfo().iPage;
var length = this.fnPagingInfo().iLength;
var index = = (page * length + (iDisplayIndex +1));
$('td:eq(0)', nRow).html(index);
}
});
For DataTables == 1.10
$('#example').dataTable({
"rowCallback": function( row, data, iDisplayIndex ) {
var info = this.api.page.info();
var page = info.page;
var length = info.length;
var index = = (page * length + (iDisplayIndex +1));
$('td:eq(0)', row).html(index);
}
});
NOTE: for DataTables < 1.10, you have to add the fnPageInfo.js script to your page
Official solution from DataTable:
table.on( 'order.dt search.dt', function () {
table.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {
cell.innerHTML = i+1;
} );
} ).draw();
when we use Server Side Rendering, One of the Easy & Best Way for Display Auto Increment Sr No. instead of table row id... I used "Laravel Yajra DataTable"
simply use return meta.row + 1; .
see Below Example Code
columns: [
{data: 'SrNo',
render: function (data, type, row, meta) {
return meta.row + 1;
}
},
.... //your Code(Other Columns)
]
Or You can also Use like this
columns: [
{data: 'SrNo',
render: function (data, type, row, meta) {
return meta.row + meta.settings._iDisplayStart + 1;
}
},
.... //your Code(Other Columns)
]
Assuming the <?php echo __('No.'); ?> is the primary key from database you can use columnDefs to add the key as row number to each cell of a row like this
"columnDefs": [{
"targets": '_all',
"createdCell": function(cell, cellData, rowData, rowIndex, colIndex) {
$(cell).attr({'data-pk': rowData[0]});
}
}]
Where rowData[0] will be the primary key value.
Just add return meta.row + 1 this inside render function. For Example.
{
data: "",
render: function(rec, type, row, meta) {
return meta.row + 1;
}
}