I know this must be one of the most popular questions. I can't see what's wrong with my data though. This is my php:
$sql = "SELECT eventid, event_type, date_display, date_from, date_to, location, done FROM events LIMIT 0, 30";
$get_result = mysql_query($sql);
$arr = Array();
while($res=mysql_fetch_assoc($get_result))
{
$arr['data'][] = $res;
}
echo json_encode($arr);
My JQuery:
function do_search()
{
var search_term=$("#search_term").val();
$.ajax
({
type:'post',
url:'get_results.php',
data:{
search:"search",
search_term:search_term
},
success:function(response)
{
console.log(JSON.parse(response))
$('#events').DataTable({
ajax: JSON.parse(response),
columns: [
{ data: 'eventid' },
{ data: 'event_type' },
{ data: 'date_display' },
{ data: 'date_from' },
{ data: 'date_to' },
{ data: 'location' },
{ data: 'done' },
],
"lengthMenu": [ [-1, 10, 25, 50, 100], ["All", 10, 25, 50, 100] ]
});
}
});
And my HTML:
<table id="events" class="display" style="width:100%">
<thead>
<tr>
<th>ID</th>
<th>Type</th>
<th>Date</th>
<th>From</th>
<th>To</th>
<th>Location</th>
<th>To do</th>
</tr>
</thead>
</table>
This is the data I get in the console:
{
"data": [
{
"eventid": "1",
"event_type": "Senate meeting",
"date_display": "61-60",
"date_from": "61",
"date_to": "60",
"location": "Unknown",
"done": "y"
},
{
"eventid": "2",
"event_type": "Legal hearing",
"date_display": "73-70",
"date_from": "73",
"date_to": "70",
"location": "Unknown",
"done": ""
},
[etc...]
]
}
As far as I can see I'm following the data expected by DataTables. What am I missing?
I am getting seven fields for each record, and the table has seven fields indeed, also mapped in the JQuery code.
In the example at the link you posted here: https://datatables.net/examples/ajax/objects.html, the ajax option in the datatables config is used to provide the URL of the file/script which returns the JSON data, so that datatables can initiate an AJAX request to fetch it.
Whereas what you've done is make your own AJAX request, and then pass the response to datatables. If you're going to do that, you should provide it to datatables via the data option instead. Your scenario, as coded now, is actually closer to this example: https://datatables.net/examples/data_sources/js_array.html
e.g.
$('#events').DataTable({
data: JSON.parse(response),
P.S. For a more complete discussion how to configure DataTables to use an AJAX request as a data source directly, see https://datatables.net/manual/ajax
Related
I am mounting a table and perfect until I want to show more data, I have read that I can use server side but I have not found any example how to consume an web service that returns json
html
<table id="datatable-buscador" class="display nowrap" style="width:100%">
<thead>
<tr>
<th>NÂș reco.</th>
<th>Fecha</th>
<th>Id trabajador</th>
<th>Trabajador</th>
<th>Id empresa</th>
<th>Ref. Int.</th>
<th>Nombre empresa</th>
<th>Visado</th>
<th>Prop.</th>
</tr>
</thead>
</table>
javascript
let $tabla = jQuery("#datatable-buscador");
$tabla.dataTable().fnDestroy();
$tabla.dataTable({
"scrollX": true,
"lengthMenu": [[15, 25, 30, -1], [15, 25, 30, "All"]],
"lengthChange": false,
"order": [1, "desc"], //columna 0 y ordenar desc
"language": { "url": "/src_reconocimientos/includes/js/utils/spanish.json" },
"ajax": {
url: "/example/example.php",
type: "POST",
dataType: "JSON",
data: { "tipo": tipo, "dias_reco": diasReco },
timeout: 180000 //3 min
},
"createdRow": function (row, data, dataIndex) {
jQuery(row).attr("id", data.N_RECONOCIMIENTO);
},
"columnDefs": [
{
// targets: "_all",
targets: [0, 1, 2, 4, 5, 7, 8],
className: 'dt-body-center'
},
],
"columns": [
{ "data": "N_RECONOCIMIENTO" },// 0
{
"data": null,
render: function (data, type, full, meta) {
return formatFecha(data.FECHA_RECONOCIMIENTO);
}
}, //1
{ "data": "DNI" }, // 2
{ "data": "NOMBRE_TRABAJADOR" }, // 3
{ "data": "EMPRESA" }, // 4
{ "data": "REF_INTERNA" }, // 5
{ "data": "NOMBRE_CLIENTE" }, // 6
{ "data": "VISADO" }, // 7
{ "data": "PROP" }, // 8
]
});
json:
{
"data": [{
"N_RECONOCIMIENTO": 29457,
"FECHA_RECONOCIMIENTO": "2021-10-11",
"DNI": "28460Q",
"NOMBRE_TRABAJADOR": "CAMPS",
"EMPRESA": 112390,
"REF_INTERNA": "Ref_interna?",
"NOMBRE_CLIENTE": "example",
"VISADO": "N",
"PROP": "Prop?"
}, {
"N_RECONOCIMIENTO": 2907,
"FECHA_RECONOCIMIENTO": "2021-10-14",
"DNI": "414J",
"NOMBRE_TRABAJADOR": "CARLOS",
"EMPRESA": 103482,
"REF_INTERNA": "Ref_interna?",
"NOMBRE_CLIENTE": "(ACUERDO DE COLABORA)",
"VISADO": "N",
"PROP": "Prop?"
}, {
"N_RECONOCIMIENTO": 2619,
"FECHA_RECONOCIMIENTO": "2021-04-16",
"DNI": "72306W",
"NOMBRE_TRABAJADOR": "DIEZ",
"EMPRESA": 29514,
"REF_INTERNA": "Ref_interna?",
"NOMBRE_CLIENTE": "example 365, S.L.",
"VISADO": "S",
"PROP": "Prop?"
}]
}
when pointing to the url of the ajax what it returns me is a json that changes the content according to the data that I pass to it, but when I want to get more 50000 records, the table fails me, so I want to implement serverside, how can I implement it and keep pointing the same url? I don't see anything related in the datatables examples
add info:
It is a very simple company webservice that receives data through my php script with cURL, in this it receives a type of request (it can be 1, 2, 3) and receives parameters (variables), the web services does the queries, simple queries and returns the result as json, it cannot be interacted any more, that's why when I try to process 50000 the datatable gives me an error. my question is: how can I do an intermediate step to process so many lines?
I am trying to get a dataTable on a page called "locations.php" but i am still get a JSON invalid error.
I generate the JSON dynamically using this php code on "get_SR_Locations.php":
$myjson = array();
foreach ($locationList as $list) :
$json= array(
"id" => addslashes($list['id']),
"name" => addslashes($list['name']),
"address" => addslashes($list['address']),
"telephone" => addslashes($list['telephone']),
"emailaddress" => addslashes($list['email'])
);
array_push($myjson, $json);
endforeach;
$mj=array("data"=>$myjson);
echo json_encode($mj);
The generated JSON looks something like this:
{"data":[{"id":"108","name":"Sportpark","address":"Karspstreet 501","telephone":"0123456789","emailaddress":"sport#mail.com"},{"id":"2","name":"Blaashal","address":"Gustavstreet 2920","telephone":"","emailaddress":"sporting#mailing.com"}]}
So when I put this in a JSON validator it says: VALID JSON
But I still get an invalid JSON warning by ajax.
On locations.php I have this code:
HTML
<table id="displayTable" class="table table-striped table-bordered display compact" style="width:100%">
<thead>
<tr>
<th> </th>
<th>Name</th>
<th>Address</th>
<th>Telephone</th>
</tr>
</thead>
<tfoot>
<tr>
<th> </th>
<th>Name</th>
<th>Address</th>
<th>Telephone</th>
</tr>
</tfoot>
</table>
And this JQUERY
function format ( d ) {
// `d` is the original data object for the row
return 'So Far .... NOT so Good';
}
$('#SR_sendForm').click(function(){
$('#displayTable').DataTable(
{
"order": [[ 1, "asc" ]],
"scrollY": $(window).height()-($(window).height()/10),
"scrollX": true,
"ajax": 'pages/get_SR_Locations.php?fdr='+$('#FDR').val()+'&s_term='+$('#searchterm').val()+'&city='+$('#city').val()+'&searchgroup='+$('#searchgroup').val(),
"columns": [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data": "name" },
{ "data": "address" },
{ "data": "telephone" }
]
}
);
$('#responseTable').show();
}
});
// Add event listener for opening and closing details
$('#responseTable 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');
}
} );
And this is the error I get:
DataTables warning: table id=displayTable - Invalid JSON response. For more information about this error, please see http://datatables.net/tn/1
What is wrong?
Thank you Jeff.... I did what you said ... Add json to the data instead of going via ajax.
So the solution is:
I made an tempDIV to load the data from get_SR_Locations.php
<div class="row" id="tempDIV" style="display: none"></div>
then I load the data and I use the callback for errors etc.
$('#tempDIV').load('pages/get_SR_Locations.php?fdr='+$('#FDR').val()+'&s_term='+$('#searchterm').val()+'&city='+$('#city').val()+'&searchgroup='+$('#searchgroup').val(), function(responseTxt, statusTxt, xhr) {
if(statusTxt == "success"){
$('#displayTable').DataTable(
{
"order": [[ 1, "asc" ]],
"scrollY": $(window).height()-($(window).height()/10),
"scrollX": true,
"data": JSON.parse($.trim($('#tempDIV').text())),
"columns": [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data": "name" },
{ "data": "address" },
{ "data": "telephone" }
]
}
);
$('#responseTable').show();
}
if(statusTxt == "error"){
$('#responseTable').html("<b>Oops</b><br>Houston we have a problem");
alert("Error: " + xhr.status + ": " + xhr.statusText);
$('#responseTable').show();
}
});
And a last modification in get_SR_Locations.php:
I removed this line:
$mj=array("data"=>$myjson);
$myjson = array();
foreach ($locationList as $list) :
$json= array(
"id" => addslashes($list['id']),
"name" => addslashes($list['name']),
"address" => addslashes($list['address']),
"telephone" => addslashes($list['telephone']),
"emailaddress" => addslashes($list['email'])
);
array_push($myjson, $json);
endforeach;
echo json_encode($myjson);
Free jqGrid uses data in the following JSON name:value pairs format:
var data = {
"page": "1",
"records": "3",
"rows": [
{ "DataID": "1", "DataDesc": "Test 1", "DataTitle": "Test 1" }
]
};
I have the following in the PHP script:
$i=0;
while ($row = mysql_fetch_assoc($result)) {
$data->rows[$i]['cell']=array($row);
$i++;
}
print json_encode($data);
Which returns:
{"rows":[{"cell":[{"user_id":"00082563","first_name":"Peter","case_title":"Male with STI (urethritis)","case_started":"2017-06-02 10:52:10"}]}]}
Which looks to be OK. However, with the JSON parts of the code below, the grid doesn't display at all.
function loadFirstGrid() {
$("#FirstGrid").jqGrid({
url: "scripts/json_test.php?user=" + user,
dataType: "json",
mtype: "GET",
postData: {
json: JSON.stringify(data)
},
colModel: [{
name: "user_id",
label: "User ID",
width: 120
},
{
name: "first_name",
label: "Name",
width: 400
},
{
name: "case_title",
label: "Case Title",
width: 500
},
{
name: "case_started",
label: "Case Started",
width: 200
},
],
emtyrecords: "Nothing to display",
viewrecords: true,
sortable: true,
shrinkToFit: false,
autowidth: true,
caption: 'First Grid'
});
}
But if I remove the postData part to have the following, the grid displays, but of course no data.
function loadFirstGrid() {
$("#FirstGrid").jqGrid({
url: "scripts/json_test.php?user=" + user,
dataType: "json",
mtype: "GET",
colModel: [{...
Any ideas?
OK, finally worked through this and got it working with this
function loadFirstGrid() {
$("#FirstGrid").jqGrid({
url: "scripts/json_test.php?user=" + user,
dataType: "json",
mtype: "GET",
colModel: [
{name: "user_id", label:"User ID", width: 120},
{name: "first_name", label:"Name", width: 400},
{name: "case_title", label:"Case Title", width: 500},
{name: "case_started", label:"Case Started", width: 200},
],
emtyrecords: "Nothing to display",
viewrecords: true,
sortable: true,
shrinkToFit: false,
autowidth: true,
caption: 'First Grid',
});
}
To get the correct format JSON for jqGrid:
{"page":"1","total":"1","records":"1","rows":[{"user_id":"00082563","first_name":"Peter","case_title":"Male with STI (urethritis)","case_started":"2017-06-02 10:52:10"}]}
I used the following PHP script:
$page = '1';
$total_pages = '1';
$count = '1';
$data = (object) array('page' => $page, 'total' => $total_pages, 'records' =>$count, 'rows' => "");
$data->page = $page;
$data->total = $total_pages;
$data->records = $count;
$i=0;
while ($row = mysql_fetch_assoc($result)) {
$data->rows=array($row);
$i++;
}
print json_encode($data);
?>
(NOTE: I don't care about the number of pages, total_pages and count as my grids will only ever have one primary record and multiple subgrids with only one record). So hope this helps someone; there is not much in the documentation or examples that describes how to do this with Free jqGrid ;-(
First of all JavaScript is case sensitive language and jqGrid will ignore parameter dataType: "json". You should fix it to datatype: "json".
Seconds, you use exotic format of the JSON data:
{
"rows": [{
"cell": {
"user_id": "00082563",
"first_name": "Peter",
"case_title": "Male with STI (urethritis)",
"case_started": "2017-06-02 10:52:10"
}
}]
}
instead of
{
"rows": [ {
"user_id": "00082563",
"first_name": "Peter",
"case_title": "Male with STI (urethritis)",
"case_started": "2017-06-02 10:52:10"
}]
}
or
[ {
"user_id": "00082563",
"first_name": "Peter",
"case_title": "Male with STI (urethritis)",
"case_started": "2017-06-02 10:52:10"
}]
You don't use loadonce: true and it's unclear, whether you plan to implement server side paging, sorting and filtering of data or you want to return all the data at once and jqGrid should use client side paging, sorting and filtering.
Finally, you should use name properties of colModel corresponds to the properties of user_id. It's very important to understand, that jqGrid have to assign unique id to every row of the grid (see here). Thus you have to inform jqGrid, which property contains rowid. You can use either jsonReader: { id: "user_id" } or to include property key: true in the column user_id.
The demo https://jsfiddle.net/OlegKi/qgrwymuu/1/ contains an example of described above modifications. It uses Echo service of JSFiddle to simulate server, which responses with some JSON data.
I am implementing datatable in my project using instruction from https://datatables.net/examples/data_sources/server_side.html
Now I have implemented same jquery code like :
$(document).ready(function() {
$('#example').DataTable( {
"processing": true,
"serverSide": true,
"ajax": "../server_side/scripts/server_processing.php"
} );
} );
but its not working in my project and gives the error of :
DataTables warning: ********** Requested unknown parameter '0' for row 0. For more information about this error, please see http://datatables.net/tn/4
but when I specify columns in jquery like :
$(document).ready(function() {
$('#example').DataTable( {
"processing": true,
"serverSide": true,
"ajax": "../server_side/scripts/server_processing.php",
"columns": [
{ "data": "id"},
{ "data": "item" },
{ "data": "name" }
],
} );
} );
then it works perfectly, So whats the issue here, why I can not use it without specifying columns ?
Ajax Response :
{
"draw": 1,
"recordsTotal": 57,
"recordsFiltered": 57,
"data": [
[
1,
"item1",
"name1"
],
[
2,
"item2",
"name2"
]
]
}
As far as I can see, you are accessing an array of objects instead of a two dimensional array.
Datatables default behavior is accepting data in this format:
[
[ "row 1, cell 1", "row 1, cell 2", "row 1, cell 3" ],
[ "row 2, cell 2", "row 2, cell 2", "row 2, cell 3" ]
]
If you use a different data source format, as I believe you do, you must specify the columns so datatables can map them.
You can find more information here
If possible, provide your json response to check if this is the case.
Ok, I can see your response now, and it works if you wrap your ids in double quotes.
Try this - create a file named response.php with this content:
{
"draw": 1,
"recordsTotal": 57,
"recordsFiltered": 57,
"data": [
[
"1",
"item1",
"name1"
],
[
"2",
"item2",
"name2"
]
]
}
Create another file named test.php with this content:
<head>
<script src="http://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>
</head>
<body>
<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th>ID</th>
<th>Item</th>
<th>Name</th>
</tr>
</thead>
<tfoot>
<tr>
<th>ID</th>
<th>Item</th>
<th>Name</th>
</tr>
</tfoot>
</table>
<script>
$(document).ready(function() {
$('#example').DataTable( {
"processing": true,
"serverSide": true,
"ajax": "./response.php"
} );
} );
</script>
</body>
Upload both files to your server and test it - it works.
I'm trying to create a dataTable of users where each row has a drop-down child row that contains checkboxes of the user privileges. So quite dynamically a 'super' admin can click on users and assign their privileges within the table.
Firstly, not sure if this is a good idea, so feel free to suggest a better way of doing it. Maybe a simple popup modal per row would be easier but for now I've decided this would be a cool way of doing it, so I push on.
Trying to initialise the dataTable with AJAX has me stumped currently however.
PermissionsController.php
public function grid()
{
//retrieve data from models
$data['data'] = collect([ 'admins' => $admins, 'roles' => $roles ]);
return $data;
}
routes.php
Route::get('user-permissions', 'PermissionsController#grid');
permissions.blade
<table class="table table-striped" id="admins_table" >
<thead>
<tr>
<th>Last Name</th>
<th>First Name</th>
<th>Email</th>
<th>Phone</th>
</tr>
</thead>
</table>
js
var oTable = $('#admins_table').dataTable( {
"sDom": "<'row'<'col-md-6'l><'col-md-6'f>r>t<'row'<'col-md-12'p i>>",
"aaSorting": [],
"oLanguage": {
"sLengthMenu": "_MENU_ ",
"sInfo": "Showing <b>_START_ to _END_</b> of _TOTAL_ entries"
},
"ajax": {
//here's where I'm trying to grab the data
"url": "http://example.app/user-permissions",
"dataSrc": "data"
},
"columns": [
{ "data": "last_name" },
{ "data": "first_name" },
{ "data": "email" },
{ "data": "phone" }
]
});
Ajax
{
"data":
{
"admins":
[{
"id":31,
"email":"example#gmail.com",
"last_login":"2015-07-27 09:50:50",
"first_name":"Gary",
"last_name":"Barlow",
"roles":[{
"id":1,"slug":"admin"
}]
}],
"roles":
[
{"id":3,"slug":"admin","name":"Admin"},
{"id":7,"slug":"accounts","name":"Accounts"},
{"id":8,"slug":"sales","name":"Sales"},
{"id":9,"slug":"superAdmin","name":"SuperAdmin"}
]
}
}
The "admin" object encompasses all the admins that are passed through and their already assigned roles. These should appear as already ticked within the child-row.
The "roles" object will contain all the current roles available to allow for assignment of additional roles. Basically, this identifies the number of checkboxes that need to appear.
I've abstracted out the rest as what's above pertains to the initialisation. Greatly appreciate any help.
Trying to use AJAX I'm getting nothing but "No data available in table" when if I type in the browser the route path I get the JSON object output.
I'm not sure how I should call the route.
url: '/user-permissions',
dataSrc: 'data.admins',
success: function (data) {
console.log(data);
}
Will the above suffice? I don't really want to be calling the whole url. I even added a success function to try and get a console output of the data but still nothing.
the correct dataSrc reference would be data.admins
you miss a admins[].phone in the sample data?
As I understand you want to show a <select> populated with data.roles, showing the current data.admins[].roles[0].id?
You can do this by collecting data.roles in the dataSrc callback (or in a xhr.dt event) and use a render method for the role column :
<table class="table table-striped" id="admins_table" >
<thead>
<tr>
<th>Last Name</th>
<th>First Name</th>
<th>Email</th>
<th>Phone</th>
<th>role</th>
</tr>
</thead>
</table>
js, only the important
var roles,
var oTable = $('#admins_table').dataTable( {
"ajax": {
"url": "http://example.app/user-permissions",
"dataSrc" : function(json) {
roles = json.data.roles;
return json.data.admins;
}
},
"columns": [
{ "data": "last_name" },
{ "data": "first_name" },
{ "data": "email" },
{ "data": "phone" },
{ "data": "roles",
"render": function(data, type, row) {
var select = '<select>',
role = data[0].id;
for (var i=0;i<roles.length;i++) {
select+='<option value="'+roles[i].id+'"';
if (role == roles[i].id) select+=' selected';
select+='>'+roles[i].name+'</option>';
}
select+='</select>';
return select;
}
}
]
});
produces this table :
with this data :
{ "data": {
"admins": [{
"id":31,
"email":"example#gmail.com",
"last_login":"2015-07-27 09:50:50",
"first_name":"Gary",
"last_name":"Barlow",
"phone" : "123",
"roles":[{
"id":8,"slug":"sales"
}]
},{
"id":32,
"email":"example#yahoo.com",
"last_login":"2015-07-27 09:50:50",
"first_name":"Bary",
"last_name":"Garlow",
"phone" : "321",
"roles":[{
"id":7,"slug":"accounts"
}]
}],
"roles": [
{"id":3,"slug":"admin","name":"Admin"},
{"id":7,"slug":"accounts","name":"Accounts"},
{"id":8,"slug":"sales","name":"Sales"},
{"id":9,"slug":"superAdmin","name":"SuperAdmin"}
]
}
}
It's been awhile now since I asked this question and I thought I'd clarify what I did to solve the problem. First I ensured all the data tables scripts were the latest versions, not sure if this was a problem but I was using some outdated stuff.
Within the tables initialisation the ajax call became simply:
ajax: "/user-permissions"
Most the hard work went into the controller function that was called by the above route:
public function grid()
{
$admins = // get users with relevant roles e.g. ($user->load('roles'))
return Datatables::of($admins)->make(true)
}