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.
Related
I am working on Highcharts using PHP/MYSQL. Data is showing properly in each chart but I tried to change one chart to ajax call in order to reduce page load.
I am generating multiple series data from PHP and displaying them back in the required format but data is not showing(I alerted the data it's coming).
Below is the code of ajax call:
function project_wise_lab(from_date, to_date) {
$.ajax({
type: "POST",
url: 'dashboard/project_wise_labtest',
data: {
from_dte: from_date,
to_dte: to_date
},
success: function(response) {
Highcharts.chart('subcontainer7', {
chart: {
type: 'line',
height: 230,
},
credits: {
enabled: false
},
title: {
text: null
},
xAxis: {
categories: ['Oct 2020', 'Nov 2020', 'Dec 2020', 'Jan 2021', 'Feb 2021', 'Mar 2021', 'Apr 2021', 'May 2021']
},
yAxis: {
min: 0,
title: {
// text: 'Total fruit consumption'
},
stackLabels: {
enabled: false,
style: {
fontWeight: 'bold',
color: ( // theme
Highcharts.defaultOptions.title.style &&
Highcharts.defaultOptions.title.style.color
) || 'gray'
}
}
},
legend: {
align: 'center',
verticalAlign: 'bottom',
backgroundColor: Highcharts.defaultOptions.legend.backgroundColor || 'white',
borderColor: '#CCC',
// borderWidth: 1,
shadow: false
},
tooltip: {
/* headerFormat: '<b>{point.x}</b><br/>',
pointFormat: '{series.name}: {point.y}<br/>Total: {point.stackTotal}'
*/
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
// enabled: true
}
}
},
colors: [
'#4a7fbb',
'#be4c48',
'#97b954',
'#7d6096'
],
series: response
});
console.log(response);
},
error: function(xhr, status, error) {
console.error(xhr);
}
});
}
I have alerted the response and the data is showing in the below format:
{ name : 'FKI',data : [10591,10576,9309,8422,9586,11171,9327,9384] },{ name : 'FKR',data : [4740,3105,2690,3598,3686,4930,3711,3859] },{ name : 'FHR',data : [17190,12757,10837,11944,14083,15748,12544,12494] },{ name : 'FUL',data : [1308,937,1002,1086,1452,1419,1248,1362] },{ name : 'FSW',data : [9535,9102,8689,8420,9941,10915,7273,6930] },{ name : 'FWP',data : [47437,42198,43012,44979,47377,55400,46520,41682] },{ name : 'FGR',data : [2112,1366,1619,1664,2387,2355,1633,1215] }
New Response after update:
[{"name":"FKI","data":{"01-OCT-20":"10591","01-NOV-20":"10576","01-DEC-20":"9309","01-JAN-21":"8422","01-FEB-21":"9586","01-MAR-21":"11171","01-APR-21":"9332","01-MAY-21":"9384"}},{"name":"FKR","data":{"01-OCT-20":"4740","01-NOV-20":"3105","01-DEC-20":"2690","01-JAN-21":"3598","01-FEB-21":"3686","01-MAR-21":"4930","01-APR-21":"3711","01-MAY-21":"3859"}},{"name":"FHR","data":{"01-OCT-20":"17190","01-NOV-20":"12757","01-DEC-20":"10837","01-JAN-21":"11944","01-FEB-21":"14083","01-MAR-21":"15748","01-APR-21":"12544","01-MAY-21":"12494"}},{"name":"FUL","data":{"01-OCT-20":"1308","01-NOV-20":"937","01-DEC-20":"1002","01-JAN-21":"1086","01-FEB-21":"1452","01-MAR-21":"1419","01-APR-21":"1248","01-MAY-21":"1362"}},{"name":"FSW","data":{"01-OCT-20":"9535","01-NOV-20":"9102","01-DEC-20":"8689","01-JAN-21":"8420","01-FEB-21":"9941","01-MAR-21":"10915","01-APR-21":"7273","01-MAY-21":"6930"}},{"name":"FHP","data":{"01-OCT-20":"47437","01-NOV-20":"42198","01-DEC-20":"43012","01-JAN-21":"44979","01-FEB-21":"47377","01-MAR-21":"55400","01-APR-21":"46520","01-MAY-21":"41682"}},{"name":"FGR","data":{"01-OCT-20":"2112","01-NOV-20":"1366","01-DEC-20":"1619","01-JAN-21":"1664","01-FEB-21":"2387","01-MAR-21":"2355","01-APR-21":"1633","01-MAY-21":"1215"}}]
The chart is showing empty, kindly help and let me know to get the issue resolve?
Thanks
You appear to have two problems...
jQuery is interpreting your response as plain text (a string) where Highcharts expects actual JS objects
Your response is not valid JSON so you can't interpret it as such on the client-side. Rule #1 when creating JSON responses is... never roll your own JSON.
I recommend getting PHP to generate valid JSON and respond with the correct Content-type
// Ensure jQuery (or any consumer) knows the response is JSON
header("Content-type: application/json");
// Create a data structure representing the series data
$data = [];
foreach ($project as $key => $value) {
$data[] = [
"name" => $key,
"data" => array_values($value) // you just want the values here, not the keys
];
}
// Respond with JSON
echo json_encode($data);
exit;
Then in your client-side code, you can simply use
series: response
as response will now be a valid JS array
You can also make sure jQuery treats the response as JSON by adding
dataType: "json",
to your $.ajax() options but with the right Content-type response header, jQuery should not need this.
Just an FYI, alert() is terrible for viewing data. The best option would be to use your browser's debugger. The second best option is to use console.log()
Within my Laravel project I am implementing the chart.js library trying to visualize a bar graph.
Which should show all work orders in finished status that were assigned to users with the operator role.
When you want to graph, simply no data is displayed, it is an empty graph.
This is my ReportController controller with this method public function getChart () I do my query
public function getChart(Request $request)
{
$_orders = DB::table('users')
->join('orders','orders.user_id','=','users.id')
->join('model_has_roles', 'users.id', '=', 'model_has_roles.model_id')
->select('users.id','users.name', DB::raw('COUNT(orders.id) as orders_by_user'), 'model_has_roles.role_id as rol')
->where('model_has_roles.role_id', '2');
$_orders->groupBy('orders.user_id', 'users.id', 'users.name', 'model_has_roles.role_id');
$orders=$_orders->get();
return ['orders' => $orders];
}
This is the result of my query: as it is observed I have what I need username and the number of orders completed per user.
{
"orders": [
{
"id": 4,
"name": "Luis",
"orders_by_user": 2,
"rol": 2
},
{
"id": 6,
"name": "Jose",
"orders_by_user": 1,
"rol": 2
},
{
"id": 7,
"name": "Miguel",
"orders_by_user": 1,
"rol": 2
}
]
}
Here is an important question: is the JSON structure returned by my query correct? With this result can I graph?
This is my report.js file for the graph:
With the renderChart() method:
I make the graph, through the data obtained in my ajax call.
With the getChartData () method:
I make my ajax call.
function renderChart(data, labels) {
var ctx = document.getElementById("orders").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: 'ordenes',
data: data,
borderColor: 'rgba(75, 192, 192, 1)',
backgroundColor: 'rgba(75, 192, 192, 0.2)',
borderWidth: 1,
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
},
title: {
display: true,
text: "Ordenes en estado terminado"
},
}
});
}
function getChartData() {
$.ajax({
url: '/admin/reports/getChart',
type: 'GET',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
dataType: 'json',
success: function (data) {
// console.log(data);
var data = [];
var labels = [];
for (var i in data) {
data.push(data[i].orders_by_user);
labels.push(data[i].name);
}
renderChart(data, labels);
},
error: function (data) {
console.log(data);
}
});
}
$("#renderBtn").click(
function () {
getChartData();
}
);
In other words I am looking to optimize my query using eloquent, so that it returns a valid JSON response for chart.js.
Dump those data obtained through an ajax call and draw
Could you help me find and solve my error?
UPDATED 1
Just in case if any error arises change my for: for (var i in data) to this: for (var i in response)
So it looks like this:
for (var i in response) {
data.push(response[i].orders_by_user);
labels.push(response[i].name);
}
I think that I am not accessing correctly the data that I get from my query to later graph.
In the console I see the following information:
{orders: Array(3)}
orders: Array(3)
0: {id: 4, name: "Luis", orders_by_user: 2, rol: 2}
1: {id: 6, name: "Jose", orders_by_user: 1, rol: 2}
2: {id: 7, name: "Miguel", orders_by_user: 1, rol: 2}
length: 3
__proto__: Array(0)
__proto__: Object
Orders is my array, so how can I just access orders_by_user and name and correctly pass it to my data.push and labels.push
try something like this but it doesn't work:
data.push(response[i].orders.orders_by_user);
labels.push(response[i].orders.name);
Apologies if the question is unclear. Its hard to convey without explaining. So I'm dynamically getting table data from mysql database, and using it in my front-end React app. In my front-end I have a columns array which contains objects. Each object has different attributes like title, field, type,hidden, etc... Each of these objects represent a column and it's associated settings. I have already dynamically got the column name and I know how to get the type, but I'm not sure how to store the boolean settings like editable, filtering and hidden.
I thought of possibly storing them in a JSON config file or creating a separate table just to store all the settings for each column.
//use map function to create columns from column_fields in props
const columns2 = props.column_fields.map(column_name => {
return (
//TODO: correctly configure all attributes
{title:column_name, field:column_name, type:'string', editable:'true', filtering:'true', editable:'true', hidden:'false'}
)
})
Something like this
const props = { column_fields: ["id", "name", "age"] };
const column_settings = {
id: {
type: "string",
editable: true,
filtering: true,
editable: true,
hidden: false
},
name: {
type: "string",
editable: true,
filtering: true,
editable: true,
hidden: false
},
age: {
type: "number",
editable: true,
filtering: true,
editable: true,
hidden: false
}
};
//use map function to create columns from column_fields in props
const columns2 = props.column_fields.map(column_name => {
return (
//TODO: correctly configure all attributes
{
title: column_name,
field: column_name,
...column_settings[column_name]
}
);
});
So if anyone stumbles upon this, I simply used a JSON file to store all the information I need about specific table columns, e.g. :
{
"table1": {
"id": {
"type": "numeric",
"hidden": false,
"filtering": true,
"editable": "never"
},
"name": {
"type": "string",
"hidden": false,
"filtering": true,
"editable": null
},
},
"table2": {
"phone": {
"type": "string",
"hidden": false,
"filtering": true,
"editable": null
},
"age": {
"type": "numeric",
"hidden": false,
"filtering": true,
"editable": null
}
}
}
I get this file in my server-side php and send everything to my frontend. Now I can access values via props in my React project.
//use map function to create columns from column_fields in props
let i = 0;
let columns = props.column_fields.map(column => {
i++;
if (column.field != 'updated_at') {
return ({
title: column.field, field: column.field, type: props.column_fields[i - 1].type, editable: props.column_fields[i - 1].editable,
filtering: props.column_fields[i - 1].filtering, hidden: props.column_fields[i - 1].hidden
})
}
})
Hopefully this method works out long term.
I'm migrating from extjs 2.2 to extjs 4.0. My code filters my grid data trough an php (the proxy url) that POST the some ext fields.
etx store:
var store = Ext.create('Ext.data.Store', {
model: 'Company',
remoteSort: true,
remoteFilter: true,
proxy: {
// load using script tags for cross domain, if the data in on the same domain as
// this page, an HttpProxy would be better
type: 'ajax',
url: "logica_de_aplicacao/usuario/grid_usuarios_dados.php",
reader: {
root: 'results',
totalProperty: 'total'
},
// sends single sort as multi parameter
simpleSortMode: true
},
sorters: [{
property: 'nome',
direction: 'ASC'
}]
});
ext fields (two exemples, there are too many fields):
var txtLogin = new Ext.form.TextField({
fieldLabel: "Login",
width: 200
});
var txtAtivo = new Ext.form.ComboBox({
fieldLabel: 'Ativo',
width: 200,
name: 'ativo',
editable: false,
disableKeyFilter: true,
forceSelection: true,
triggerAction: 'all',
mode: 'local',
store: new Ext.data.SimpleStore({
id: 0,
fields: ['value', 'text'],
data : [['S', 'Sim'], ['N', 'Não']]
}),
valueField: 'value',
displayField: 'text',
hiddenName: 'ativo'
});
Filtering:
tbar: [{
text: "Adicionar Filtro", //add filter
tooltip: "Filtre os resultados",
iconCls:"icone_filtro",
handler: function() {
iniciaPesquisa();
}
}, {
text: "Remover Filtro", //remove filter
tooltip: "Cancelar o filtro",
iconCls:"icone_cancel_filtro",
handler: function() {
store.baseParams = {
login: "",
nome: "",
privilegio: "",
ativo: "",
municipio: ""
};
store.removeAll();
store.load();
}
}],
PHP:
...
$login = $_POST["login"];
...
$ativo = $_POST["ativo"];
In ext 2.2 that would normally post the fields content on the store.load() action, but nothing happens now. How could I post those fields in ext 4?
(apologizes for the bad english)
It's actually simpler now, just use store.clearFilter()
store.clearFilter();
store.removeAll();
store.load();
var store = Ext.create('Ext.data.Store', {
model: 'Company',
remoteSort: true,
remoteFilter: true,
proxy: {
// load using script tags for cross domain, if the data in on the same domain as
// this page, an HttpProxy would be better
type: 'ajax',
url: "logica_de_aplicacao/usuario/grid_usuarios_dados.php",
baseParams: { //here you can define params you want to be sent on each request from this store
login: "",
nome: "",
privilegio: "",
ativo: "",
municipio: ""
},
reader: {
root: 'results',
totalProperty: 'total'
},
// sends single sort as multi parameter
simpleSortMode: true
},
sorters: [{
property: 'nome',
direction: 'ASC'
}]
});
tbar: [{
text: "Adicionar Filtro", //add filter
tooltip: "Filtre os resultados",
iconCls:"icone_filtro",
handler: function() {
iniciaPesquisa();
}
}, {
text: "Remover Filtro", //remove filter
tooltip: "Cancelar o filtro",
iconCls:"icone_cancel_filtro",
id : 'BtnRemoveFilter', // added this
handler: function() {
store.baseParams = {
login: "",
nome: "",
privilegio: "",
ativo: "",
municipio: ""
};
store.removeAll();
store.load();
}
}],
var Btn = Ext.getCmp('BtnRemoveFilter');
Btn.on('click', function(){
store.load({
params: { //here you can define params on 'per request' basis
login: "the value u want to pass",
nome: "the value u want to pass",
privilegio: "the value u want to pass",
ativo: "the value u want to pass",
municipio: "the value u want to pass"
}
})
});
try this code is working or not.i think this is what u want
So What I'm trying to do is populate an Extjs line graph. I've created a JSON store that pulls json from a remote page and for some reason my graph is not being populated.
Heres my Ext code:
Ext.onReady(function(){
var store = new Ext.data.JsonStore({
autoDestroy: true,
url: 'http://myURL.com',
storeId: 'graphStore',
root: 'rows',
idProperty: 'date',
fields: ['date', 'posts']
});
new Ext.Panel({
title: 'Posts',
renderTo: 'test_graph',
width:500,
height:300,
layout:'fit',
items: {
xtype: 'linechart',
store: store,
xField: 'date',
yField: 'posts',
listeners: {
itemclick: function(o){
var rec = store.getAt(o.index);
Ext.example.msg('Item Selected', 'You chose {0}.', rec.get('date'));
}
}
}
});
});
And here's the JSON that is supposed to be populating it:
{"rows":[
{"date":"2010-06-11","posts":4},
{"date":"2010-06-12","posts":3},
{"date":"2010-06-13","posts":1},
{"date":"2010-06-14","posts":2}
]}
I can't figure out for the life of me why this won't work. The graph axis shows up, but the line doesn't render.
I was having the same problem, even with store.autoLoad set to true
Actually, everything worked great when I hardcoded the json results into the page. But when I tried to use ajax to pull it from a database, the line never rendered! This wasn't a problem reading from the database, either. I verified that it was definitely pulling from the database.
I solved this by setting autoLoad to false and added store.load() after actual chart rendered and it worked totally fine.
you may want to set the autoLoad property to true on the store, such as:
var logsRemoteJsonStore = new Ext.data.JsonStore
({
proxy: logsRemoteProxy
, storeId: 'ourRemoteStore'
, autoLoad: true
, fields: logsRecordFields
});
In fact, verified that the following code from http://joefreeman.co.uk/projects/extstock/part-2.html does work, so it is almost certainly the autoload parameter, but review the other parameters in the example below.
Ext.onReady(function () {
var store = new Ext.data.JsonStore({
baseParams: {
symbol: 'GOOG'
},
autoLoad: true,
url: '/CMSAdmin/ReadSiteStatisticsEightMonthSummary/',
root: 'data',
fields: ['date', 'close']
});
new Ext.Window({
title: 'GOOG',
width: 400,
height: 300,
items: new Ext.chart.LineChart({
store: store,
xField: 'date',
yField: 'close'
})
}).show();
});
json:
{
"symbol": "GOOG",
"start": 1279627043,
"span": 32140800,
"data": [{
"close": 462,
"date": "2010-08-20"
}, {
"close": 476,
"date": "2010-09-09"
}, {
"close": 527,
"date": "2010-09-28"
}, {
"close": 601,
"date": "2010-10-15"
}, {
"close": 620,
"date": "2010-11-03"
}, {
"close": 591,
"date": "2010-11-22"
}, {
"close": 592,
"date": "2010-12-10"
}, {
"close": 598,
"date": "2010-12-30"
}, {
"close": 631,
"date": "2011-01-19"
}]
}