Add nested datatable within child row of another datatable - javascript

I have seen where others have asked this question (like here: Add child row as nested datatable within exisiting datatable) but I have yet to see it answered.
I have a "master" datatable that makes use of the child row feature. Here's the code that initializes the "master" datatable. (I'm including it just to be thorough, but everything here works perfect.)
var table = $('#members');
var oTable = table.dataTable({
"language": {
"aria": {
"sortAscending": ": activate to sort column ascending",
"sortDescending": ": activate to sort column descending"
},
"emptyTable": "No data available in table",
"info": "Showing _START_ to _END_ of _TOTAL_ entries",
"infoEmpty": "No entries found",
"infoFiltered": "(filtered1 from _MAX_ total entries)",
"lengthMenu": "_MENU_ entries",
"search": "Search:",
"zeroRecords": "Loading..."
},
"buttons": [],
"columnDefs": [
{className: 'control'},
{orderable: false, targets: 0 }
],
// setup responsive extension: http://datatables.net/extensions/responsive/
"responsive": true,
"order": [
[1, 'asc']
],
"order-column": false,
"lengthMenu": [
[5, 10, 15, 20, -1],
[5, 10, 15, 20, "All"] // change per page values here
],
// set the initial value
"pageLength": 5,
"dom": "<'row' <'col-md-12'B>><'row'<'col-md-6 col-sm-12'l><'col-md-6 col-sm-12'f>r><'table-scrollable't><'row'<'col-md-5 col-sm-12'i><'col-md-7 col-sm-12'p>>",
});
This next bit of code is located right after the above code and accomplishes 2 things:
1) It prevents multiple child rows from being opened at once (just a personal preference) and
2) Uses an AJAX call to populate the child row that was just toggled open.
table.on('click', 'tr', function () {
var id = $(this).attr('id');
if($(this).hasClass('parent'))
{
table.$('tr.parent').not(this).find('td:first-child').trigger('click');
var load_member_leads = $(this).next().find('td.child > ul > li span.dtr-data');
//var load_member_leads = $('#test');
$.ajax({
url: base_url + 'process/load_member_leads',
type: 'POST',
data: {test:id},
dataType: "html",
success: function(data){
console.log ("success");
load_member_leads.html(data);
formRepeater();
initTable1(id);
},
failure: function (data) {
console.log ("failed");
}
});
}
});
This portion of the code appears to be working well, but here is where it gets tricky. Within the returned AJAX data, I have an html table that I would like to initialize using the datatables plugin. Essentially what I'd have is a nested datatable within a child row of another "master" datatable. The problem is, everything works great until I try to initialize the datatable plugin on the nested table using:
initTable1(id);
(Note: the id variable being passed is to prevent multiple tables with the same ids. You can see in the code below how it's appended to the datatable init call.) Once this function is called, everything in the child row disappears and is erased from the DOM. Just gone. And I have no idea why.
Here is the code within the initTable1() function that initializes the 2nd datatable:
var table2 = $('#leads_' + id);
var oTable2 = table2.dataTable({
"language": {
"aria": {
"sortAscending": ": activate to sort column ascending",
"sortDescending": ": activate to sort column descending"
},
"emptyTable": "No data available in table",
"info": "Showing _START_ to _END_ of _TOTAL_ entries",
"infoEmpty": "No entries found",
"infoFiltered": "(filtered1 from _MAX_ total entries)",
"lengthMenu": "_MENU_ entries",
"search": "Search:",
"zeroRecords": "No matching records found"
},
destroy: true,
//setup buttons extentension: http://datatables.net/extensions/buttons/
buttons: [],
// setup responsive extension: http://datatables.net/extensions/responsive/
responsive: {
details: {
type: 'column',
target: -1
}
},
"columnDefs": [ {
className: 'control',
orderable: false,
targets: -1
} ],
"order": [
[0, 'asc']
],
"ordering": false,
"lengthMenu": [
[5, 10, 15, 20, -1],
[5, 10, 15, 20, "All"] // change per page values here
],
// set the initial value
"pageLength": 10,
"dom": ""
});
And for good measure, here is the code being fetched by the AJAX call. (Note the $test variable is the same as the id variable being passed to the initTable1 function)
<table class="table table-striped table-bordered dt-responsive" width="100%" id="leads_<?php echo $test; ?>">
<thead>
<tr>
<th class="all">Column 1</th>
<th class="all">Column 2</th>
<th class="all">Column 3e</th>
<th class="all">Column 4</th>
<th class="all">Column 5</th>
<th class="all">Column 6</th>
<th class="all">Column 7e</th>
<th class="all">Column 8</th>
<th class="none">Column 9</th>
<th class="all">Column 10</th>
</tr>
</thead>
<tbody>
<!-- table rows populated here - this is currently hardcoded for testing -->
</tbody>
</table>
Here's what DOES work, which may shed some light as to what's actually causing the problem.
1) It works if I comment out the initTable1() function within the AJAX call...well everything but the initialization of the datatable plugin on the 2nd table. But the html populates where it should within the child row of the "master" datatable.
2) It works if I change where the AJAX data is being populated - specifically, it works outside of the "master" datatable. It not only populates where it should (note the commented out var load_member_leads that points to $('#test').), but it initializes datatables correctly as well.
It only seems to break if I both initialize datatables on the second table, and place said table in the child row of the "master" datatable. And by break, I mean completely disappear as if the AJAX call failed - which it isn't according to the console.log.
This problem is driving me crazy, what am I doing wrong? Any help is much appreciated!

I feel kind of stupid after spending hours on this one issue, but it turns out I was using the responsive extension rather than the built in functionality with datatables. For anyone else running into this issue, just follow and modify the code as needed from the example here: https://datatables.net/examples/api/row_details.html

Related

How to replace standard bootstrap table with dataTables in jQuery?

I have tried and searching lot of solution but not solve my problem, even at dataTables website. The problem is how to display nested array in json using DataTables? Fo example below, How if I just want to display l3_id: "1" data only.
I try to understand this link but not really understand. Example
There is no error at console and network tab.
DataTable not appear, including dataTables features such as search box, pagination. (The CDN/library has been imported)
JSON
{
"data": [
{
"project_id": "1",
"l1_task": [
{
"l1_id": "1",
"l2_task": [
{
"l2_id": "1",
"l3_task": [
{
"l3_id": "1",
"l3_name": "My name"
}
]
}
]
}
]
}
]
}
JS (I am applying HTML in JS)
"<table id='Layer3Table' class='table dt-responsive nowrap' style='width:100%'>"+
"<thead>"+
"<tr>"+
"<th class='text-center'>ID</th>"+
"<th class='text-center'>Activity Name</th>"+
"</tr>"+
"</thead>"+
"</table>"+
$('#Layer3Table').DataTable({
ajax: {
url: url_project_detail",
dataSrc : "data"
},
columns: [
{ data : "l1_task.0.l2_task.0.l3_task.0.l3_id" },
{ data : "l1_task.0.l2_task.0.l3_task.0.l3_name" },
],
});
Either define your table, including all tbody content in HTML, then use DataTables to enable the search etc features. If you do it this way you don't need to set the url or columns (although you can still set other options).
$('#Layer3Table').DataTable();
Or if you want to make use of the url and column features, create the basic table structure in HTML
<table id='Layer3Table' class='table dt-responsive nowrap' style='width:100%'>
<thead>
<tr>
<th class='text-center'>Project ID</th>
<th class='text-center'>Project Name</th>
<th class='text-center'>Project Description</th>
<th class='text-center'>Project Status</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Then set up your DataTable separately in JavaScript.
$('#Layer3Table').DataTable( {
ajax: {
url: url_project_detail,
crossDomain : true,
type : "POST",
cache : false,
dataType : "json",
contentType: "application/json",
dataSrc : "data",
},
columns: [
{ data : "l3_id", "className": "text-center" },
{ data : "l3_name", "className": "text-center" },
{ data : "l3_description", "className": "text-center" },
{ data : "l3_status", "className": "text-center" }
],
});
What you appear to be doing is looping over your results and creating a DataTable for each of them, which is why it doesn't understand.

jQuery datatables - how to set the column name

I have a jQuery datable pluged into my ASP.NET application and currently, in order to show the column names, I have the following piece of code in my Razor view..
<table id="myDataTable" class="display">
<thead>
<tr>
<th>Contact name</th>
<th>Title</th>
<th>Country</th>
<th>City</th>
<th>Project</th>
</tr>
</thead>
<tbody style="font-size:x-small"></tbody>
</table>
Then, I have my javascript for the jQuery datatbles...
$('#myDataTable').DataTable({
"bServerSide": false,
"sAjaxSource": //controller binding,
"bAutoWidth": false,
"bProcessing": true,
"aoColumns": [
{ "sName": "CONTACT_NAME" },
{ "sName": "TITLE"},
{ "sName": "COUNTRY" },
{ "sName": "CITY" },
{ "sName": "PROJECT" },
],
"bDestroy":true
});
However, when I render the HTML the first time before I fill in the table, it looks awkward because I am rending some random HTML (that is related to the future column names) with no datatable at all...
How can I define the column of my table without having to set it in the HTML so I can avoid having that random text there?
Thanks!
just set the initial CSS of the #myDataTable to visibility:hidden; like this:
#myDataTable { visibility:hidden; }
That way you can put it right in the HTML and just call the following JavaScript to show it after you update the values:
document.getElementById('#myDataTable').style.visibility = "visible";

No data available in a table in server-side processing mode

I want to show my record data into table enhanced by jQuery DataTables plugin using server-side processing mode. I followed the docs Datatables Server side but in my table I can't show the record data.
Here's my Ajax response:
{
"draw": 0,
"recordsTotal": 4,
"recordsFiltered": 4,
"data": [
[
27,
"Brokoli Segar",
"25000"
],
[
28,
"Tomat Super",
"2000"
],
[
29,
"Oreo Roll",
"9400"
],
[
30,
"Close Up Toothpaste Fire Freeze",
"7000"
]
],
"queries": [
{
"query": "select count(*) as aggregate from (select '1' as row_count from `product` where `product`.`deleted_at` is null) count_row_table",
"bindings": [],
"time": 0.79
},
{
"query": "select `id`, `name`, `price` from `product` where `product`.`deleted_at` is null",
"bindings": [],
"time": 0.68
}
],
"input": []
}
My HTML table:
<table class="table table-bordered" id="tabelStokBarang">
<thead>
<tr>
<th>ID</th>
<th>Nama Barang</th>
<th>Harga Barang</th>
</tr>
</thead>
</table>
My JavaScript:
$('#tabelStokBarang').DataTable({
processing: true,
serverSide: true,
ajax: '{!! route('admin.product.stock.getAll') !!}',
columns: [
{ data: 'id', name: 'id' },
{ data: 'name', name: 'name' },
{ data: 'price', name: 'price' }
]
});
My result in table is still "No data available". I don't know what I've missed.
Remove columns to match your data because you're returning rows as arrays but with columns property expecting rows to be objects with properties id, name and price. See the code below:
$('#tabelStokBarang').DataTable({
processing: true,
serverSide: true,
ajax: '{!! route('admin.product.stock.getAll') !!}'
});
Another potential problem is that your draw parameter is 0. Your script should return draw parameter with the same value of the draw parameter in the request. I believe it starts at 1 and then increments with every request.
From the manual:
draw
The draw counter that this object is a response to - from the draw parameter sent as part of the data request. Note that it is strongly recommended for security reasons that you cast this parameter to an integer, rather than simply echoing back to the client what it sent in the draw parameter, in order to prevent Cross Site Scripting (XSS) attacks.

How to disable sorting on specific column while searching is functional

I am using DataTable (http://www.datatables.net) in order to get desired functionality including sorting columns and searching within columns from Table Heading individually. Initializing is as follow which returns api and searching functionality is achieved.
$('#table2').DataTable()
Now Problem is when I have to disable sorting on checkbox and I have to use following line of code.
$('#table2').dataTable( {
"aoColumnDefs": [
{ "bSortable": false, "aTargets": [ 0 ] }
] } );
it does apply sorting disabled on column but search functionality within column also doesn't work. Is there any way I can pass any parameter in DataTable({something}) in order to disable sorting on first column or please help me to combine (api & jquery object) method in order to achieve desired functionality.
$('#table2').DataTable();
$('#table2').dataTable();
<table class="table table-striped draggable sortable dataTable" id="table2">
<thead>
<tr>
<th class="text-center"> <input class="check_box_all no-sort" id="check_all" type="checkbox" title="Check All"></th>
<th class="text-center">Company Name </th>
</tr>
</thead>
<tbody>
<tr class="odd gradeX">
<td class="text-center"><input type="checkbox" class="check_box"></td>
<td class="text-center">Med Assets Company</td>
</tr>
</tbody>
This snippet makes input field in table heading for searching purpose
$('#table2 thead th').slice(3).each(function () {
var title = $('#table2 thead th').eq($(this).index()).text();
$(this).html('<input type="text" placeholder="' + title + '" />');
});
Data Table Initialize
var table = $('#table2').DataTable({
"dom": 'C<"clear">lfrtip',
"sPaginationType": "full_numbers",});
Applying the search
var tableResult = table.columns().eq(0);
if (tableResult !== null) {
tableResult.each(function (colIdx) {
$('input', table.column(colIdx).header()).on('keyup change', function () {
table
.column(colIdx)
.sort()
.search(this.value)
.draw();
});
});
}
Please check jsfiddle when check box is checked it totally mess up
https://jsfiddle.net/sxgd0thm/
$('#example').dataTable( {
"aoColumnDefs": [
{ "bSearchable": true, "aTargets": [ 0,1,2,3,4,5 ] }
] } );
Try with "bSearchable" with allowable column search
$('#table2').dataTable({
"dom": 'C<"clear">lfrtip',
"sPaginationType": "full_numbers",
"aoColumnDefs": [
{ "bSearchable": false, "aTargets": [ 0 ] },
{"bSortable": false, "aTargets": [ 1 ]}
]});
Can you try with this

Disable Sorting on every column except the first one

i'm currently using Datatables for a Custom system and i would like to disable Sort for every column but the first one.
I tried with the following code wich is working fine when i add values separated by comma
"aoColumnDefs": [
{ 'bSortable': false, 'aTargets': [ 1, 2, 3, 4 ] }
],
But my tables column number vary for each individual file so i can have 3 or maybe 12 columns, and i don't want to have to manually add the values for each file.
If i add more values than the columns i have in one file i get the following error, and an execution stop
Uncaught TypeError: Cannot read property 'className' of undefined
So, is there any way i can get those index and pass them to the function?
Thanks!
You can add a specific class to the TH element that you do not want to be sortable.
<table>
<thead>
<th>
...
</th>
<th class="no-sort">
...
</th>
</thead>
<tbody>
...
</tbody>
</table>
And then you can specify this class in your aTargets parameter.
"aoColumnDefs": [
{ 'bSortable': false, 'aTargets': ['no-sort'] }
]
View here for more information on the Column specific options.
And then you can specify this class in your aTargets parameter.
columnDefs: [ { orderable: false, targets: [1,2,3,4,5,6,7,8,9] } ]
This worked for me and seems more practical (though not exactly elegant)
columnDefs: [
{
"targets": [0],
"orderable": true
}, {
"targets": [''],
"orderable": false
}
]

Categories