I have a simple messaging system and I am retrieving the messages from the DB using jQuery/AJAX and appending to a table. I wanted pagination for the messages so I opted to use the DataTables plugin (https://datatables.net/).
I am having trouble using this with my dynamically generated data. I also have functions such as "delete message" which would then delete the message and then retrieve the messages again (refresh the table). I am getting the error "cannot re-initialise DataTable".
This is my code so far:
function getmessages(){
$.ajax({
type: "POST",
url: "modules/ajaxgetmessages.php",
dataType: 'json',
cache: false,
})
.success(function(response) {
if(!response.errors && response.result) {
$("#tbodymessagelist").html('');
$.each(response.result, function( index, value) {
var messagesubject = value[3];
var messagecontent = value[4];
var messagetime = value[5];
var sendername = value[2];
var readstatus = value[7];
var messageid = value[8];
if (readstatus==0){
messageheader += '<tr><td><input type="checkbox" class="inboxcheckbox input-chk"></td><td class="sendername"><b>'+sendername+'</b></td><td class="messagesubject"><b>'+messagesubject+'</b></td><td><b>'+messagetime+'</b></td><td class="messageid" style="display:none">'+messageid+'</td><td class="readstatus" style="display:none">'+readstatus+'</td><td class="messagecontent" style="display:none"><b>'+messagecontent+'</b></td></tr>';
} else {
messageheader += '<tr><td><input type="checkbox" class="inboxcheckbox input-chk"></td><td class="sendername">'+sendername+'</td><td class="messagesubject">'+messagesubject+'</td><td>'+messagetime+'</td><td class="messageid" style="display:none">'+messageid+'</td><td class="readstatus" style="display:none">'+readstatus+'</td><td class="messagecontent" style="display:none"><b>'+messagecontent+'</b></td></tr>';
}
});
$("#tbodymessagelist").html(messageheader);
$('#tblinbox').DataTable({
"paging": true,
"ordering": false,
"info": false
});
} else {
$.each(response.errors, function( index, value) {
$('input[name*='+index+']').addClass('error').after('<div class="errormessage">'+value+'</div>')
});
}
});
}
So how can I essentially, make changes to my table after message deletion or other functions and then "refresh" the table? It also shows Showing 0 to 0 of 0 entries in the footer even though there are entries there.
You must destroy datatable berfore create new instance;
`
$('#tblinbox').DataTable.destroy();
$('#tblinbox').empty();
Related
I have an add feature that runs an insert query (using PDO).
The first insert works accordingly. It's the second run, and every run after that causes the query to duplicate times 2.
I have no idea why this is happening.
The user makes a selection, which populates a datatable (example1). They can then select one of the records (or lanes) which populates another datatable (example2).
Here is the initial onClick event:
$('#example1').on('click', 'tr > .laneClick', function(e){
e.preventDefault();
const dataTable = $('#example1').DataTable();
const rowData = dataTable.row($(this).closest('tr')).data();
let partnerCode = rowData['partner_code'];
let partnerName = rowData['partner_name'];
let groupName = rowData['groupname'];
let lanecriteria = {
partnerCode: partnerCode,
partnerName: partnerName,
groupName: groupName
}
displayLaneRecords(lanecriteria);
});
Here is the function displayLaneRecords, which displays the second datatable called "example2" after the .laneClick onClick event:
function displayLaneRecords(lanecriteria){
if(lanecriteria == ""){
let data = '';
}
else{
let data = {
lanecriteria: {
partnerCode: lanecriteria.partnerCode,
vesselProfile: lanecriteria.vesselProfile,
salesRep: lanecriteria.salesRep
}
}
}
$.ajax({
url: 'api/getLaneData.php',
type: 'POST',
data: data,
dataType: 'html',
success: function(data, textStatus, jqXHR){
var jsonObject = JSON.parse(data);
var table = $('#example2').DataTable({
"data": jsonObject,
"columns": [
// data columns
],
"dom": 'Bfrtip',
"buttons": [
{
text: '<i class="fa fa-plus"></i> Add Lane',
className: 'addLane btn btn-primary btn-sm',
action: function (e, dt, node, config){
// opens the form for processing
$('#addLaneModal').modal('show');
}
}
]
});
},
error: function(jqHHR, textStatus, errorThrown){
console.log('fail: '+ errorThrown);
return false;
}
}); // end ajaxcall
// here is where the form process will occur
} // end displayLaneRecords();
As you will see, the form process will occur within the displayLaneRecords() function. I had to do this so when the process is complete, I can repopulate the datatable without refreshing.
Here is the form process:
$('#addLaneSubmit').on('click', function(e){
e.preventDefault();
let partnerCode = $('#addlanepartnercode').val();
let partnerName = $('#addlanepartnername').val();
let groupName = $('#addlanegroupname').val();
let addlanecriteria = {
partnerCode: partnerCode,
partnerName: partnerName,
groupName: groupName
}
$.post('api/editLane.php', {addlanecriteria:addlanecriteria}, function(data){
if(data.indexOf('Error') > 1){
$('.message').text(data);
$('#errorModal').modal('show');
return false();
}
else{
$('.message').text(data);
$('#messageModal').modal('show');
$('#messageModal').on('hidden.bs.modal', function(){
$("#addLaneModal").modal('hide');
displayLaneRecords(lanecriteria); // call displayLaneRecords to refresh the table
});
}
});
});
The actual PHP process called editLane.php looks like this:
<?php
if(isset($_POST['addlanecriteria'])){
$value = $_POST['addlanecriteria'];
$partnerCode = isset($value['partnerCode']) ? $value['partnerCode'] : '';
$partnerName = isset($value['partnerName']) ? $value['partnerName'] : '';
$groupName = isset($value['groupName']) ? $value['groupName'] : '';
try{
$dbc->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$insert = $dbc->prepare("INSERT INTO table (`partner_code`, `partner_name`, `group_name`) VALUES (:newpartnercode, :newpartnername, :newgroupname)");
$insert->execute([
'newpartnercode' => $partnerCode ,
'newpartnername' => $partnerName ,
'newgroupname' => $groupName
]);
if($insert){
echo "Success: New Lane has been added.";
}
}
catch(PDOException $e){
echo "Error: " . $e->getMessage();
}
}
?>
I tried to minimize as much code as I could.
All of the above works without any visible errors. When the form is submitted, a new record is inserted into the table, and the datatable refreshes without the page refreshing.
The problem occurs when the user adds another record - the query duplicates, and instead of inserting 1 record, 2 are inserted. If they add another record, the query will insert 4 records.
What can I try next?
I am using jquery to send data through ajax to my DB, on success it shows a notification and adds a row to a datatable with the note / info the user just posted.
For some reason it's adding the row twice, instead of just once. Cant figure out why.
My code is :
<script type="text/javascript">
$(document).ready(function() {
$('#notestable').DataTable({
"paging": false,
"ordering": false,
"info": false,
"filter": false
});
$("#addnote").click(function(e) {
e.preventDefault();
var note = $("#note1").val();
var leadid = "<?echo $lead->leadid;?>";
$.ajax({
url: "/leads/addnote",
method: "POST",
data: {
note: note,
leadid: leadid
},
success: function(data) {
$('#closemodal12').trigger('click');
swal({
title: "Note added",
type: "success",
});
var notestable1 = $('#notestable').DataTable();
var lengthToCut = 23;
var short = note.substr(0, lengthToCut);
var i = 1;
var row = $('<tr>');
row.append('<td>' + short + ' </td>')
.append('<td><? echo $user->forename;?></td>')
.append('<td><? echo date('d / m / Y ');?> </td>')
.append('<td><? echo date('H: i ');?> </td>')
.append('<td><i class ="fa fa-eye"> </i></td>')
.append('<td><i class ="fa fa-trash-o"> </i></td>')
notestable1.row.add(row);
$('#notestable tbody').prepend(row);
},
error: function() {
alert("Slight problem");
}
});
});
});
</script>
Without seeing the markup that goes along with this, it's difficult to be sure, but I believe the problem lies with these two lines of code:
// Append row to notestable1 (already visible in DOM)
notestable1.row.add(row);
// (pre)Append the row again
$('#notestable tbody').prepend(row);
notestable1 appears to be a valid object, already inserted into the DOM, that you're appending the row to. You then append the row again using $('#notestable tbody').prepend(row).
why is this my data table not reloading?. In my situation, I have a data table named table_clinics that I declared global in my javascript, now I have other function to add a data within the data table, I want to prevent refresh that is why I want my data table to be reloaded after adding new data. Am I doing it wrong?.
Here is my code:
<script type="text/javascript">
var table_clinics;
$(document).ready(function() {
table_clinics = $('#dataTables-clinics').dataTable();
});
function show_clinics() {
$("#dataTables-clinics").dataTable().fnDestroy();
table_clinics = $('#dataTables-clinics').DataTable({
"ajax": {
"url": "<?php echo site_url('clinic_admin/myclinics')?>",
"type": "POST",
},
responsive: true,
bInfo: false,
});
}
</script>
now I have a function to add data from the data table and after success, i want to refresh my data table. Here is my function: i tried : table_clinics.ajax.reload(null,false); but it doesn't reload my data table. how can I do this?
function create_clinic() {
$('#btnCreateClinic').text('Saving...');
$('#btnCreateClinic').attr('disabled',true);
$.ajax({
url : siteurl+"clinic_admin/create_clinic",
type: "POST",
data: $('#frm_create_clinic').serialize(),
dataType: "JSON",
success: function(data)
{
if(data.status) {
table_clinics.ajax.reload(null,false);
alert('Added Sucessfuly');
}
else
{
for (var i = 0; i < data.inputerror.length; i++)
{
$('[name="'+data.inputerror[i]+'"]').parent().parent().addClass('has-error');
$('[name="'+data.inputerror[i]+'"]').next().text(data.error_string[i]);
}
}
$('#btnCreateClinic').text('Save'); //change button text
$('#btnCreateClinic').attr('disabled',false); //set button enable
},
error: function (jqXHR, textStatus, errorThrown)
{
alert('Error adding data' + jqXHR+ textStatus +errorThrown);
$('#btnCreateClinic').text('Save');
$('#btnCreateClinic').attr('disabled',false);
}
});
}
also tried this:
if(data.status) {
table_clinics = $("#dataTables-clinics").dataTable( { bRetrieve : true } );
table_clinics.fnDraw();
// Hide all tables
$('dataTables-clinics').hide();
// Show the refreshed
$('dataTables-clinics').show();
alert('Added Sucessfuly');
}
also i tried this one:
and i add https://cdn.datatables.net/plug-ins/1.10.15/api/fnReloadAjax.js.
if(data.status) {
table_clinics.fnReloadAjax('<?php echo site_url('"clinic_admin/myclinics"')?>');
table_clinics.fnReloadAjax();
alert('Added Sucessfuly');
}
Reload You datatable , Try this
$('#dynamic-table').DataTable().ajax.reload(); // id of table
You must call draw() on the datatable object.
var oTable = $('#yourDataTable').dataTable();
oTable.fnDraw();
See the example i have done. Click on Add New Data button in jsfiddle
I hope I can explain my issue clearly.
I am running a function to get values from a database using ajax, and adding each result as a row in a table. This is so the user can delete or edit any row they want. I'm adding IDs dynamically to the columns and also the edit and delete buttons which are generated. So it looks like this:
My code:
function getstationdata(){
var taildata1 = $('#tailnumber2').val();
var uid = $('#uid').val();
$.ajax({
// give your form the method POST
type: "POST",
// give your action attribute the value ajaxadd.php
url: "ajaxgetstationdata.php",
data: {tailnumber:taildata1, uid:uid},
dataType: 'json',
cache: false,
})
.success(function(response) {
// remove all errors
$('input').removeClass('error').next('.errormessage').html('');
// if there are no errors and there is a result
if(!response.errors && response.result) {
var trHTML = '';
$.each(response.result, function( index, value) {
trHTML += '<tr><td><input type="text" value="' + value[2] + '"></td><td><input type="text" class="weightinputclass"value="' + value[3] + '"></td><td><input type="text" class="arminputclass"value="' + value[4] + '"></td><td><input type="text" class="momentinputclass" value="' + value[5] + '"></td><td><button id="updatecgbtn" onclick="updatecg()"class="editbuttonclass">Edit</button></td><td><button id="deletecgbtn" class="deletebuttonclass"">Delete</button></td></tr>';
});
$('#mbtbody').html('');
$('#mbtbody').html(trHTML);
var ID = 0;
$('.weightinputclass').each(function() {
ID++;
$(this).attr('id', 'weightinputboxID'+ID);
});
var ID = 0;
$('.arminputclass').each(function() {
ID++;
$(this).attr('id', 'arminputboxID'+ID);
});
var ID = 0;
$('.momentinputclass').each(function() {
ID++;
$(this).attr('id', 'momentinputboxID'+ID);
});
var ID = 0;
$('.editbuttonclass').each(function() {
ID++;
$(this).attr('id', 'editbutton'+ID);
});
var ID = 0;
$('.deletebuttonclass').each(function() {
ID++;
$(this).attr('id', 'deletebutton'+ID);
});
} else {
// append the error to the form
$.each(response.errors, function( index, value) {
// add error classes
$('input[name*='+index+']').addClass('error').after('<div class="errormessage">'+value+'</div>')
});
}
});
}
The code I have when adding the info is in a form and it looks like this:
$('#addstations').on('submit', function(e){
e.preventDefault();
$.ajax({
type: $(this).attr('method'),
url: $(this).attr('action'),
data: $(this).serialize(),
dataType: 'json',
cache: false,
})
.success(function(response) {
$('input').removeClass('error').next('.errormessage').html('');
if(!response.errors && response.result) {
$.each(response.result, function( index, value) {
chartdata4=(tailnumber3.value)
});
} else {
// append the error to the form
$.each(response.errors, function( index, value) {
// add error classes
$('input[name*='+index+']').addClass('error').after('<div class="errormessage">'+value+'</div>')
});
}
});
});
I searched a bit on the internet and found out that I can't add a form inside my table for each row which would have been easy to do and I can reuse my code which I use when adding new info.
So, can someone please point me in the right direction?
Here is the direction you could go
$('#formTable').on('click',"button" function(e){
var $row = $(this).closest("tr"), $form = $("#addstations");
var data = {
passenger:$row.find("passengerClass").val(),
weight :$row.find("weightClass").val()
} // no comma on the last item
data["type"]=this.className=="deletebuttonclass"?"delete":"edit";
$.ajax({
type: $form.attr('method'),
url: $form.attr('action'),
dataType: 'json',
cache: false,
})
...
I assume that the problem is that you want to add a form as a child of a table / tbody element to wrap your row. You cannot do that and the browser will most likely strip the form tags, leaving you with nothing to serialize.
There are different solutions for that, for example:
Build the data object manually in javascript when a button on a row is clicked;
Use a non-form grid solution for your layout.
Add each row in its own table and have the form wrap that table
The third solution is a bit of a hack, I would use the first or the second myself.
In my project I'm using Parse.com as server and database, and DataTable plugin to create a table showing the data returned. There's no problem when I use a predefined json file, but when I try to construct a local json file using the data returned from Parse.com I get an error. It seems no matter what I do, the table creation process is run first and only afterwards the json object is created.
JSfiddle with the relevant code is here. Please note that due to the large amount of code I did not provide a working sample, but only the relevant part.
function getDataFromParse(){
console.log("test function run");
var loc_json={
"data":[]
};
//get data from parse
var parseTable = Parse.Object.extend("parseTable");
var tableObj = new parseTable();
var query = new Parse.Query(parseTable);
var count=0;
query.descending("createdAt");
query.find({
success: function(resultArr){
console.log("retreiving data from parse");
for(var i=0;i<resultArr.length;i++){
query.get(resultArr[i].id,{
success: function(tableObj){
var ret_phone = tableObj.get("phone");
var ret_first = tableObj.get("firstName");
var ret_last = tableObj.get("lastName");
var ret_status = tableObj.get("redemption_status");
var ret_vipCode = tableObj.get("vipCode");
loc_json.data.push([count,ret_first +" "+ret_last,ret_phone,tableObj.get("createdAt"),ret_vipCode]); //construction of local json
count++;
console.log("finished fetching data for "+ret_first+" "+ret_last);
},
error: function(object, error) {
console.log("could not do something "+error.message);
}
});
}
console.log("success function end");
},
error: function(error){
console.log(error.message);
}
});
console.log("trying to return json");
return loc_json;
}
var rows_selected = [];
console.log("table creation");
var table = $('#example').DataTable({
ajax: getDataFromParse(), // ajax: 'https://api.myjson.com/bins/4qr1g', THIS WORKS!!
columns: [
{},
{ data: 1},
{ data: 2 },
{ data: 3 }
],
'columnDefs': [{
'targets': 0,
'searchable':false,
'orderable':false,
'className': 'dt-body-center',
'render': function (data, type, full, meta){
return '<input type="checkbox">';
}
}],
'order': [1, 'asc'],
'rowCallback': function(row, data, dataIndex){
// Get row ID
$('input.editor-active', row).prop( 'checked', data[3] == 1 )
var rowId = data[0];
// If row ID is in the list of selected row IDs
if($.inArray(rowId, rows_selected) !== -1){
$(row).find('input[type="checkbox"]').prop('checked', true);
$(row).addClass('selected');
console.log("table trying to create itself");
}
}
});
SOLUTION
Remove ajax option from DataTables initialization options.
Call getDataFromParse() after initializing the DataTable
In the success handler for each query, replace this line:
loc_json.data.push([count, ret_first + " " + ret_last, ret_phone, tableObj.get("createdAt"), ret_vipCode]);
with the line below to add a new row to the table.
$('#example').DataTable()
.row.add([
count,
ret_first + " " + ret_last,
ret_phone,
tableObj.get("createdAt"),
ret_vipCode
])
.draw(false);
DEMO
See this jsFiddle for code and demonstration.
NOTES
The drawback of this solution is that a new row would be added once each query finishes successfully. Not sure if it is possible with Parse.com to handle event when all queries are completed.
Your example uses jQuery DataTables 1.9 but you're using option names and API from 1.10. You need to upgrade your jQuery DataTables library.
You're supplying data to jQuery DataTables using ajax option were in fact you should be using data option instead.
Remove code after // FOR TESTING ONLY as it was needed for demonstration only in jQuery DataTables - Row selection using checkboxes article and is not needed for production.