I get API response in JSON format with nested arrays in it. I want to parse it in nested datatable. I've tried for this, but it won't work. Can anyone let me know where I made a mistake. In JSON I have passenger data & each passenger having multiple drivers, I want to show it in datatable in nested format, like Passenger is parent & respective drivers of it as child.
Expected Result
Here is my JSON response:
/* Formatting function for row details - modify as you need */
function format(driver_data) {
// `d` is the original data object for the row
return '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">' +
'<tr>' +
'<td>Full name:</td>' +
'<td>' + driver_data.employeename + '</td>' +
'</tr>' +
'<tr>' +
'<td>Extension number:</td>' +
'<td>' + driver_data.email + '</td>' +
'</tr>' +
'</table>';
}
$(document).ready(function () {
var table = $('.trip_unmacthed').DataTable({
type: "GET",
url: "https://api.myjson.com/bins/13woes",
dataType: "json",
"columns": [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{
"data": "employeename"
},
{
"data": "email"
}
],
"order": [[1, 'asc']]
});
// Add event listener for opening and closing details
$('.trip_unmacthed 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');
}
});
});
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<table class="table table-striped table-bordered table-hover trip_unmacthed">
<thead>
<tr>
<th>User Type</th>
<th> Name</th>
<th>Start Location</th>
<th>Drop Location</th>
<th> Date </th>
<th>Actions</th>
</tr>
</thead>
<tbody id="myData">
</tbody>
</table>
Change the passenger_data to data according to API Docs and your format function.
$(document).ready(function () {
function format(driver_data) {
console.log(driver_data); var b = ''; var i;
for (i = 0; i < driver_data.length; i++) {
b = b + '<tr>' +
'<td></td>' +
'<td>' + driver_data[i].employeename + '</td>' +
'<td>' + driver_data[i].email + '</td>' +
'<td>' + driver_data[i].distance + '</td>' +
'</tr>';
}
return b;
}
var table = $('#example').DataTable({
"ajax": "https://api.myjson.com/bins/y53hs",
"columns": [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{
"data": "employeename"
},
{
"data": "email"
},
{
"data": "mobilenumber"
}
],
"order": [[1, 'asc']]
});
// Add event listener for opening and closing details
$('#example 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
console.log(row.data());
row.child(format(row.data().driver_data)).show();
tr.addClass('shown');
}
});
});
Not sure about what your JSON is . If you have a passenger in your JSON e.g.
{
"passenger_data": [
{
"employeename": "Passenger A",
"email": null,
"driver_data": [
{
"employeename": "Driver A1",
"email": null,
"distance": 0,
},
{
"employeename": "Driver A2",
"email": null,
"distance": 0,
},
],
"mobilenumber": "+12344576",
},
]
}
then you should do it like
"columns": [
{"passenger_data": "employeename"},
{"passenger_data": "driver_data.employeename"},
{"passenger_data": "driver_data.email"}
],
may be your are not using the . operator
Related
I want to get a value of 53.54.57 but somehow I always get the value of 53.53.53 not as expected. anyone can help me?
columns: [
{ data: 'linenum' },
{ data: 'nama' },
{ data: 'harga' },
{ data: 'qty' },
{ data: 'total' },
{ data: 'remove' },
{ data: 'untung' },
]
$("#table-main").DataTable().rows().every(function(){
var data = this.data();
var master_id = $("#" + $(data.remove).attr("id")).val();
//53,54,57 is index column name = "remove"
var master_barang_id;
master_barang_id = $("#" + $(data.remove).attr("id")).val(); //the method I use to retrieve data
alert(master_barang_id); //it should alert 53,54,57 BUT alerts only appear 53,53.53
});
$("#" + $(data.remove).attr("id")).val();
I use this function to retrieve data from the datatable, but the line can only be the same value. always a value of 53, how to get the value of a line in the column called 'remove'
Is my looping wrong? or is there another way to get that value?
Like #charlietfl said, it seems you're duplicating the element ids.
If I understood you correctly, and the id of your input(type number) is the value, then you only need to change one line:
$("#table-main").DataTable().rows().every(function(){
var data = this.data();
var master_id = $("#" + $(data.remove).attr("id")).val();
//53,54,57 is index column name = "remove"
var master_barang_id;
//change this line
//master_barang_id = $("#" + $(data.remove).attr("id")).val(); //the method I use to retrieve data
//for this one
master_barang_id = $("#" + data.remove).val();
alert(master_barang_id); //it should alert 53,54,57 BUT alerts only appear 53,53.53
});
This is a working example:
var jsonData = [{ "linenum": 1, "nama": "lampu economat 3w LED", "harga": 20000, "qty": 1, "total": 20000, "remove": 53, "untung": "X" }, { "linenum": 2, "nama": "lampu economat 5w LED", "harga": 25000, "qty": 1, "total": 25000, "remove": 54, "untung": "X" }, { "linenum": 3, "nama": "lampu economat 9w LED", "harga": 30000, "qty": 1, "total": 30000, "remove": 57, "untung": "X" }];
$("#btnGetData").click(function() {
$("#table-main").DataTable().rows().every(function(){
var data = this.data();
var master_id = $("#" + $(data.remove).attr("id")).val();
//53,54,57 is index column name = "remove"
var master_barang_id = $("#" + data.remove).val(); //the method I use to retrieve data
alert(master_barang_id); //it should alert 53,54,57 BUT alerts only appear 53,53.53
});
});
var oTable = $('#table-main').DataTable({
data: jsonData,
columns: [
{ data: 'linenum' },
{ data: 'nama' },
{
data: 'harga',
"render": function (data, type, row, meta) {
return '<input type="text" value=' + data + ' />';
}
},
{
data: 'qty',
"render": function (data, type, row, meta) {
return '<input type="number" value=' + data + ' />';
}
},
{ data: 'total' },
{
data: 'remove',
"render": function (data, type, row, meta) {
return '<input type="number" id="' + data + '" value=' + data + ' />';
}
},
{ data: 'untung' },
]
});
input {
text-align: right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
<link href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css" rel="stylesheet"/>
<div class="data-table-container">
<table id="table-main" class="table cell-border order-column stripe">
<thead>
<tr>
<th>linenum</th>
<th>nama</th>
<th>harga</th>
<th>qty</th>
<th>total</th>
<th>remove</th>
<th>untung</th>
</tr>
</thead>
</table>
</div>
<br>
<input type="button" id="btnGetData" value="GET DATA" />
I am using to Jquery datables to create a table with row details . Everything working fine Only the number of entries
The current logic is counting the parents row + child rows. I want to count only parents rows which are 4. My result should be Showing 1 to 10 of 4 entries.
In my Json file, I have recordsTotal: 16 which is the total rows parents + child. When I change to 4 which is number of parents rows the table will show me only first record (Ticket id 1 + its 3 child rows ) as it's counted as 4 entries.
Any suggestions please how can I update ? Thank you.
$(document).ready(function() {
function format ( d ) {
d.Items.sort(function compare(a,b) {
if (a.Line_No < b.Line_No)
return -1;
if (a.Line_No > b.Line_No)
return 1;
return 0;
});
var x = '<table class="nowrap table table-bordered table-hover" cellspacing="0" width="100%"><thead><tr><th>Line No</th><th>Line Level Issue</th><th>Created Date</th><th>Created By</th></tr></thead><tbody>' ;
$.each(d.Items, function( index, value ) {
x += '<tr><td>' + d.Items[index].Line_No + '</td><td>' + d.Items[index].Line_Level_Issue + '</td><td>' + d.Items[index].Created_Date + '</td><td>' + d.Items[index].Created_By + '</td></tr>';
});
x +='</tbody></table>';
return x;
}
var dt = $('#example').DataTable( {
"processing": true,
"serverSide": true,
"deferRender": true,
"lengthChange": true,
"pageLength": 10,
"language": { "emptyTable": "No matching records found",
"info": "Showing _START_ to _END_ of _TOTAL_ entries",
"zeroRecords": "No matching records found" },
"ajax": "https://api.myjson.com/bins/vwjfc",
"columns": [
{
"class": "details-control",
"data": "Ticket_id"
,render : function(data, type, row) {
return ' ' + data;
}
},
{ "data": "Order_Level_Issue" },
{ "data": "Geo" },
{ "data": "Region" },
{ "data": "Territory" },
{ "data": "Market" },
{ "data": "Country" },
{ "data": "SoldTo_Number" },
{ "data": "SoldTo_Name" },
{ "data": "Order_Numer" }
],
"order": [[0, 'asc'],[1, 'asc']]
} );
var detailRows = [];
$('#example tbody').on( 'click', 'tr td.details-control', function () {
var tr = $(this).closest('tr');
var row = dt.row( tr );
var idx = $.inArray( tr.attr('id'), detailRows );
if ( row.child.isShown() ) {
tr.removeClass( 'details' );
row.child.hide();
detailRows.splice( idx, 1 );
}
else {
tr.addClass( 'details' );
row.child( format( row.data() ) ).show();
if ( idx === -1 ) {
detailRows.push( tr.attr('id') );
}
}
} );
dt.on( 'draw', function () {
$.each( detailRows, function ( i, id ) {
$('#'+id+' td.details-control').trigger( 'click' );
} );
} );
} );
td.details-control {
background: url('https://datatables.net/examples/resources/details_open.png') no-repeat center left;
cursor: pointer;
}
tr.details td.details-control {
background: url('https://datatables.net/examples/resources/details_close.png') no-repeat center left;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.css" rel="stylesheet"/>
<link href="https://cdn.datatables.net/1.10.20/css/dataTables.bootstrap4.min.css" rel="stylesheet"/>
<table id="example" class="nowrap table table-hover table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th>TicketT id</th>
<th>Order Level Issue</th>
<th>Geo</th>
<th>Region</th>
<th>Territory</th>
<th>Market</th>
<th>Country</th>
<th>SoldTo Number</th>
<th>SoldTo Name</th>
<th>Order Numer</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Ticket id</th>
<th>Order Level Issue</th>
<th>Geo</th>
<th>Region</th>
<th>Territory</th>
<th>Market</th>
<th>Country</th>
<th>SoldTo Number</th>
<th>SoldTo Name</th>
<th>Order Numer</th>
</tr>
</tfoot>
</table>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.20/js/dataTables.bootstrap4.min.js"></script>
I assume the problem was not dataTables at all but your ajax call, since you are using serverSide your server side is the one who sends the data the table will display including the total of records so in your ajax response you have:
{draw: 1, recordsTotal: 16, recordsFiltered: 16, data: Array(4)}
So all you have to do is work in your server side script in order the reflect the expected output.
Hope it helps
I've been making CRUD tables in school traditionally through scaffolding per page and wanted to try out if I could do all operations without using Partial View. I opted to use AJAX which I followed a guide here: https://dzone.com/articles/crud-operation-in-aspnet-mvc-using-ajax-and-bootst
Everthing works flawlessly, but I wanted to use DataTable API to add Search and sorting functionality to the table. This is what the table looks like
HERE.
As you can see it doesn't recognize the data coming from the JS that I made, most notably with "Showing 0 to 0 of 0 entries". Is there any way to load data from AJAX to the DataTable script? Thanks very much! I'll provide my code below.
EDIT: I put the DataTable initilization in Inventory.js and the DataTable SOMETIMES works on page load. It's very random when trying to refresh the page multiple times. I tried putting a delay before the page loads to see if that makes any difference but it doesn't work. Anybody know what's going?
Inventory(model)
public List<Inventory> ListAll()
{
List<Inventory> lst = new List<Inventory>();
using (SqlConnection con = new SqlConnection(Helper.GetCon()))
{
con.Open();
string query = #"SELECT * FROM Inventory";
using (SqlCommand cmd = new SqlCommand(query, con))
{
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
lst.Add(new Inventory
{
InventoryId = Convert.ToInt32(dr["inv_id"]),
Category = Helper.Decrypt(dr["category_name"].ToString()),
Name = Helper.Decrypt(dr["item_name"].ToString()),
Details = Helper.Decrypt(dr["item_details"].ToString()),
Quantity = Convert.ToInt32(dr["quantity"]),
CsbCode = Helper.Decrypt(dr["csb_code"].ToString()),
Notes = Helper.Decrypt(dr["notes"].ToString()),
Location = Helper.Decrypt(dr["location"].ToString()),
DateCreated = DateTime.Parse(dr["date_created"].ToString()),
LastModified = DateTime.Parse(dr["last_modified"].ToString()),
});
}
return lst;
}
}
}
}
InventoryController.cs
public JsonResult List()
{
return Json(invDB.ListAll(), JsonRequestBehavior.AllowGet);
}
Inventory.js(How I get my data)
function loadData() {
$.ajax({
url: "/Inventory/List",
type: "GET",
contentType: "application/json;charset=utf-8",
dataType: "json",
success: function (result) {
var html = '';
$.each(result, function (key, item) {
html += '<tr>';
html += '<td>' + item.InventoryId + '</td>';
html += '<td>' + item.Category + '</td>';
html += '<td>' + item.Name + '</td>';
html += '<td>' + item.Details + '</td>';
html += '<td>' + item.Quantity + '</td>';
html += '<td>' + item.CsbCode + '</td>';
html += '<td>' + item.Notes + '</td>';
html += '<td>' + item.Location + '</td>';
html += '<td>' + dateTimeFormat(item.DateCreated) + '</td>';
html += '<td>' + dateTimeFormat(item.LastModified) + '</td>';
html += '<td>Edit | Delete</td>';
html += '</tr>';
});
$('.tbody').html(html);
},
error: function (errormessage) {
alert(errormessage.responseText);
}
});
}
Index (DataTable script):
#section scripts {
<script src="https://cdn.datatables.net/1.10.19/js/dataTables.uikit.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.5.6/js/dataTables.buttons.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.5.6/js/buttons.print.min.js"></script>
<script>
$(document).ready(function () {
$('#user').DataTable({
dom: 'Bfrtip',
buttons: [
'print'
]
});
});
</script>
}
I am using 1.10 Jquery Datatables and for the templating i am using Underscore JS.
Here is my code for loading from server side.
Put this template and table in your html code.
<table class="table table-bordered table-condensed" id="tblAccounts"></table>
<script type="text/template" id="tmpl_Grid">
<td><%= Id %></td>
<td><%= Amount %></td>
<td><%= Date %></td>
<td><%= Type %></td>
</script>
Then this method for js to load data from server side.
function Load() {
var tmpl = _.template($('#tmpl_Grid').html());
$('#tblAccounts').DataTable({
"dom": "<'row'<'col-md-6 col-sm-12'l><'col-md-6 col-sm-12'f>r>t<'row'<'col-md-5 col-sm-12'i><'col-md-7 col-sm-12'p>>",
"paging": true,
"info": true,
"ordering": true,
"search": true,
"processing": true,
"serverSide": true,
"destroy": true,
"ajax": {
"url": "/Accounts/LoadList",
"type": "POST",
"data": function (d) {
d.startDate = $("#txtStartDate").val();
d.endDate = $("#txtEndDate").val();
}
},
"columns": [
{ "data": null, "title": "ID", "className": "", "orderable": false, "searchable": false },
{ "data": null, "title": "AMOUNT", "className": "", "orderable": false, "searchable": false },
{ "data": null, "title": "DATE", "className": "", "orderable": false, "searchable": false },
{ "data": null, "title": "TYPE", "className": "", "orderable": false, "searchable": false }
],
"order": [[0, "asc"]],
"rowCallback": function (row, data) {
$(row).html(tmpl(data));
},
"initComplete": function (settings, json) {
}
});
}
Here is the code for controller. I am using EntityFrameword for database processing you can use your own method or technique.
[HttpPost]
public async Task<JsonResult> LoadList(string startDate, string endDate)
{
var search = Request.Form["search[value]"] + "";
var totalCount = 0;
var fList = _context.Expenses.Include(x => x.AccountType).AsQueryable();
if (!string.IsNullOrEmpty(search))
{
fList = fList.Where(x => x.Description.ToLower().Trim().Contains(search.ToLower().Trim()));
}
var list = await fList.OrderByDescending(x => x.Id).Skip(start).Take(length).Select(x => new
{
x.Id,
x.Amount,
Date = x.Date != null ? x.Date.Value.ToString("dd-MMM-yyyy") : "",
Type = x.AccountTypeId != null ? x.AccountType.Name : "",
x.Description,
x.BillAmount,
x.Payment,
x.AccountTypeId
}).ToListAsync();
if (list.Any())
{
totalCount = fList.Count();
}
var result = JObject.FromObject(new
{
draw,
recordsFiltered = totalCount,
recordsTotal = totalCount,
data = list
});
return result;
}
thanks for the help. I got it to work consistently with a post I found on the same forum.
I changed my code for getting my data to this. Apparently you need to append the data, this was the most important thing that got my DataTables to work.
$("#user tbody").append(html);
$.ajax({
url: "/Artwork/List",
type: "GET",
contentType: "application/json;charset=utf-8",
dataType: "json",
success: function (result) {
$.each(result, function (key, item) {
var html = '';
html += '<tr>';
html += '<td>' + item.ArtID + '</td>';
html += '<td>' + item.Name + '</td>';
html += '<td>' + item.Details + '</td>';
html += '<td>' + item.Location + '</td>';
html += '<td>' + item.Notes + '</td>';
html += '<td>' + dateTimeFormat(item.DateCreated) + '</td>';
html += '<td>' + dateTimeFormat(item.LastModified) + '</td>';
html += '<td>Edit | Delete</td>';
html += '</tr>';
$("#user tbody").append(html);
});
$('#user').DataTable({
destroy: true,
dom: 'Bfrtip',
buttons: [
{
extend: 'print',
exportOptions: {
columns: ':visible' ,
}
},
'colvis'
],
columnDefs: [{
visible: false
}]
});
Again, thank you!
I have a html+php page with javascript.
In script I have a table with child row. In child row i vold like to open a modal window, that contain a text from mysql database. BUT the modal do not open, if I put into the child row table. From html link works perfectly.
What can I modify to work.
function format ( d ) {
// `d` is the original data object for the row
return '<div class="slider">'+
'<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
'<tr>'+
'<th>Operatőr 2:</th>'+
'<td>'+d.doctor2+'</td>'+
'<td style="width:100px"></td>'+
'<th>Leírás: </th>'+
'<td>'+d.description+'</td>'+
'<td style="width:100px"></td>'+
'<th>TAJ:</th>'+
'<td> '+d.patientid+'</td>'+
'</tr>'+
'</table>'+
'</div>';
$(document).ready(function() {
var table = $('#videos').DataTable( {
"ajax": 'data.php',
"columns": [
{
"class": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data": "patient" },
{ "data": "patientid" },
{ "data": "diagnose" },
{ "data": "surgerydate" },
{ "data": "description" },
{ "data": "doctor1" },
{ "data": "uploader", "visible": false }
]
}
});
// Add event listener for opening and closing details
$('#videos 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
$('div.slider', row.child()).slideUp( function () {
row.child.hide();
tr.removeClass('shown');
} );
}
else {
// Open this row
row.child( format(row.data()), 'no-padding' ).show();
tr.addClass('shown');
$('div.slider', row.child()).slideDown();
}
});
//Modal description
$('.openPopup').on('click',function(){
var dataURL = $(this).attr('data-href');
$('.modal-body').load(dataURL,function(){
$('#myModal').modal({show:true});
});
});
});
I would like this demo to work with the filter, not removing entries whose children have the data that you are filtering for.
E.g. in the example if you filter for 5407 Airi Satou does not get deleted and maybe even the child data gets expanded.
HTML and JS
/* Formatting function for row details - modify as you need */
function format ( d ) {
// `d` is the original data object for the row
return '<div class="slider">'+
'<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
'<tr>'+
'<td>Full name:</td>'+
'<td>'+d.name+'</td>'+
'</tr>'+
'<tr>'+
'<td>Extension number:</td>'+
'<td>'+d.extn+'</td>'+
'</tr>'+
'<tr>'+
'<td>Extra info:</td>'+
'<td>And any further details here (images etc)...</td>'+
'</tr>'+
'</table>'+
'</div>';
}
$(document).ready(function() {
var table = $('#example').DataTable( {
"ajax": "/examples/ajax/data/objects.txt",
"columns": [
{
"class": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data": "name" },
{ "data": "position" },
{ "data": "office" },
{ "data": "salary" }
],
"order": [[1, 'asc']]
} );
// Add event listener for opening and closing details
$('#example 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
$('div.slider', row.child()).slideUp( function () {
row.child.hide();
tr.removeClass('shown');
} );
}
else {
// Open this row
row.child( format(row.data()), 'no-padding' ).show();
tr.addClass('shown');
$('div.slider', row.child()).slideDown();
}
} );
} );
CSS
td.details-control {
background: url('/examples/resources/details_open.png') no-repeat center center;
cursor: pointer;
}
tr.shown td.details-control {
background: url('/examples/resources/details_close.png') no-repeat center center;
}
div.slider {
display: none;
}
table.dataTable tbody td.no-padding {
padding: 0;
}
SOLUTION
In order for jQuery DataTables to search child rows you need to add data displayed in the child rows to the main table as hidden columns.
For example, you can add hidden column for extn data property using columns.visible option as shown below:
JavaScript:
"columns": [
{
"class": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data": "name" },
{ "data": "position" },
{ "data": "office" },
{ "data": "salary" },
{ "data": "extn", "visible": false }
],
HTML:
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Salary</th>
<th>Extn.</th>
</tr>
</thead>
DEMO
See this jsFiddle for code and demonstration.