Add child row as nested datatable within exisiting datatable - javascript

I have a datatable that lists a number of 'stages' (which relate to work employment procedures being carried out against the individual employee).
I have managed to code this so the table can display child rows. I want each child row to display another datatable which will list associated tasks for the selected stage.
So far I have managed to add and display a child row with the table header. See here:
[Child Row][1]
My HTML is as follows:
<div class="table-responsive">
<table class="table table-hover " id="stage_datatable">
<thead>
<tr>
<th>Select</th>
<th><!-- Detail --></th>
<th>ID</th>
<th>Stage</th>
<th>Title</th>
<th>Desc</th>
<th>Date/Time</th>
<th>Location</th>
<th>Rep Required</th>
<th>Logged By</th>
<th>Date Logged</th>
</tr>
</thead>
</table>
The Jquery for my stage table is here:
function loadStageTable (action, id) {
$.ajax ( {
url: './stages/stage_ajax.php',
method: 'GET',
data: {action: action, id:id}, // id could be taskID or caseID
dataType: 'json',
success: function (data) {
console.log(data);
console.log("success");
iTableCounter = 0;
var table = $('#stage_datatable').DataTable ( {
"searching": false,
"sort": false,
data:data,
select: {
style: 'os'
},
responsive: true,
columns: [
{ 'data': null },
{
"data": null,
"className": 'details-control',
"orderable": false,
"defaultContent": ''
},
{ 'data': 'meeting_id' },
{ 'data': 'stage_desc' },
{ 'data': 'meeting_title' },
{ 'data': 'meeting_desc' },
{ 'data': 'meeting_date_time' },
{ 'data': 'meeting_location' },
{ 'data': 'rep_required' },
{ 'data': 'logged_by' },
{ 'data': 'start_date' }
],
"columnDefs": [ {
"targets": -11,
"data": null,
"defaultContent": "<button class='btn btn-xs btn-primary'>Select</button>"
},
{
"targets": -3,
"className": "dt-body-center",
"render": function (data, type, full, meta){
var is_checked = data == true ? "checked" : "";
return '<input type="checkbox" class="checkbox" ' + is_checked + ' disabled />';
}
}]
});
console.log("stage datatable processed");
$('#stage_datatable tbody').on('click', 'td.details-control', function () {
var tr = $(this).parents('tr');
    var row = table.row( tr );
    if ( row.child.isShown() ) { // Close this row if already open
$('div.slider', row.child()).slideUp( function () {
row.child.hide();
tr.removeClass('shown');
} );
    }else {
// table id is required for child rows and will be unique
iTableCounter = iTableCounter + 1
row.child(getChildRow).show(); // call getChildRow function to obtain the child row html
var caseID = localStorage.getItem('caseID');
console.log(caseID);
loadMyTaskTable('get case tasks', caseID); // this is the AJAX function invoked to retrieve tasks. THIS DOESN'T WORK
tr.addClass('shown');
$('div.slider', row.child()).slideDown("slow");
    }
});
},
failure: function (data) {
console.log ("failed");
}
});
In the above I have coded an event that triggers the child row to be inserted:
$('#stage_datatable tbody').on('click', 'td.details-control', function () {
var tr = $(this).parents('tr');
var row = table.row( tr );
if ( row.child.isShown() ) { // Close this row if already open
$('div.slider', row.child()).slideUp( function () {
row.child.hide();
tr.removeClass('shown');
} );
}else {
// table id is required for child rows and will be unique
iTableCounter = iTableCounter + 1
row.child(getChildRow).show(); // call getChildRow function to obtain the child row html
var caseID = localStorage.getItem('caseID');
console.log(caseID);
loadMyTaskTable('get case tasks', caseID); // this is the AJAX function invoked to retrieve tasks
tr.addClass('shown');
$('div.slider', row.child()).slideDown("slow");
}
});
The getChildRow is as follows:
function getChildRow() {
var x = innerTaskTableTemplate(iTableCounter, taskTableTemplate());
return x;
}
The taskTableTemplate parameter is as follows:
function taskTableTemplate() {
return '<thead>'+
'<tr>'+
'<th>Select</th>'+
'<th>ID</th>'+
'<th>Task Title</th>'+
'<th>Desc</th>'+
'<th>Due Date/Time</th>'+
'<th>Allocated To</th>'+
'<th>Logged By</th>'+
'<th>Date Logged</th>'+
'</tr>'+
'</thead>'+
'<tbody></tbody>';
}
And the innerTaskTableTemplate function is as follows:
function innerTaskTableTemplate(tableID, html) {
var sOut = "<div class='slider'><table id='task_table_" + tableID + "'>";
sOut += html;
sOut += "</table></div>";
console.log(sOut);
return sOut;
}
IF I OMIT THIS LINE from my **loadStageTable ** function then the code successfully adds a child row and inserts the table html.
loadMyTaskTable('get case tasks', caseID);
However, if I include the line then the child row seems to disappear. If I inspect the DOM using firebug I can't find my child row (e.g. 'task_table_1'). See [here][2].
The loadMyTaskTable function is as follows:
function loadMyTaskTable (action, id) {
$.ajax ( {
url: './tasks/task_ajax.php',
method: 'GET',
data: {action: action, id:id}, // id could be taskID or caseID
dataType: 'json',
success: function (data) {
console.log(data);
var taskTable = $('#task_table_1')
$(taskTable).DataTable ( {
data:data,
select: {
style: 'os'
},
responsive: true,
columns: [
{ 'data': null },
{ 'data': 'task_id' },
{ 'data': 'task_title' },
{ 'data': 'task_desc' },
{ 'data': 'task_due_date' },
{ 'data': 'allocated_to' },
{ 'data': 'logged_by' },
{ 'data': 'start_date' }
],
"columnDefs": [ {
"targets": -8,
"data": null,
"defaultContent": "<button class='btn btn-xs btn-primary'>Select</button>"
}]
});
console.log("task table successfully loaded");
},
failure: function (data) {
console.log ("failed");
}
});
}
Please can you let me know where I am going wrong. i am confident that my AJAX is working fine as I've tried adding the task table html onto the main page and it loads properly this way, but not when I dynamically insert it as a child row in my datatable.
I have tried looking at similar other posts (e.g. [click here][3]) but I think that the code has since been superseded by the datatables new API.
Many thanks.
Additional Detail
I have debugged the script and found the following:
The script successfully inserts the child row with the task_table_1 html
The child row is subsequently removed from the DOM once it hits the *console.log("task table successfully loaded"); * line in my loadMyTaskTable function.
Am still not sure what I am doing wrong here.

Related

JQuery Datatable Reload From Server MVC

I have a Datatable of JQuery generated at first-page load. I am trying to refresh it according to the selected criteria from the selectlist.
My Datatable initialized first like the following code.
<table class="table table-striped table-hover" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>Select All <input type="checkbox" class="checkbox" id="chkBoxAll"></th>
#foreach (System.Data.DataColumn col in Model.DataTypesTable.Columns)
{
<th> #col.Caption</th>
}
</tr>
</thead>
<tbody>
#foreach (System.Data.DataRow row in Model.DataTypesTable.Rows)
{
<tr>
<td> <input type="checkbox" class="checkbox" name="chkBox" value="#row.ItemArray[0]"></td>
#foreach (var cell in row.ItemArray)
{
<td>
#cell.ToString()
</td>
}
</tr>
}
</tbody>
</table>
<script>
$(document).ready(function() {
$('#dataTable').DataTable();
});
</script>
It initializes well at first. However, when I try to reload it on the selectlistchange event, it doesn't reload anything and displays an error like this.
DataTables warning: table id=dataTable - Requested unknown parameter 'Id' for row 0, column 0. For more information about this error, please see http://datatables.net/tn/4
<script type="text/javascript">
$("#slctDeviceList").change(function () {
var selectedValue = $("#slctDeviceList option:selected").text();
$.ajax({
traditional: true,
dataType: 'html',
type: "GET",
url: '#Url.Action("GetDeviceDataTypes", "Home")',
data: { slctDeviceList: selectedValue },
success: function (result) {
console.log("Success");
console.log(result);
$("#dataTable").DataTable({
destroy: true,
data: result,
columns: [
{ data: "Id", name: "Id" },
{ data: "Data Name", name: "Data Name" },
{ data: "Description", name: "Description" },
{ data: "Device Type", name: "Device Type" }
], columnDefs: [{
"defaultContent": "-",
"targets": "_all"
}]
});
},
error: function (result) {
console.log("error");
}
});
});
</script>
Controller:
public JsonResult GetDeviceDataTypes(string slctDeviceList)
{
ChartRepository repository = new ChartRepository();
System.Data.DataTable dt = repository.GetDataTypes(slctDeviceList);
var json = this.Json(new { data = dt }/*, _jsonSetting*/);
return json;
}
My data is like below from the developer tools:
Please help me out to resolve the issue... Thanks in advance.
After long tries and losing hairs.. I have found a solution clear and add the rows again instead of destroy command. Here is the solution below.
<script type="text/javascript">
$("#slctDeviceList").change(function () {
var selectedValue = $("#slctDeviceList option:selected").text();
$.ajax({
traditional: true,
dataType: 'json',
type: "GET",
url: '#Url.Action("GetDeviceDataTypes", "Home")',
data: { slctDeviceList: selectedValue },
success: function (result) {
console.log("Success");
var dataTable = $("#dataTable").DataTable();
dataTable.clear().draw();
$.each(result, function myfunc (index, value) {
// use data table row.add, then .draw for table refresh
dataTable.row.add([
'<input type="checkbox" class="checkbox" name="chkBox" value="' + value.Id + '">',
value.Id,
value.DataName,
value.Description,
value.DeviceType
]).draw();
});
},
error: function (result) {
console.log("error");
}
});
});
</script>
Also, it is important to return a json object from the controller action.
PS. If the Json Object has an initial tag like data, you may need to change the looping value.Id to value.data.Id. But it is better to not use any tag.
public JsonResult GetDeviceDataTypes(string slctDeviceList)
{
ChartRepository repository = new ChartRepository();
System.Data.DataTable dt = repository.GetDataTypes(slctDeviceList);
JsonSerializerSettings _jsonSetting = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore };
var json = this.Json(dt , _jsonSetting);
return json;
}

Pass and Get Id to Ajax with datatable

Loan account number is a unique number that I want to get and pass to query the database. As of now, With the code below, I could select each column but couldn't select number longer than five.
So since that didn't work, I am trying to see if I can pass Id so as to select the account no and pass it to the controller.
$(document).ready(function () {
$('#dailyload').DataTable({
pageLength: 10,
ajax: {
url: '/DailyInterest/Details',
dataSrc: ''
},
columns: [
{
title: "Loan Account No",
data: 'loanAccountNo'
},
{
title: "Loan Amount Written off",
data: 'amountWrittenOff'
}
]
});
var table = $('.dataTable').on('click', 'tbody td', function() {
//get textContent of the TD
console.log('TD cell textContent : ', this.textContent)
$.ajax({
type: "Get",
url: "/DailyInterest/GetInterestCalculated/" + this.textContent,
contentType: "application/json",
success: function (result) {
console.log("this is the result: ",result )
}
})
}).data());
})
})
``

onClick function for button inside jquery DataTable

I have a button for each row inside my jquery DataTable. I want when I click the button to alert the value of the first columns of the selected record.
The problem is that, with the code I have for the button, it does not work.
This is the documentation that I have followed: https://datatables.net/examples/ajax/null_data_source.html
Here is my code:
jQuery
$(document).ready(function () {
$.ajax({
type: "POST",
url: "WebService1.asmx/Bind",
dataType: 'json',
success: function (data) {
$('#datatable').DataTable({
data: data,
columns: [
{ 'data': 'CenterID' },
{ 'data': 'CenterName' },
{ 'data': 'LicenseKey' },
{ 'data': 'ExpiryDate' },
{ 'data': 'YearID' },
{ 'data': 'Date' },
// This is where I add the button
{ "defaultContent": "<button>Edit</button>"}
]
});
}
});
//This is where I make an attempt to add functionality for the button in the datatable
$('#datatable tbody').on('click', 'button', function () {
var data = table.row($(this).parents('tr')).data();
alert("The value is: " + data[0]);
});
});
HTML
<table id="datatable" class="display" style="width: 100%">
<thead>
<tr>
<th>CenterID</th>
<th>CenterName</th>
<th>LicenseKey</th>
<th>ExpiryDate</th>
<th>YearID</th>
<th>Date</th>
<th>Action</th>
</tr>
</thead>
</table>
Please assist. Thank you.
So after a lot of research, I got it. I had to change the button function.
$('#datatable tbody').on( 'click', 'button', function () {
var tr = $(this).closest('tr');
var value = $(tr).find('td').eq(0)[0].innerHTML;
alert(value);
return false;
});
If anyone has a better way of doing this, please let me know.

Two way data binding using jQuery dataTable and ASP.NET MVC

I have a form which gets it's data using jQueryDataTable.
$('#myTableName').DataTable(
{
"ajax": {
"url": "/API/Loaddata",
"type": "GET",
"datatype": "json"
},
"columns": [
{
"data": "IsSelected",
"render": function (data, type, row) {
if (type === 'display') {
return '<input type="checkbox" class="editor-active">';
}
return data;
},
"className": "dt-body-center"
// "autoWidth": true
},
{ "data": "Name", "autoWidth": true }
],
"rowCallback": function (row, data) {
// Set the checked state of the checkbox in the table
$('input.editor-active', row).prop('checked', data.active == 1);
}
}
);
Now to get data I have following code,
private static IEnumerable<CircState> rCirc;
[AllowAnonymous]
public ActionResult LoadData()
{
rCirc= _repo.GetAll().OrderBy(circ => circ.ID).Select(x => new CState { IsSelected = true, Name = x.Name });
return Json(new { data = circuits }, JsonRequestBehavior.AllowGet);
}
This works fine an I get following JSON, which is bound to my view:
{
"data":
[
{"IsSelected":true,"Name":"SMyDataPoint__01"},
{"IsSelected":true,"Name":"SMyDataPoint__04"},
{"IsSelected":true,"Name":"SMyDataPoint__07"},
{"IsSelected":true,"Name":"SMyDataPoint__08"},
{"IsSelected":true,"Name":"SMyDataPoint__09"},
{"IsSelected":true,"Name":"SMyDataPoint__10"},
{"IsSelected":true,"Name":"SMyDataPoint__11"}
]
}
This is my UI code:
<div class="form-group">
#Html.LabelFor(model => model.Cirs, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-5">
<table id="filtersTable">
<thead>
<tr>
<th>Select</th>
<th>Name</th>
</tr>
</thead>
</table>
</div>
</div>
Now when I am tick/untick an item and click on submit button, How can I get the unslected items.
What I need is two-way binding between View and Model , so When I call following code , I should get all the items based on there state(true/false).
$('#btnRunReport').click(function (e) {
e.preventDefault();
$.ajax({
type: "GET",
url: "/Circuits/SelectedCircs/",
success: function (result) {
console.log(result);
},
error: function (result) {
console.log('Error');
}
});
});
[AllowAnonymous]
public ActionResult SelectedCirs()
{
//rCirc is the global variable decalred on top (In First API)
var selectedCircs = rCirc.Where(x => x.IsSelected == false);
return Json(selectedCircuits);
}

JQuery DataTable resets on button click

I am using jQuery DataTables on a site that features the regular searchbox and some preset buttons that sort the table by column when pressed. The code does indeed sort the table when the button resets, but it immediately resets within 1/2 second. Here is my code:
//CATEGORY BUTTONS
$("#Term").on('click', function (event) {
dataTable.column(2).search('Term').draw();
});
I've searched around and looked at many forums. This should be correct, but the result always instantly resets the form. I've removed the search box functionality to see if that was interfering and causing the issue, but the issue remained. It just blinks the results up really fast and then resets it all to showing the entire list again. Could this be a thing with Internet Explorer (this machine has no access to any other browsers)?
Here is the full code:
$(document).ready(function () {
//USES API FOR DYNAMIC SEARCHING
//RENDERS TABLE
var dataTable = $("#videos").DataTable({
"paging": false,
bjQueryUI: true,
ajax: {
url: "/api/videos",
dataSrc: ""
},
columns: [
{
width: "70%",
data: "title",
render: function (data, type, video) {
var videoTitle = video.title.toUpperCase();
return "<VideoItem><a href='" + "../" + video.url + "'>" + "<spacerTop>" + videoTitle + "</spacerTop></a></VideoItem>";
}
},
{
width: "10%",
visible: false,
data: "description",
render: function (data) {
return data;
}
},
{
width: "10%",
visible: false,
data: "categoryName",
render: function (data) {
return data;
}
},
{
width: "10%",
visible: false,
data: "meta",
render: function (data) {
return data;
}
},
{
width: "10%",
visible: false,
data: "date",
render: function (data) {
return data;
}
},
{
width: "10%",
visible: false,
data: "categoryID",
render: function (data) {
return data;
}
}
]
});
//CONTROLS DELETE BUTTON ACTION
$("#videos").on("click", ".js-delete", function () {
var button = $(this);
bootbox.confirm("Are your sure you want to delete this video?", function (result) {
if (result) {
$.ajax({
url: "/api/videos/" + button.attr("data-video-id"),
method: "DELETE",
success: function () {
button.parents("tr").remove();
}
});
}
});
});
//MAKES SEARCH BOX ON TOP INTERACT WITH DATATABLE
$(".search-box-input").keyup(function () {
dataTable.search(this.value).draw();
});
//CATEGORY BUTTONS
$("#Term").on('click', function (event) {
dataTable.column(2).search('Term').draw();
});
});

Categories