Datatables serverside info + static colum with 2 buttons - javascript

I'm struggeling to make a static column with 2 buttons that trigger 2 links with dynamic data. I managed to make 1 button work but i can't make the other. I tried adding an id to each one and call different functions for each one but it seems it's only working with $(\'#example tbody \') and not ($(\'#customID \').
Here is my js:
<script type="text/javascript">
$(document).ready(function() {
var table = $(\'#example\').DataTable( {
"processing": true,
"serverSide": true,
"ajax": "app/server_processing.php",
"columnDefs": [ {
"targets": -1,
"data": null,
"defaultContent": "<button>Edit</button> <button>Delete</button>"
} ]
} );
$(\'#example tbody \').on( \'click\', \'button\', function () {
var data = table.row( $(this).parents(\'tr\') ).data();
window.location.href = "index.php?categ=edit&id="+ data[0];
} );
} );
</script>

I fixed it
<script type="text/javascript">
$(document).ready(function() {
var table = $(\'#example\').DataTable( {
"processing": true,
"serverSide": true,
"ajax": "app/server_processing.php",
"columnDefs": [ {
"targets": -1,
"data": null,
"defaultContent": "<button id="edit">Edit</button> <button id="delete">Delete</button>"
} ]
} );
$(\'#example tbody \').on( \'click\', \'#edit\', function () {
var data = table.row( $(this).parents(\'tr\') ).data();
window.location.href = "index.php?categ=edit&id="+ data[0];
} );
$(\'#example tbody \').on( \'click\', \'#delete\', function () {
var data = table.row( $(this).parents(\'tr\') ).data();
window.location.href = "index.php?categ=delete&id="+ data[0];
} );
} );
</script>

Related

Server-side processing DataTables

I'm trying to dynamically load data into a table, but on each page all records are loaded at once.
my html:
<table cellspacing="0" class="display cell-border table table-sm table-striped table-bordered" width="100%" id="audience">
<thead>
<tr>
<th>Корпус</th>
<th>Этаж</th>
<th>Комната</th>
<th>Тип</th>
<th>Подразделение</th>
<th>Мест</th>
<th>Компьютерных мест</th>
<th>Действия</th>
</tr>
</thead>
</table>
js
<script>
$(document).ready(function() {
var table = $('#audience').DataTable(
{
"serverSide": true,
"processing": true,
"ajax": '/ajax/audience/zxv',
"data": JSON,
"columns": [
{ "data": "Корпус"},
{ "data": "Этаж"},
{ "data": "Комната"},
{ "data": "Тип"},
{ "data": "Подразделение"},
{ "data": "Мест"},
{ "data": "Компьютерных мест"},
{ "data": "Действия"}
],
language: tables_lang,
pageLength: 10,
orderCellsTop: true,
fixedHeader: true,
dom: 'l<"toolbar">frtip',
initComplete: function(){
$("div.toolbar")
.html('<button class="btn btn-success ml-3 add_audience">Добавить</button');
}
});
$('#audience thead tr').clone(true).appendTo( '#audience thead' );
$('#audience thead tr:eq(1) th').each( function (i) {
var title = $(this).text();
$(this).html( '<input type="text" placeholder="Поиск" />' );
$( 'input', this ).on( 'keyup change', function () {
if ( table.column(i).search() !== this.value ) {
table
.column(i)
.search( this.value )
.draw();
}
} );
} );
table.state.clear();
table.draw();
});
</script>
php
if($request->hasValue("zxv")){
//i call the function to find out which page is now
$draw = $audienceHome->getDrawDatatables();
$data = array(
'draw' =>($draw),
'recordsTotal' =>("680"),
'recordsFiltered' =>("680"),
'data'=>
array()
);
//filled in the data from the DB
//i just get data from database using sql query and put it in array
$arr = $audienceHome->tesr();
$data['data'] = $arr;
echo json_encode($data);
}
what do i getting in json:
the table simply displays all the records at once, as well as when switching the page, regardless of how much I put 10,25,50
what should I do? so that the records are loaded gradually? Thanks in advance!

Nested Datatable returns undefined rowData on Ajax call

*
My Task is to get Nested DataTbless after making an ajax call.
I'm Getting the function working. Everytime I make a call it returns the data in main Datatable.
But, On Ajax call it gives me rowData is undefined error in Nested datatable.
Since I'm new at using Jquery I couldn't figure out the logical solution.
*
function ts_data(tabledata,tableChild,Expected_hrs,Hours_logged,Working_days,table_month){
$(document).ready(function() {
var table=$('#example').DataTable( {
"data": tabledata,
"retrieve": true,
"columns": [{
className: 'details-control',
orderable: false,
data: null,
defaultContent: ''
},
{ "data": "Fullname"},
{ "data": "Hours" },
{ "data": "Present_Hours_month"},
{ "data": "Working_Days" },
{ "data": "Month_Year"}],
"order": [[1, 'asc']]
} );
function format ( rowData ) {
console.log(rowData);
var file = jQuery.grep(tableChild, function(obj) {
return obj.Fullname === rowData.Fullname;});
var div = $('<table/>');
div.DataTable( {"paging": false,
"ordering": true,
"info": false,
"data": file,
"columns": [
{ "title": "Fullname", "data": "Fullname" },
{ "title": "Date","data": "Date" },
{ "title": "Day","data": "Day" },
{ "title": "Logged_Hours","data": "Logged_Hours" },
{ "title": "Present_Hours","data": "Present_Hours" }],
"order": [[1, 'asc']]})
return div;
}
// 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
row.child( format(row.data()) ).show();
tr.addClass('shown');
}
} );
});
};
function getMonth(){
$(document).ready(function() {
var month_yr = $('#recent').val();
$("#AjaxLoader").show();
$.getJSON('/attendance_log' + '/' + month_yr,
function(data) {
var tabledata = data.Main,
tableChild = data.Child,
Expected_hrs = data.Expected_hrs,
Hours_logged = data.Hours_logged,
Working_days = data.Working_days;
table_month = data.table_month;
console.log(tabledata);
/* Formatting function for row details - modify as you need */
document.getElementById("table_name").innerHTML = "Attendance log for " + table_month + " Month";
$("#AjaxLoader").hide();
ts_data(tabledata,tableChild,Expected_hrs,Hours_logged,Working_days,table_month);
});
})
}
var startDate = new Date();
$('.from').datepicker({
autoclose: true,
minViewMode: 1,
format: 'mm-yyyy'
}).on('changeDate', function(selected){
startDate = new Date(selected.date.valueOf());
startDate.setDate(startDate.getDate(new Date(selected.date.valueOf())));
$('.to').datepicker('setStartDate', startDate);
});
window.onload = function(){
var today = new Date().toISOString().substr(0, 10);
var month_yr = today.substring(5, 7) +"-" + today.substring(0,4);
document.getElementById("recent").setAttribute("value", month_yr);
getMonth()
};

Function to get row data works only in responsive mode in Datatables

When I click on the image in Reponsive mode, it will return the row data in console. But in normal view I get Undefined error.
var table = $('.dataTable').DataTable({
"responsive": true,
"columnDefs": [{
"targets": 4,
"data": null,
"render": function (data, type, full, meta) {
if (type === 'display') {
data = "<a href='#' width='30px' class='editMe' data='" + full[0] + "'><img src='/images/edit.png' width='30px' /></a>";
}
return data;
}
} ,
{
"targets": 0,
"visible": false,
"searchable": false
}]
});
$('.dataTable').on('click', '.editMe', function () {
console.log(table.row(this).data());
});
Use the code below instead:
$('.dataTable').on('click', '.editMe', function () {
var $row = $(this).closest('tr');
if($row.hasClass('child')){ $row = $row.prev(); }
console.log(table.row($row).data());
});
See this example for code and demonstration.

Why would blur event only fire one time? [duplicate]

I have a couple of drop downs that are populated from SharePoint using SPServices. This part works great. But then, I have a button that on click loads data from SharePoint and uses the dropdown texts as filter to fetch the data that will populate a table using the DataTables plugin. This part works only once; if I click the button again, nothing happens.
This is how I populate the dropdowns:
$(document).ready(function () {
var theYear; // Selected Year
var theRO; // Selected RO
//Fills the Dropdown lists (Year and RO)
$().SPServices({
operation: "GetListItems",
async: false,
listName: "{ListID}",
CAMLViewFields: "<ViewFields><FieldRef Name='Fiscal_x0020_Year' /><FieldRef Name='Regional_x0020_Office' /></ViewFields>",
completefunc: function (xData, Status) {
//Add Select Value option
$("#dropdown").prepend($('<option>', {
value: '',
text: 'Select Fiscal Year'
}));
$("#dropdownRO").prepend($('<option>', {
value: '',
text: 'Select Regional Office'
}));
//Fetching Data from SharePoint
$(xData.responseXML).SPFilterNode("z:row").each(function () {
var dropDown = "<option value='" + $(this).attr("ows_Fiscal_x0020_Year") + "'>" + $(this).attr("ows_Fiscal_x0020_Year") + "</option>";
var dropDownRO = "<option value='" + $(this).attr("ows_Regional_x0020_Office") + "'>" + $(this).attr("ows_Regional_x0020_Office") + "</option>";
$("#dropdown").append(dropDown);
$("#dropdownRO").append(dropDownRO);
/////////////Deletes duplicates from dropdown list////////////////
var usedNames = {};
$("#dropdown > option, #dropdownRO > option").each(function () {
if (usedNames[this.text]) {
$(this).remove();
} else {
usedNames[this.text] = this.value;
}
});
////Deletes repeated rows from table
var seen = {};
$('#myTable tr, #tasksUL li, .dropdown-menu li').each(function () {
var txt = $(this).text();
if (seen[txt]) $(this).remove();
else seen[txt] = true;
});
});
} //end of completeFunc
}); //end of SPServices
$('.myButton').on('click', function () {
run()
});
}); //End jQuery Function
This is the function I need to run every time I click on "myButton" after changing my selection in the dropdowns:
function run() {
theYear = $('#dropdown option:selected').text(); // Selected Year
theRO = $('#dropdownRO option:selected').text(); // Selected RO
var call = $.ajax({
url: "https://blah-blah-blah/_api/web/lists/getByTitle('Consolidated%20LC%20Report')/items()?$filter=Fiscal_x0020_Year%20eq%20'" + theYear + "' and Regional_x0020_Office eq '" + theRO + "'&$orderby=Id&$select=Id,Title,Fiscal_x0020_Year,Notices_x0020_Received,Declined_x0020_Participation,Selected_x0020_Field_x0020_Revie,Selected_x0020_File_x0020_Review,Pending,Pending_x0020_Previous_x0020_Yea,Controversial,GFP_x0020_Reviews,NAD_x0020_Appeals,Mediation_x0020_Cases,Monthly_x0020_Cost_x0020_Savings,Monthly_x0020_Expenditure,Regional_x0020_Office,Month_Number", //Works, filters added
type: "GET",
cache: false,
dataType: "json",
headers: {
Accept: "application/json;odata=verbose",
}
}); //End of ajax function///
call.done(function (data, textStatus, jqXHR) {
var oTable = $('#example').dataTable({
"aLengthMenu": [
[25, 50, 100, 200, -1],
[25, 50, 100, 200, "All"]
],
"iDisplayLength": -1, //Number of rows by default. -1 means All Records
"sPaginationType": "full_numbers",
"aaData": data.d.results,
"bJQueryUI": false,
"bProcessing": true,
"aoColumns": [{
"mData": "Id",
"bVisible": false
}, //Invisible column
{
"mData": "Title"
}, {
"mData": "Notices_x0020_Received"
}, {
"mData": "Declined_x0020_Participation"
}, {
"mData": "Selected_x0020_Field_x0020_Revie"
}, {
"mData": "Selected_x0020_File_x0020_Review"
}, {
"mData": "Pending"
}, {
"mData": "Pending_x0020_Previous_x0020_Yea"
}, {
"mData": "Controversial"
}, {
"mData": "GFP_x0020_Reviews"
}, {
"mData": "NAD_x0020_Appeals"
}, {
"mData": "Mediation_x0020_Cases"
}, {
"mData": "Monthly_x0020_Cost_x0020_Savings",
"fnRender": function (obj, val) {
return accounting.formatMoney(val);
}
}, {
"mData": "Monthly_x0020_Expenditure",
"fnRender": function (obj, val) {
return accounting.formatMoney(val);
}
}],
"bDeferRender": true,
"bRetrieve": true,
"bInfo": true,
"bAutoWidth": true,
"bDestroy": true,
"sDom": 'T&;"clear"&;frtip',
"oTableTools": {
"aButtons": ["xls"],
"sSwfPath": "../../Style Library/js/datatables/TableTools/media/swf/copy_csv_xls_pdf.swf",
},
"sSearch": "Filter",
"fnDrawCallback": function () {
//Add totals row
var Columns = $("#example > tbody").find("> tr:first > td").length;
$('#example tr:last').after('<tr><td class="total"></td><td class="total"></td><td class="total"></td><td class="total"></td><td class="total"></td><td class="total"></td><td class="total"></td><td class="total"></td><td class="total"></td><td class="total"></td><td class="total"></td><td class="total"></td><td class="total"></td><td class="total"></td></tr>');
//Formating the Total row number to no decimals
$("#example tr:last td:not(:first,:last)").text(function (i) {
var t = 0;
$(this).parent().prevAll().find("td:nth-child(" + (i + 2) + ")").each(function () {
t += parseFloat($(this).text().replace(/[\$,]/g, '') * 1);
});
return parseInt(t * 100, 10) / 100;
});
//Format the monthly expenditure and savings to currency formatFormating the currency
var cell = new Array();
cell[0] = $('#example tr:last td:nth-child(12)').text();
cell[1] = $('#example tr:last td:nth-child(13)').text();
$('#example tr:last').find('td:nth-child(12)').html(accounting.formatMoney(cell[0]));
$('#example tr:last').find('td:nth-child(13)').html(accounting.formatMoney(cell[1]));
$('#example tr:last').find('td:last').hide();
} //hides extra td that was showing
}); //End of Datatable()
}); //End of call.done function
$('#theTableDiv').slideDown();
} //end of run() function
I'm not a programmer, I'm just trying to learn. I would appreciate any help. Thanks in advance
I would guess that you are replacing the part of the page where the button lives. (you really need to format your code more neatly for SO... use JSFiddle.net and their TidyUp button).
If that is the case you need to use a delegated event handler:
$(document).on('click', '.myButton', function () {
run()
});
This listens at a static ancestor of the desired node, then runs the selector when the event occurs, then it applies the function to any matching elements that caused the event.
document is the fallback parent if you don't have a convenient ancestor. Do not use 'body' for delegated events as it has odd behaviour.

DataTables plugin is not working when hiding a details

I am using the DataTables jQuery plugin and I am having a problem when I want to insert a hide details option on my existing table, this is how this option should look like: LINK
My problem is that table head is inserted correctly but I am not seeing a table column with plus sign to expand and see details.
Here is my code and as you can see it is almost incidental as it is on the link that I provided.
The code:
/* Formating function for row details */
function fnFormatDetails ( oTable, nTr )
{
var aData = oTable.fnGetData( nTr );
var sOut = '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">';
sOut += '<tr><td>Rendering engine:</td><td>'+aData[1]+' '+aData[4]+'</td></tr>';
sOut += '<tr><td>Link to source:</td><td>Could provide a link here</td></tr>';
sOut += '<tr><td>Extra info:</td><td>And any further details here (images etc)</td></tr>';
sOut += '</table>';
return sOut;
}
$(document).ready(function() {
/*
* Insert a 'details' column to the table
*/
var nCloneTh = document.createElement( 'th' );
var nCloneTd = document.createElement( 'td' );
nCloneTd.innerHTML = '<img src="../images/details_open.png">';
nCloneTd.className = "center";
$('#jphit thead tr').each( function () {
this.insertBefore( nCloneTh, this.childNodes[0] );
} );
$('#jphit tbody tr').each( function () {
this.insertBefore( nCloneTd.cloneNode( true ), this.childNodes[0] );
} );
var oTable=$('#jphit').dataTable( {
"sDom": 'T,C<"clear">lfrtip',
"oTableTools": {
"sSwfPath": "swf/copy_csv_xls_pdf.swf"
},
"oColVis": {
"buttonText": "Extend table",
"activate": "mouseover"
},
"aoColumnDefs": [
{ //"bVisible": false, "aTargets": [ 0 ],
"bSortable": false, "aTargets": [ 0 ] }
],
"aaSorting": [[1,'asc']],
"bProcessing": true,
"bServerSide": true,
"sPaginationType": "full_numbers",
"sScrollY": "350px",
"bDeferRender": true,
"sAjaxSource": "increment_table.php"
} );
/* Add event listener for opening and closing details
* Note that the indicator for showing which row is open is not controlled by DataTables,
* rather it is done here
*/
$('#jphit tbody td img').live('click', function () {
var nTr = $(this).parents('tr')[0];
if ( oTable.fnIsOpen(nTr) )
{
/* This row is already open - close it */
this.src = "../images/details_open.png";
oTable.fnClose( nTr );
}
else
{
/* Open this row */
this.src = "../images/details_close.png";
oTable.fnOpen( nTr, fnFormatDetails(oTable, nTr), 'details' );
}
} );
} );
As I was debugging I realized that this code is processed but its not drawing what it should draw:
$('#jphit tbody tr').each( function () {
this.insertBefore( nCloneTd.cloneNode( true ), this.childNodes[0] );
} );
Any idea what might went wrong with my code? And if someone is using this plugin can you please help and share your experience?
EDIT:
This is the picture that I am getting. It should be shifted one spot to the right and in that empty column I should have a pic for opening a details
EDIT2:
I have tried to use this code with data that I wrote manually inside the table and it is working perfectly.
I have tired to put the code inside the fnDrawCallback function but then I have 2 headers as my table is drawing twice.
How to use this with sAjaxSource?
var oTable = $('#jphit').dataTable( {
"sDom": 'T,C<"clear">lfrtip',
"oTableTools": {
"sSwfPath": "swf/copy_csv_xls_pdf.swf"
},
"oColVis": {
"buttonText": "Extend table",
"activate": "mouseover"
},
"aoColumnDefs": [
{ //"bVisible": false, "aTargets": [ 0 , 2 ] ,
"bSortable": false, "aTargets": [ 0 ] }
],
"bProcessing": true,
//"bServerSide": true,
"sPaginationType": "full_numbers",
"sScrollY": "350px",
"bDeferRender": true,
//"sAjaxSource": "live_table.php",
"fnDrawCallback": function( oSettings ) {
var nCloneTh = document.createElement( 'th' );
var nCloneTd = document.createElement( 'td' );
nCloneTd.innerHTML = '<img src="images/details_open.png" style="width:25px; height:25px;">';
nCloneTd.className = "center";
$('#jphit thead tr').each( function () {
this.insertBefore( nCloneTh, this.childNodes[0] );
} );
$('#jphit tbody tr').each( function () {
this.insertBefore( nCloneTd, this.childNodes[0] );
} );
}
} );
The problem here is that table renders data based on data from response. I suppose that there is aaData array where 0 index is filled with value, which is inserted in the first column as expected.
You can use this approach http://datatables.net/release-datatables/examples/ajax/null_data_source.html
In your case you could change aoColumnDefs option to:
"aoColumnDefs": [ {
"bSortable": false, mData : null, "aTargets": [ 0 ]
}],
EDIT Override fnServerData
The other idea I have is to override fnServerData callback, to change datasource as you need.
"fnServerData": function ( sSource, aoData, fnCallback, oSettings ) {
oSettings.jqXHR = $.ajax( {
"dataType": 'json',
"type": "POST",
"url": sSource,
"data": aoData,
"success": function(jsonData) {
//Here you need to shift jsonData aoData array values to right
//to add [0] index in all values.
//I have no possibility to test it today:( but hope it will help you
//and Then you need to call fnCallback(jsonData) with changed jsonData
for (var data in jsonData["aoData"]) {
jsonData["aoData"][data].unshift(0);
}
fnCallback(jsonData);
}
} );
}
Hope it helps.

Categories