How can i display on a datatable array data using Ajax? - javascript

I'm using a MongoDB database to store some data. I now want to display this data on a HTML Datatable.
The data i'm trying to use is stored in arrays, here is how it is structured:
data: [[1848, 84857], [4944, 4949], [34, 65], [3566, 78], .... ]
$(document).ready(function() {
var table = $('#mytable').DataTable({
"serverSide": true,
"ajax": "/endpoint/?format=datatables",
"columns": [
{"data": 'data'},
]
});
setInterval( function () {
table.ajax.reload();
}, 10000 );
});
The problem with my actual code is that it will display the datatable like this:
DATA:
[[1848, 84857], [4944, 4949], [34, 65], [3566, 78], .... ]
While i would like it like this:
DATA:
1848, 84857
4944, 949
36, 65 and so on
How can i fix this issue? I was thinkin with a foor loop, but i don't really know how to do that, since i'm calling the data straight in the table variable.
The json response is something like this:
{"data":"[[11756.53, 2.419583] .....

You are using array of array data, just use index key to map your columns:
"columns": [
{"data":0},
{"data":1}
]
Awesome Example below:
function randomIntFromInterval(min, max) { // min and max included
return Math.floor(Math.random() * (max - min + 1) + min);
}
$.mockjax({
url: "/endpoint/?format=datatables",
response: function(settings) {
this.responseText = {
"draw": settings.data.draw,
"recordsTotal": 4,
"recordsFiltered": 4,
"data": [
[randomIntFromInterval(400, 8000), 84857],
[4944, 4949],
[34, 65],
[3566, 78]
]
}
}
});
var editable=false;
$(document).ready(function() {
var table = $('#mytable').DataTable({
"serverSide": true,
"ajax": "/endpoint/?format=datatables",
"columns": [
{"data":0},
{"data":1}
]
});
setInterval( function () {
table.ajax.reload();
}, 10000 );
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-mockjax/1.6.2/jquery.mockjax.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet" />
<table id="mytable" class="display nowrap" width="100%">
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Col1</th>
<th>Col2</th>
</tr>
</tfoot>
</table>

Related

Get MySQL Query using Ajax then Inserting Result to Data Table on button click

I want to ask how can I insert my sql query to the html datatable table body.
This is my present code:
AJAX Query for loading datatable after button click:
$(document).on('click','#filtersearch',function(e){
e.preventDefault();
$.ajax({
url:"index.php",
method:"POST",
data:{
formula:"filtersearch"
},
dataType:"json",
beforeSend:()=>{
$('.load_spinner').removeClass('d-none');
},
success:function(res){
$('.load_spinner').addClass('d-none');
select_d = res;
console.log(res);
var str ="";
if (!$.isEmptyObject(select_d)) {
select_d.forEach((x)=>{
str += `<tr>
<td>${x.assetid}</td>
<td>${x.assetcode}</td>
<td>${x.assetserial}</td>
<td>${x.assetname}</td>
<td>${x.assettype}</td>
<td>${x.assetcat}</td>
<td>${x.dpurchased}</td>
<td>${x.price}</td>
<td>${x.dperiod}</td>
<td>${x.finprice}</td>
<td>${x.status}</td>
<td>${x.assetage}</td>
<td>${x.location}</td>
</tr>`;
})
}
data_table("#table_index","#tbody_index",str);
}
})
})
Javascript for Datatable Content transfer from AJAX:
function data_table(table_name,tbody_name,data_tbody) {
$(table_name).DataTable().destroy();
$(tbody_name).empty().html(data_tbody);
$(table_name).DataTable();
};
Datatable HTML cointainer that will get the ajax query:
<table class="table table-bordered" id="table_index" width="100%" cellspacing="0">
<thead>
<tr>
<th>No.</th>
<th>Asset Code</th>
<th>Asset Serial</th>
<th>Asset Name</th>
<th>Category</th>
<th>Type</th>
<th>Date Purchased</th>
<th>Initial Price (PHP)</th>
<th>Depreciation Period</th>
<th>Final Price (PHP)</th>
<th>Status</th>
<th>Classification</th>
<th>Location</th>
</tr>
</thead>
<tbody id="tbody_index">
</tbody>
</table>
PHP code for database query:
<?php
include 'include/dbconfig.php';
$sql = 'SELECT * FROM tbl_assets';
$result = mysqli_query($conn, $sql);
$formula ='';
if (isset($_POST['formula'])) {
$formula = $_POST['formula'];
}
switch ($formula) {
case 'filtersearch':
$result = filtersearch();
$supData = array();
while ($row = $result->fetch_assoc()) {
$supData[] = $row;
}
echo json_encode($supData);
break;
default:
break;
}
function filtersearch()
{
include 'include/dbconfig.php';
$query = mysqli_query($conn,"SELECT * FROM tbl_assets");
return $query;
}
?>
I just want to ask what is wrong with my code since the script doesn't show the values of Tbody as intended. Thanks.
I found a solution after manipulating the pages instead.
Instead of coding all of them in one page, I tried creating another page (switchcase.php) that contains the PHP files and it worked as intended.
Just a hunch, but I think ajax doesn't accept urls of the same page. I don't know if thats how it works but yeah, I changed the url to switchcase.php and it worked.
if you using datatable with ajax and php try this way
<script>
$(function(){
$('#table_index').dataTable( {
'lengthMenu': [[10, 25, 50, 100, 500], [10, 25, 50, 100, 500]],
'processing': true,
'serverSide': true,
'serverMethod': 'post',
'order': [[ 1, "desc" ]],
'ajax': {
'url': 'index.php'
},
"columns": [
{ "data": "id" },
{ "data": "asset_code" },
{ "data": "asset_serial" ,'bSortable': false},
{ "data": "asset_name" ,'bSortable': false},
{ "data": "category_id" ,'bSortable': false},
{ "data": "type", 'bSortable': false},
{ "data": "date_purchased"},
{ "data": "initial_price" },
{ "data": "depreciation_period" },
{ "data": "final_price" },
{ "data": "status" ,'bSortable': false},
{ "data": "classification" },
{ "data": "location" }
]
});
$.fn.dataTable.ext.errMode = 'none';
});
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-hover table-nomargin table-condensed" id="table_index">
<thead>
<tr>
<th>No.</th>
<th>Asset Code</th>
<th>Asset Serial</th>
<th>Asset Name</th>
<th>Category</th>
<th>Type</th>
<th>Date Purchased</th>
<th>Initial Price (PHP)</th>
<th>Depreciation Period</th>
<th>Final Price (PHP)</th>
<th>Status</th>
<th>Classification</th>
<th>Location</th>
</tr>
</thead>
<tbody></tbody>
</table>

How to get Row data after a button click in datatables

can anyone help me on how to get a single row data on a click event.
This is the table which is dynamically populated after Success function in AJAX call is executed
<div class="table-responsive table-wrap tableFixHead container-fluid">
<table class="table bg-violet dT-contain" id="datatable" >
<thead class="thead-dark">
<tr>
<th>No.</th>
<th>Main</th>
<th>Shrinked</th>
<th>Clicks</th>
<th>Disable</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr class="bg-violet">
</tr>
</tbody>
</table>
</div>
<script src="scripts/jquery-3.5.1.min.js"></script>
<script src="scripts/jquery.dataTables.min.js"></script>
<script src="scripts/dataTables.bootstrap4.min.js" defer></script>
<script src="scripts/dashboard.js" defer></script>
This is my ajax success function
success: function(data){
$('#datatable').dataTable({
data: data,
"autoWidth": true,
columns: [
{'data': 'id'},
{'data': 'main'},
{'data': 'shrinked'},
{'data': 'clicks'},
{"defaultContent": "<button id='del-btn'>Delete</button>"}
]
})
}
I am adding a delete button to each row dynamically, but can't seem to fetch row data using it.
I tried this method with some tweaks to my success function
$('#datatable tbody').on( 'click', 'button', function () {
var data = table.row( $(this).parents('tr') ).data();
alert( data[0] );
} );
But this didn't seem to work.
The JSON data returning from the AJAX call is in this format:
[{"id":"12","main":"ndkekfnq" ...}, {.....}]
I also added an onclick function on the delete button to try to fetch data but that also didn't work.
EDIT: whole AJAX request
$(document).ready(()=>{
$.ajax({
url: 'URL',
method: 'post',
dataType: 'json',
data: {
"email": window.email,
"token": window.token
},
success: function(data){
let table = $('#datatable').dataTable({
data: data,
"autoWidth": true,
columns: [
{'data': 'id'},
{'data': 'main'},
{'data': 'shrinked'},
{'data': 'clicks'},
{"defaultContent": "<button id='dis-btn' class='btn btn-warning'>Disable</button>"},
{"defaultContent": "<button id='del-btn' class='btn btn-danger'>Delete</button>"}
]
})
$('#datatable tbody').on('click', "#del-btn", function() {
let row = $(this).parents('tr')[0];
//for row data
console.log(table.row(row).data().id);
});
}
})
})
What would be the correct way to do this? Thank you
You need to use column.render instead o defaultContent and then get the data on an outside function, you need to render a button at the render of the table:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link
rel="stylesheet"
href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css"
/>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
</head>
<body>
<div class="table-responsive table-wrap tableFixHead container-fluid">
<table class="table bg-violet dT-contain" id="datatable" >
<thead class="thead-dark">
<tr>
<th>No.</th>
<th>Main</th>
<th>Shrinked</th>
<th>Clicks</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr class="bg-violet">
</tr>
</tbody>
</table>
<script>
$('#datatable').dataTable( {
"data": [{'id':20,'main':'hola','shrinked':false,'clicks':2000},{'id':21,'main':'hola','shrinked':false,'clicks':283000}],
"autoWidth": true,
"columns": [
{"data": "id"},
{'data': 'main'},
{'data': 'shrinked'},
{'data': 'clicks'},
{"data": "id",
"render": function ( data, type, row, meta ) {
return '<button data-id="'+data+'" onclick="deleteThis(event)">Delete</button>'
}
}
]
} )
function deleteThis(e){
console.log(e.target.getAttribute('data-id'))
}
</script>
</body>
</html>
Haven't tried, but based on Datatables docs, this should work, let me know if it worked.
Here is working code for you. You need to set the datatables in a var.
Use that var table to look for clicked row which will $(this).parents('tr')[0] and use .data.id to the clicked item id
I have recreated the your example and its working fine. Just set you ajax response to the data.
Demo
//Ajax Data
var data = [{
"id": "10",
"main": "ndkekfnq",
"shrinked": "ndkekfnq",
"clicks": "ndkekfnq"
}, {
"id": "12",
"main": "Something",
"shrinked": "Data",
"clicks": "Ha"
}]
//Data Table
var table = $('#datatable').DataTable({
data: data,
columns: [{
'data': 'id'
},
{
'data': 'main'
},
{
'data': 'shrinked'
},
{
'data': 'clicks'
},
{
"defaultContent": "<button id='del-btn'>Delete</button>"
}
]
});
$('#datatable tbody').on('click', "#del-btn", function() {
var row = $(this).parents('tr')[0];
//for row data
console.log(table.row(row).data().id);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.21/js/jquery.dataTables.min.js" integrity="sha512-BkpSL20WETFylMrcirBahHfSnY++H2O1W+UnEEO4yNIl+jI2+zowyoGJpbtk6bx97fBXf++WJHSSK2MV4ghPcg==" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.21/css/jquery.dataTables.min.css" integrity="sha512-1k7mWiTNoyx2XtmI96o+hdjP8nn0f3Z2N4oF/9ZZRgijyV4omsKOXEnqL1gKQNPy2MTSP9rIEWGcH/CInulptA==" crossorigin="anonymous" />
<div class="table-responsive table-wrap tableFixHead container-fluid">
<table class="table bg-violet dT-contain" id="datatable">
<thead class="thead-dark">
<tr>
<th>No.</th>
<th>Main</th>
<th>Shrinked</th>
<th>Clicks</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr class="bg-violet">
</tr>
</tbody>
</table>
#Javier 's answer is a very good way to solve the OP's issue. Another way, if you don't want to include id field twice, would be like this:
"columns": [
{"data": "id"},
{'data': 'main'},
{'data': 'shrinked'},
{'data': 'clicks'},
{"data": null,
"render": function ( data, type, row, meta ) {
return '<button data-id="' + data.id + '" onclick="deleteThis(event)">Delete</button>'
}
}
]

Store selected rows id

I have a datatable loaded from a query from my database. (+/- 10000 records)
The idea is that the user should be able to select multiple records to be later processed
First i thought to add a column with checkbox for the selection then when user is done with all his selection the application keep track of all selected rows then progress to the next step with "Next Button" some where on the page, but after 12 hours of trying i couldn't do it.
Then i thought to make it simpler by adding a button in each row so that every time the user clicks on this button the application save the selected id in a session variable.
<div class="panel-body">
<table id="userTable" class="table display compact order-column">
<thead>
<tr>
<th>Select</th>
<th>Name</th>
<th>City</th>
<th>Phone</th>
<th>Zipcode</th>
</tr>
</thead>
</table>
#section Scripts {
#Scripts.Render("~/bundles/datatable")
<script type="text/javascript">
$(document).ready(function () {
var ids;
var mytable = $('#userTable').DataTable({
"sDom": 'ltipr',
"bServerSide": true,
"ajax": {
"beforeSend": AjaxBegin,
"type": "POST",
"url": '/LocationModifier/UserHistory',
"contentType": 'application/json; charset=utf-8',
'data': function (data) { return data = JSON.stringify(data); },
'complete': AjaxComplete
},
"bProcessing": false,
"orderMulti": false,
"scrollX": true,
"deferRender": true,
"searchDelay": 7000,
"fixedHeader": {
"header": true,
"footer": true
},
"columnDefs": [
{ "defaultContent": "-", "targets": "_all" },
{ "className": "text-center custom-middle-align", "targets": [0, 1, 2, 3, 4, ] },
],
"colReorder": true,
"lengthMenu": [[10, 25, 50, 100], [10, 25, 50, 100]],
"columns": [
{
"title": "Select",
"data": "ID",
"searchable": false,
"sortable": false,
"render": function (data, type, full, meta) {
return '<span class="glyphicon glyphicon-pencil btn-sm btn-info"></span>';
}
},
{ "data": "Name", "orderable": false },
{ "data": "City", "orderable": true },
{ "data": "Phone", "orderable": true },
{ "data": "Zipcode", "orderable": false },
],
"order": []
});
});
</script>
}
public ActionResult AddToCache(int id)
{
GetRecordAndAddeToCache(id);
// what should i return here, the page should not be refreshed????
}
There's no problem to implement your initial approach:
use some global set that will store selected row id's, like var rowsSelected = new Set();
add/delete id of the row being checked to that global variable upon clicking selection checkbox:
$('.markSelected').on('click', function () {
const selectedRowId = dataTable.row($(this).closest('tr')).data().id;
$(this).prop('checked') ? rowsSelected.add(selectedRow) : rowsSelected.delete(selectedRow);
});
upon table re-rendering append checkboxes to the first column and set those checked if rendered row id is present within rowsSelected:
render: function (data) {
return `<input type="checkbox" ${rowsSelected.has(data.id) ? 'checked' : ''}></input>`;
}
The complete demo, implementing that concept:
//table source
const srcData = [
{id: 1, item: 'apple', cat: 'fruit'},
{id: 2, item: 'pear', cat: 'fruit'},
{id: 3, item: 'carrot', cat: 'vegie'},
{id: 4, item: 'tomato', cat: 'vegie'},
{id: 5, item: 'cucumber', cat: 'vegie'}
];
//global variable that stores selected item id's
const selectedRows = new Set();
//datatables initialization
const dataTable = $('#mytable').DataTable({
dom: 't',
data: srcData,
columns: [
{data: null, render: function(data){
return `<input class="markSelected" type="checkbox" ${selectedRows.has(data.id) ? 'checked' : ''}></input>`;
}},
{data: 'item', title: 'item'},
{data: 'cat', title: 'cat'}
]
});
//selection checkboxes click handler
$('#mytable').click('.markSelected', function(){
const selectedRowId = dataTable.row($(event.target).closest('tr')).data().id;
$(event.target).prop('checked') ? selectedRows.add(selectedRowId) : selectedRows.delete(selectedRowId);
});
//proceed to the next step with selected row id's
$('#nextStep').on('click', function(){
console.log([...selectedRows]);
});
<!doctype html>
<html>
<head>
<script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="application/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
</head>
<body>
<table id="mytable"></table>
<button id="nextStep">Next Step</button>
</body>
</html>
You can use datatable's Row selection feature to achieve what you are trying to do.
$(document).ready(function() {
var table = $('#userTable').DataTable();
$('#userTable tbody').on( 'click', 'tr', function () {
$(this).toggleClass('selected');
} );
$('#submitButtonId').click( function () {
alert( table.rows('.selected').data().length +' row(s) selected' );
// You can use table.rows('.selected').data() to get all the selected Data
} );
} );
Reference

Invalid JSON format Datatable

I'm trying to implement sever side datatable, but it throws Invalid JSON format error.
CDN
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.js"></script>
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
HTML
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>EmployeeCode</th>
<th>EmployeeName</th>
<th>ManagerName</th>
<th>DesignationName</th>
</tr>
</thead>
</table>
JS
<script>
$(document).ready(function() {
$('#example').DataTable( {
"processing": true,
"serverSide": true,
"ajax": "/api/url",
"columns": [
{ data: "EmployeeCode" },
{ data: "EmployeeName" },
{ data: "ManagerName" },
{ data: "DesignationName" }
],
} );
} );
</script>
JSON
{
"Results":[{"EmployeeCode": "12345"}], // This is just a sample of data
"CurrentPage": 1,
"PageCount": 42,
"PageSize": 10,
"RecordCount": 417
}
it is clear what the issue is, looking at the JSON returned by the XHR/Ajax call to the server. It should just contain the expected data like this:
[
{'EmployeeCode':12345,EmployeeName:'abcde',...},
{'EmployeeCode':12346,EmployeeName:'fghij',...},
...
]
Rather your JSON contains other properties and the data is nested under the "Results" property. Also looking at the documentation, I think you need to format the JSON to contain a data property:
{
"draw": 1,
"recordsTotal": 57,
"recordsFiltered": 57,
"data": [
[
"12345",
"John Smith",
"Adam James",
"Manager",
],
...
}
So as a simple fix use the 'dataSrc':'Results' property as suggested by Ankush in your datatable configuration.
Use dataSrc attribute to let datatable know from where to collect data:
$(document).ready(function() {
$('#example').DataTable( {
"processing": true,
"serverSide": true,
"ajax": "/api/url",
"dataSrc": function (json) {
debugger;
return json.data;
},
"columns": [
{ data: "EmployeeCode" },
{ data: "EmployeeName" },
{ data: "ManagerName" },
{ data: "DesignationName" }
],
} );
} );
More detail about dataSrc can found here.

DataTables warning: table id=table_especie - Requested unknown parameter '0' for row 0, column 0

I know this was asked hundreds of times, but I think my case is very specific and it needs someone who knows jQuery to help, or at least has seen this before!
I have this code to build a table called "especie:
HTML
<table class="table" id="table_especie">
<thead>
<tr>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Script JS:
var tableEspecie= $('#table_especie').DataTable({
"paging": false,
"info": false,
"order": [
[2, "asc" ],
[3, "asc"],
[1, "asc"]
],
"columnDefs": [
{ "visible": false, "targets": 0 },
{ "visible": false, "targets": 2 },
{ "visible": false, "targets": 3 }
],
"drawCallback": function () {
var api = this.api();
var rows = api.rows( {page:'current'} ).nodes();
var last=null;
api.column(2, {page:'current'} ).data().each( function ( especie, i ) {
if ( last !== especie) {
$(rows).eq( i ).before(
'<tr class="especie info"><td colspan="4">'+especie+'</td></tr>'
);
last = especie;
}
} );
$("#table_especie thead").remove();
$("#table_especie tfoot").remove();
}
});
var populateEspecieShowName = function(data) {
$('#animal_especie_name').text(data[0].name);
};
var populateEspecieTable = function(data) {
var animais = [];
$.each(data, function(id_animal, animal){
animais.push([
animal.id_animal,
animal.nome_animal + ': ' + '<br>' + animal.notas_animal,
animal.foto_animal
]);
});
$('#table_especie').dataTable().fnClearTable();
$('#table_especie').dataTable().fnAddData(animais);
$('#table_especie').dataTable().fnDraw();
};
$('#table_especie tbody').on( 'click', 'tr', function () {
var animalId = $('#table_especie').DataTable().row(this).data();
if (animalId !== undefined)
$.route('animal/' + animalId[0]);
});
$('#table_especie_search').keyup(function(){
$('#table_especie').DataTable().search($(this).val(), false, true).draw() ;
});
Basically, it builds the table using data from a database! And I get the error (DataTables warning: table id=table_especie - Requested unknown parameter '0' for row 0, column 0. For more information about this error, please see http://datatables.net/tn/4) every time I go from table "especies" to table "especie". The error makes it sound like it's something wrong with "especie". What should I change to make the error go away? It still builds the table, but I get this error before. Thanks!!!
Solution:
"columnDefs": [{
"defaultContent": "-",
"targets": "_all"
}],

Categories