Is there a way to add row as html to datatable? I understand that the suggested way of doing it is this:
$('#addRow').on( 'click', function () {
t.row.add( [
counter +'.1',
counter +'.2',
counter +'.3',
counter +'.4',
counter +'.5'
] ).draw( false );
counter++;
} );
But I have a complex JSON input and I want to pre process it in PHP. Is it doable or even possible?
EDIT:
So instead of doing the code above:
t.row.add(resultfromphpserverwithalltherows);
UPDATE:
JSON output
{"student":[{"id":"2008-161","name":"Joseph Taylor","age":"20","status":"married","address":"USA","subjects":[{"math":"90","science":96,"history":99,"literature":93,"pe":"96"}],"remarks":"passed"}
and sometimes:
{"student":[{"id":"2008-161","name":"Joseph Taylor","age":"20","status":"married","address":"USA","subjects":[{"math":"90","science":96,"history":99,"literature":93,"pe":"96"}],"remarks":"passed","othersubjects":[{"applied math":"90","general science":96,"world history":99,"literature":93,"pe":"96"}],"remarks":"passed"}
So I can't really define the columns because the JSON output is dynamic and that's why I want to preprocess it in PHP first.
No matter how you approach this, there's going to be some significant data-formatting required.
Best approach for what you're asking: use DataTables server-side tools.
It requires including some additional components, but will simplify the javascript down to:
$('#example').DataTable( {
"processing": true,
"serverSide": true,
"ajax": "../server_side/scripts/server_processing.php"
} );
...with a little tweaking, you can simplify that further:
$(function(){
var dt = new dataTableAuto();
dt.load();
});
function dataTableAuto() {
this.params = {
"processing": true,
"serverSide": true,
"ajax": "../server_side/scripts/server_processing.php"
};
this.load = function() {
$('#example').DataTable( this.params );
}
}
php ajax server to send raw JSON as a single row
Simply send an ajax request to php which includes the counter, then respond with a json array matching what you want to build.
Javascript snippet
counter = 0;
$.ajax({
url: '[your url]',
type: 'post',
data: {"counter":counter},
contentType: "application/json",
dataType: 'json',
success: function(response){
t.row.add(JSON.parse(response)).draw( false );
counter++;
},
});
php Snippet
$jsonString = file_get_contents('php://input');
$data = json_decode($jsonString);
$counter = $data['counter'];
$totalRows = 10;
for( $i = 0; $i < $totalRows; $i++) {
$result[] = $counter .".". $i;
}
header('Content-Type: application/json', true, 200);
echo json_encode($result);
exit;
DataTables pure AJAX approach
javascript
$(function(){
t = $('#example');
$.ajax({
url: '[your url]',
type: 'post',
data: {"classID":12},
contentType: "application/json",
dataType: 'json',
success: function(response){
t.DataTable( JSON.parse(response) );
},
});
});
php
$jsonString = file_get_contents('php://input');
$data = json_decode($jsonString);
$classID = intval($data['classID']);
$cols = array('Name', 'Position', 'Score');
foreach ( $cols as $colName ) {
$entry = new stdClass();
$entry->title = $colName;
$result['columns'][] = $entry;
}
$result = // some query [ex: get rows by class id]
foreach( $result as $row) {
$thisRow = array();
foreach ( $cols as $colName ) {
$thisRow[] = $row['$colName']
}
$result['data'][] = $thisRow;
}
header('Content-Type: application/json', true, 200);
echo json_encode($result);
exit;
This should produce an object similar to:
{
data: [
['Joseph Taylor', '22', '90']
],
columns: [
{ title: "Name" },
{ title: "Position" },
{ title: "Score" }
]
}
Related
I am having trouble getting the success call to fire in my ajax request. I know the communication is working fine, but the last call in my PHP script, which is a return json_encode($array); will fire as if it is a part of the onprogress object. I would like to "break" the onprogress call and run the success function on the last data sent via return json_encode when the PHP script has terminated...
Here is my AJAX call:
$( document ).ready(function(e) {
var jsonResponse = '', lastResponseLen = false;
$("#btn_search").click(function(e){
var firstname = document.getElementById('firstname').value;
var lastname = document.getElementById('lastname').value;
$.ajax({
type: "POST",
url: 'search.php',
data: $('#search_fields').serialize(),
dataType: "json",
xhrFields: {
onprogress: function(e) {
var thisResponse, response = e.currentTarget.response;
if(lastResponseLen === false) {
thisResponse = response;
lastResponseLen = response.length;
} else {
thisResponse = response.substring(lastResponseLen);
lastResponseLen = response.length;
}
jsonResponse = JSON.parse(thisResponse);
document.getElementById('progress').innerHTML = 'Progress: '+jsonResponse.msg;
}
},
success: function(data) {
console.log('done!');
document.getElementById('progress').innerHTML = 'Complete!';
document.getElementById('results').innerHTML = data;
}
});
e.preventDefault();
});
});
And here is the basic PHP server script:
<?php
function progress_msg($progress, $message){
echo json_encode(array('progress' => $progress, 'msg' => $message));
flush();
ob_flush();
}
$array = array('msg' => 'hello world');
$count = 0;
while($count < 100){
progress_message($count, "working....");
$count += 10;
sleep(2);
}
return json_encode($array);
?>
I made your code work, there were 2 errors. First, in your while loop, your function name is incorrect, try this:
progress_msg($count, "working... ." . $count . "%");
Secondly, the very last line outputs nothing, so technically you don't get a "successful" json return. Change the last line of your server script from:
return json_encode($array);
to:
echo json_encode($array);
UPDATE: Full working code with hacky solution:
Ajax:
$( document ).ready(function(e) {
var jsonResponse = '', lastResponseLen = false;
$("#btn_search").click(function(e){
var firstname = document.getElementById('firstname').value;
var lastname = document.getElementById('lastname').value;
$.ajax({
type: "POST",
url: 'search.php',
data: $('#search_fields').serialize(),
xhrFields: {
onprogress: function(e) {
var thisResponse, response = e.currentTarget.response;
if(lastResponseLen === false) {
thisResponse = response;
lastResponseLen = response.length;
} else {
thisResponse = response.substring(lastResponseLen);
lastResponseLen = response.length;
}
jsonResponse = JSON.parse(thisResponse);
document.getElementById('progress').innerHTML = 'Progress: '+jsonResponse.msg;
}
},
success: function(data) {
console.log('done!');
dataObjects = data.split("{");
finalResult = "{" + dataObjects[dataObjects.length - 1];
jsonResponse = JSON.parse(finalResult);
document.getElementById('progress').innerHTML = 'Complete!';
document.getElementById('results').innerHTML = jsonResponse.msg;
}
});
e.preventDefault();
});
Search.php:
<?php
function progress_msg($progress, $message){
echo json_encode(array('progress' => $progress, 'msg' => $message));
flush();
ob_flush();
}
$array = array('msg' => 'hello world');
$count = 0;
while($count <= 100){
progress_msg($count, "working... " . $count . "%");
$count += 10;
sleep(1);
}
ob_flush();
flush();
ob_end_clean();
echo json_encode($array);
?>
The problem with the "success" method of the ajax call was that it couldn't interpret the returning data as JSON, since the full return was:
{"progress":0,"msg":"working... 0%"}{"progress":10,"msg":"working... 10%"}{"progress":20,"msg":"working... 20%"}{"progress":30,"msg":"working... 30%"}{"progress":40,"msg":"working... 40%"}{"progress":50,"msg":"working... 50%"}{"progress":60,"msg":"working... 60%"}{"progress":70,"msg":"working... 70%"}{"progress":80,"msg":"working... 80%"}{"progress":90,"msg":"working... 90%"}{"progress":100,"msg":"working... 100%"}{"msg":"hello world"}
Which is not a valid JSON object, but multipje JSON objects one after another.
I tried removing all previous output with ob_end_clean(); , but for some reason I can't figure out, it didn't work on my setup. So instead, the hacky solution I came up with was to not treat the return as JSON (by removing the dataType parameter from the AJAX call), and simply split out the final Json element with string operations...
There has got to be a simpler solution to this, but without the use of a third party jQuery library for XHR and Ajax, I couldn't find any.
I send data via json. It is working well:
$.ajax({
url: "json.php",
type: "POST",
dataType: "json",
encode: true,
data: {},
success: function (data) {
$(".blue").html(data.blue);
$(".red").html(data.red);
}
});
json.php
$array['blue'] = "blue array";
$array['red'] = "red content";
echo json_encode($array);
My problem is now, that instead of..
blue array
...I want to send:
$pdo = $db->query('SELECT * FROM data;');
while ($row = $pdo->fetch(PDO::FETCH_ASSOC)) {
echo "<li>".$row['name']."</li>";
}
is this possible?
Here's an extremely basic example:
<?php
$json = array(
'blue' => '',
'red' => 'Empty red content or whatever'
);
$pdo = $db->query('SELECT * FROM data;');
while ($row = $pdo->fetch(PDO::FETCH_ASSOC)) {
$json['blue'].= "<li>".$row['name']."</li>";
}
echo json_encode($json);
Not sure what logic you would use to actually populate red but you can work it into the while loop or whatever.
is it possible to get two json output on a single page result set
I have to populate data-grid and chart by passing data to another page using ajax and get tow types of json result set from single mysql query, when I try to return json it fails to handle
here is my result.php code where json will be generated,
include('connection.php');
if (isset($_POST)) {
$rep_date1 = $_POST['date1'];
$date1 = date("Y-m-d", strtotime($rep_date1));
$rep_date2 = $_POST['date2'];
$date2 = date("Y-m-d", strtotime($rep_date2));
$sql = mysql_query("SELECT * FROM infra.prob_report WHERE prob_rept_date BETWEEN '$date1' AND '$date2'");
$rows = array();
while ($row = mysql_fetch_assoc($sql)) {
$nestedData = array();
$nestedData[] = $row["rep_id"];
$nestedData[] = $row["prob_rept_date"];
$nestedData[] = $row["prob_equip_name"];
$nestedData[] = $row["prob_rept_name"];
$nestedData[] = $row["prob_desc"];
$data[] = '<tr><td>'.$row["rep_id"].
'</td><td>'.$row["prob_rept_date"].
'</td><td>'.$row["prob_equip_name"].
'</td><td>'.$row["prob_rept_name"].
'</td><td>'.$row["prob_desc"].
'</td></tr>';
$point = array("label" => $row['prob_equip_name'], "y" => $row['rep_id']);
array_push($data_points, $point);
}
echo json_encode($data); //json output populating data-grid
echo json_encode($data_points); //json output populating chart
}
here is my handle.php where my handling script runs,
<script>
$(document).ready(function() {
$('#submit').click(function() {
var name = $("#name").val();
event.preventDefault();
$.ajax({
type: "POST",
url: "new_prob_submit.php",
data: {
'date1': $('#picker1').val(),
'date2': $('#picker2').val()
},
dataType: "json",
success: function(data) {
$('#tbdy').html(data);
$.getJSON("result.php", function(result) {
var chart = new CanvasJS.Chart("chartContainer", {
data: [{
dataPoints: result
}]
});
chart.render();
});
}
});
});
});
</script>
Just do one thing.
In php
echo json_encode(
array(
'data' => $data,
'dataPoints' => $data_points
)
); //json output populating data-grid and populating chart
In javascript
success:function(result){
result.data;
result.dataPoints;
}
I have problems to create an array which is evaluated correctly by jqplot.
If i try it like this, i have an x-axis range from -5 to 95 but with the correct line.
Actually i would expect a chart with x-axis from 0 to 30.
With firebug i can check with typeof that params is an object (array).
Where is the failure?
Here is my getPlotData.php with some dummy data:
$temp = array();
for( $i=0; $i<30; $i++ ){
$temp[] = "[" . $i . "," . ($i*5) . "]";
}
$return['line'] = "[" . implode(',', $temp . "]";
die(json_encode($return));
And here is my ajax function which is calling the createPlot-function:
$.ajax({
type: "GET",
dataType: "json",
url: "getPlotData.php?rand=" + new Date(),
data: data,
cache: false,
success: function(data) {
var params = eval(data['line']);
createPlot(params);
}
});
function createPlot(params){
plot1 = $.jqplot('plot_data', [params], {
series:[{showMarker:true}],
markerOptions: { style:'circle' },
axesDefaults:{
tickRenderer: $.jqplot.CanvasAxisTickRenderer ,
tickOptions: {
fontSize: '14px',
textColor: "#fff"
}
},
axes:{
xaxis:{
labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
label:'Tag',
tickOptions:{
},
labelOptions: {
fontSize: '13pt',
textColor: '#FFFFFF'
}
},
yaxis:{
label:'Anzahl',
labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
tickOptions:{
},
labelOptions: {
fontSize: '13pt',
textColor: '#FFFFFF'
}
}
}
});
Currently you are using implode and json_encode. I guess, that manually creating JSON might produce some kind of error in the output. (Like double encoding the JSON data.)
It should work if you only add the data to the array first and then json_encode whole dataset.
<?php
$temp = array();
for( $i=0; $i < 30; $i++ ) {
$temp[] = array( $i, $i*5 );
}
$return['line'] = $temp;
die( json_encode( $return ) );
I was dealing today with Flot and when I try to get the data from PHP (with json_encode()) I can't get it work properly.
I could display labels but no chart is created.
PHP
$newData = array();
$newData[0] = array();
$newData[1] = array();
$newData[2] = array();
$newData[0]['label'] = 'Slice 1';
$newData[1]['label'] = 'Slice 2';
$newData[2]['label'] = 'Slice 3';
$newData[0]['color'] = '#122b45';
$newData[1]['color'] = '#064792';
$newData[2]['color'] = '#9e253b';
$newData[0]['data'] = array();
$newData[0]['data'][0] = 1;
$newData[0]['data'][1] = 1000;
$newData[1]['data'] = array();
$newData[1]['data'][0] = 1;
$newData[1]['data'][1] = 500;
$newData[2]['data'] = array();
$newData[2]['data'][0] = 1;
$newData[2]['data'][1] = 100;
echo json_encode($newData);
jQuery
$.ajax({
url: "get-stats.php",
type: "POST",
async: false,
dataType : 'JSON',
data: {section: section, endDate: endDate, startDate: startDate},
success: function(data){
$.plot($("#flot"), data,{
series: {
pie: {
show: true
},
grid: {
hoverable: true,
clickable: true
}
}
}
});
Can anyone tell me where I'm doing wrong?
Labels and colors are ok but it seems I can't get the data.
Thank you for your time and concern in advance.
I found the problem and solution. I had to do following for the data;
$newData[0]['data'] = array(array(1,100));
This saved my day.