Ajax error on datatable initialisation on table within modal - javascript

I have a modal with a search box within it, which when the search button is hit, has an ajax call which goes to the controller, which then returns a table of results, which is then put into a div. Like so:
$.ajax({
url: url,
data: JSON.stringify(viewModel),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
cache: false,
type: "POST",
success: function (result) {
if (result.success === true) {
$("#searchResultsPlaceHolder").show();
$("#searchResultsPlaceHolder").html(result.view, function() {
var noOfRows = $('#searchResultsTable tr').length;
if (noOfRows > 1) {
loadSearchDatatable();
}
});
}
},
error: function (responseText, textStatus, errorThrown) {
alert('Error - ' + errorThrown);
}
});
All that is fine, and works perfectly up until I try to make it a datatable. If I take out the lines
$("#searchResultsPlaceHolder").html(result.view, function() {
var noOfRows = $('#searchResultsTable tr').length;
if (noOfRows > 1) {
loadSearchDatatable();
}
});
and just have
$("#searchResultsPlaceHolder").html(result.view)
it works fine, it gives me a table with my results. But as this is in a modal, and the returned results may get quite lengthy, I want to use a datatable to implement pagination and sorting. But whenever I apply the loadSearchDatatable function to the table after the div is populated with the returned html, I get the error:
table id=searchResultsTable - Ajax error
The datatable actually appears, with the sort buttons and paging buttons present, but none of them do anything, and the table is longer than the length I specified (5). Here is my datatable function:
function loadSearchDatatable() {
$('#searchResultsTable').dataTable({
ajax: "data.json",
"bLengthChange": false,
'iDisplayLength': 5,
"bSort": true,
"sPaginationType": "full_numbers",
"bFilter": false,
"sDom": 'ft<"bottom"ilp>',
"bDestroy": false,
"aaSorting": [[0, "asc"]]
});
};
Does anyone have any idea how to fix this error?

Use the code below instead:
$("#searchResultsPlaceHolder").html(result.view);
var noOfRows = $('#searchResultsTable tr').length;
if (noOfRows > 1) {
loadSearchDatatable();
}
Also remove ajax: "data.json", in your function loadSearchDatatable().

Related

I failed to refresh data in yajra/laravel-datatables-oracle with draw method

In laravel 6 app I use "yajra/laravel-datatables-oracle": "^9.4" and I need selecting 1 row and running ajax request on server to delete this row
I try to refresh table with draw() method and it does not work.
In my blade file :
#push('scripts')
var oTable;
$(document).ready(function () {
oTable = $('#my_tasks_data').DataTable({
processing: true,
serverSide: false,
info: false,
order: [],
});
$('div.dataTables_length select').select2({
theme: "bootstrap"
});
...
function taskComplete(rowId) {
$.ajax({
url: 'tasks/' + rowId + '/complete',
type: "post",
dataType: 'json',
data: {'_token': '{{csrf_token()}}'},
success: function (data) {
console.log('taskComplete success data::')
console.log(data)
console.log('oTable::')
console.log(oTable)
oTable.draw(); // THat does not work
alert( 'AFTER::' )
},
error: function (xhr) {
console.error(xhr)
}
});
}
I check oTable var and see : https://prnt.sc/ujyp14 It looks like valid Table object
Why it does not work and how it can be fixed?
Thanks!
I found decision with setting serverSide property to true
oTable = $('#my_tasks_data').DataTable({
processing: true,
serverSide: true,
and after that method oTable.draw() works ok

Child Rows and PHP sourced data issues on

I am developing a web application for myself to learn JavaScript/jQuery, and I am trying to use dataTables plug-in for display data on page.
I am failing to implement Child Rows, to detail my data - I get "Uncaught ReferenceError" when tying to expand child row. I found on my searches, solutions for similar problems; but I'm having trouble applying to my code due the way I structured it for get data from a PHP file.
On solution I found, this problem was generated for using different variable names for the table on dataTables settings and click event.
In my case, my dataTables settings is inside a callback function, due to PHP request (It was the way I successfully did it work, after long hours trying - I was having problems with async on JavaScript), therefore I don't have it as a variable to make the reference.
The way I am getting data from PHP it's working, but I am not sure if it is the most appropriate manner.
I am looking for a solution to set the Child Rows without messing up my PHP request. This solution can be either by changing the way data is get from PHP or the way Child Rows is setted.
function dataJSON(callback) {
$.ajax({
url: "historicoTransacoes.php",
type: "GET",
dataType: "html",
}).done(function (data) {
callback(data);
}).fail(function () {
console.log("Erro na requisição");
});
};
function dataJSON2(data) {
d = JSON.parse(data);
console.log(d)
var table = $('#ultimosLancamentos').dataTable({
//"bProcessing": true,
//"serverSide": true,
data: d,
paging: true,
ordering: false,
info: true,
columns: [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{data: "local"},
{data: "tipotransacao"},
{data: "contain"},
{data: "contaout"},
{data: "valor"},
{data: "datatransacao"}
]
});
}
$('#ultimosLancamentos 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 format(d) {
// `d` is the original data object for the row
return '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">' +
'<tr>' +
'<td>' + d.descricao + '</td>' +
'</tr>' +
'</table>';
}
$(document).ready(function () {
dataJSON(dataJSON2);
var table = $('#ultimosLancamentos').dataTable;
});
Make it work with these changes:
function dataJSON() {
var d=[];
$.ajax({
url: "historicoTransacoes.php",
type: "GET",
dataType: "html",
async: false,
success : function(data) {
//console.log(data);
d.push(data);
}, error : function(req, err) {
console.log(err);
}
});
//console.log(d[0]);
return JSON.parse(d[0]);
};
function format(d) {
// `d` is the original data object for the row
return '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">' +
'<tr>' +
'<td>' + d.descricao + '</td>' +
'</tr>' +
'</table>';
}
d=dataJSON();
//console.log(d);
$(document).ready(function () {
var table = $('#ultimosLancamentos').DataTable({
//"bProcessing": true,
//"serverSide": true,
data: d,
paging: true,
ordering: false,
info: true,
columns: [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{data: "local"},
{data: "tipotransacao"},
{data: "contain"},
{data: "contaout"},
{data: "valor"},
{data: "datatransacao"}
]
});
$('#ultimosLancamentos 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');
}
});
});
The key was setting ajax async propertie to 'false', so I could pass the Json from request to a JavaScript variable.
Still don't know if it is the most apporpriete way, but it worked.
Any tips for improve this code are still welcome!

rowData remains on first record after filtering

When using the filter box of a datatable, the rowId remains on the first record, and I cannot figure out why.
Here is the datatable (simplified as much as possible):
$.ajax({
url: 'process/getData.php',
type: 'POST',
data: data,
dataType: 'html',
success: function(data, textStatus, jqXHR){
var jsonObject = JSON.parse(data);
var table = $('#example1').DataTable({
"data": jsonObject,
"columns": [
{
"data": "MONDAY",
"fnCreatedCell": function (nTd, sData, oData, iRow, iCol)
{
$(nTd).html("<span class='checkMon'>+oData.MONDAY+</span>");
},
// columns for each work day
}
],
"paging": false,
"scrollY": 730,
"scrollX": true,
"bDestroy": true,
"stateSave": true,
"autoWidth": true
});
},
error: function(jqHHR, textStatus, errorThrown) {
console.log('fail: '+ errorThrown);
return false;
}
});
Outside of the datatable, I have onclick event handler:
$('#example1').on('click', 'tr > td > .checkMon', function(e)
{
e.preventDefault();
var $dataTable = $('#example1').DataTable();
var tr = $(this).closest('tr');
var data = $dataTable.rows().data();
var rowData = data[tr.index()];
console.log(rowData.UID);
});
Prior to filtering, when I click any cell, the console reads the correct rowData.UID.
The problem is when I filter and click the cell again, the console reads the first row's rowData.UID.
Does anyone see why this is happening and how to fix it?
If what you want to achieve is simply log into the console UID property of the object that sourced the row that holds the <span> you've clicked, following approach should work:
$('#example1').on('click', '.checkMon', function(e)
{
e.preventDefault();
const dataTable = $('#example1').DataTable();
const rowData = dataTable.row($(this).closest('tr')).data();
console.log(rowData.UID);
});
Also, consider using ajax option. With that you won't need to waste performance destroying/re-creating your table and that will make your code cleaner and safer.

Reload DATATABLE inside AJAX success without refreshing page

I have a table using Datatable plugin. I have filtered what I want to delete and after deletion, I manage to empty the value.
After that, if I want to filter using the same text again, for example, I have ba 1 and ba 2 and after deleting ba 1, it still shows the cell when I entered ba on the filter textarea field. It suppose to display the remaining ba which are not deleted yet.
For your information, I'm not using built in Datatable Ajax method.
what I'm trying to do is I want it to reload the table with the new data without refreshing the page after ajax on success. How to do that?
My datatable :
var table1 = $('#table1').DataTable(
{
pageLength : 500,
lengthChange: false,
deferRender: true,
scrollY: 800,
scrollCollapse: true,
scrollX: true,
bSort: false,
cache: true,
autoWidth: false,
columnDefs: [
{
targets: 0,
checkboxes:
{
selectRow: true
}
}
],
select: {
style: 'multi',
selector: 'td:not(:nth-child(4), :nth-child(5), :nth-child(6), :nth-child(9), :nth-child(10), :nth-child(13), :nth-child(14), :nth-child(15), :nth-child(16), :nth-child(17), :nth-child(18), :nth-child(19), :nth-child(20), :nth-child(21), :nth-child(22), :nth-child(23), :nth-child(24), :nth-child(25))'
}
});
Here's my filtering function code :
table1.columns().every(function ()
{
var table = this;
$('.filter', this.header()).on('keyup change', delay(function (settings, data, dataIndex)
{
if (table.search() !== this.value)
{
table.search(this.value).draw();
}
}, 500));
});
Here's my AJAX success code for deletion based on selected checkbox:
$('.btnN2').click(function(){
var answer = confirm('Delete N2 : Are you sure you want to delete selected items?');
if (answer)
{
console.log('yes');
var rows = $(table1.rows({selected: true}).$('input[type="checkbox"]').map(function()
{
return $(this).prop("checked") ? $(this).closest('tr').attr('data-getstockcode') : null;
}));
var getstockcodes = [];
$.each(rows, function(index, rowId)
{
console.log(rowId)
getstockcodes.push(rowId);
});
$.ajax({
url: 'del_n2',
type: 'GET',
data: {"getstockcodes": JSON.stringify(getstockcodes)},
dataType: 'JSON',
success:function(data){
console.log(data);
$(table1.rows({selected: true}).$('input[type="checkbox"]').map(function()
{
if($(this).prop("checked"))
{
$(this).parents("tr:eq(0)").find(".note2").val('');
console.log('reset');
}
}));
}
});
}
else
{
console.log('cancel');
}
});
Here's my insert data based on keyup event
$(".note2").keyup(delay(function()
{
var stockcode = $(this).data("stockcode");
var stockname = $(this).data("stockname");
var value = $(this).val().replace(/(\r\n|\n)/g, "\\n");
$.ajax({
url: 'saveNote2',
type: 'GET',
data: 'stockcode='+stockcode+'&stockname='+stockname+'&value='+value,
dataType: 'JSON',
success: function(data){
console.log(data);
},
error: function(data){
console.log(data);
}
});
}, 300));
Just add this in your success function
table1.ajax.reload()
If you are using ajax datatable or local you need to make it like this
table1.clear();
table1.rows.add(your response data array);
table1.draw()

Datatable ,Javascript and Json

I have a Django Python webapp , i have a function :
def showreport(newrequest) :
rep1 = get_report_data(newrequest,2)
data={['columns':rep1[0],'rows':rep1[1]}
return JsonResponse(data,safe=False)
i call this function from javascript in HTML page , the data return is an array with two elements, 1 represent columns and the other the data.
I want to present in the HTML page the data in a DataTable object , and since the columns and data is dynamic i want to create the DataTable dynamically
In the HTML
In JavaScript
$(document).ready(function () {
$("#showresults").on('click', function(evt) {
evt.preventDefault();
$('#show_loading').show();
$('#theTable').hide();
froms = document.getElementById('startdate').value;
tos = document.getElementById('todate').value;
$.ajax({
type: "POST",
url: 'showreport',
data: {
'start_date' : froms,
'end_date' :tos,
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
success: function (data, textStatus, jqXHR) {
$('#show_loading').hide();
var rowSet=data['rows'];
var columnset =data['columns'];
$('#theTable').DataTable({
"processing": true,
searching: false,
paging: false,
"bInfo" : false,
columns: [columnset] ,
data: [rowSet]
} );
$('#theTable').show();
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
$('#show_loading').hide();
alert("Error, please try again!");
}
});
});
});
Now the problem i have is that the Columns are not presented and the data is presenting only 1 row and it is not separated to columns.
In inspect mode , i can see
{"rows": [["Test1", "Test2"],["Test3", "Test4"] etc..., "columns": ["col1","col2"]}
What am i doing wrong.
Thanks,
N
I think you have an array of an array :)
try
change this
columns: [columnset],
data: [rowSet]
to this
columns: columnset,
data: rowSet

Categories

Resources