jqGrid not displaying JSON data - asp.net-mvc-2

I'm using asp.net mvc to create a webpage that renders a jqGrid for data in my azure table. The grid will callback into my controller and using the debugger, I can visually verify data is being generated correctly. The issue is that once the data is returned as a JSON string, the jqGrid throws this error:
b.jgrid.getAccessor(p, d.cell) is undefined
http://localhost:54758/jquery.jqGrid.min.js
Line 65
I've looked online for documentation but have been unsuccessful in returning anything except what appears to be repository snapshots. I've stripped down my code to only have one column of data (shown below) returned as a string and still nothing.
If I add the line "datatype: 'local'," to my jqGrid options, the error isn't thrown. However, data is still not being rendered either. None of the other questions suggested in "Similar Questions" solved my issue. The data is just an Id field and is a simple C# string.
Below is the aspx file contents used to render the jqGrid:
<asp:Content ID="Content2" ContentPlaceHolderID="HeadContent" runat="server">
<%--Must load language tag BEFORE script tag--%>
<script src="grid.locale-en.js" type="text/javascript"></script>
<script src="jquery.jqGrid.min.js" type="text/javascript"></script>
<script type="text/javascript">
jQuery(document).ready(function () {
jQuery("#list").jqGrid({
autowidth: true,
url: '/HouseData/GridData/',
datatype: 'local', <---instead of 'local' I also tried 'jsonstring'
mtype: 'POST',
colNames: ['House Name'],
colModel: [
{ name: 'houseName', index: 'houseName', key: true, width: 80, align: 'right', hidden: false }],
pager: jQuery('#pager'),
rowNum: 20,
rowList: [5, 10, 20, 50],
sortname: 'houseName',
sortorder: "desc",
height: 400,
viewrecords: true,
imgpath: ''
});
});
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<div id="main">
<h2>Show House Name</h2>
<div class="disignBoxFirst">
<div class="boxContent">
<%: Html.Partial("HouseDataSearch") %>
</div>
</div>
<hr />
<table id="list" class="scroll" cellpadding="0" cellspacing="0"></table>
<div id="pager" class="scroll" style="text-align:center;"></div>
</div>
</asp:Content>
The function used to compose the json string, contained in the C# file "HouseDataController.cs", is below (initially I didn't have the "datatype" option in the aspx file shown above for the jqGrid):
public JsonResult GridData(string sidx, string sord, int page, int rows, string houseName)
{
//Setup values to return to the view for display of user entered values
ViewData["HouseName"] = houseName;
//Get table data
CloudStorageAccount storageAccount = CloudStorageAccount.FromConfigurationSetting("ConnectionString");
ReportStorageDataServiceContext storageContext = new ReportStorageDataServiceContext(storageAccount.TableEndpoint.ToString(), storageAccount.Credentials);
int houseCount = 0;
IQueryable<HouseDataModel> houses = storageContext.CreateQuery<HouseDataModel>("HouseDataTable").Where(h => h.isAvailable == true);
List<HouseDataModel> queryDetails = new List<HouseDataModel>();
foreach (HouseDataModel house in houses)
{
queryDetails.Add(house);
houseCount++;
}
//Figure out paging
int pageIndex = Convert.ToInt32(page) - 1;
int pageSize = rows;
int totalRecords = houseCount;
int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize);
var jsonData = new
{
total = totalPages,
page,
records = totalRecords,
rows = (from house in queryDetails select new { User = house.houseName }).ToArray()
};
return Json(jsonData);
}
The error message was caught using Firebug. If this is not specific/detailed enough or if it was resolved in another thread please advise.
Thanks!

Try this:
jQuery("#list").jqGrid({
autowidth: true,
url: '/HouseData/GridData/',
datatype: 'local', <---instead of 'local' I also tried 'jsonstring'
mtype: 'POST',
colNames: ['House Name'],
colModel: [
{ name: 'houseName', index: 'houseName', key: true, width: 80, align: 'right', hidden: false }],
pager: jQuery('#pager'),
rowNum: 20,
rowList: [5, 10, 20, 50],
sortname: 'houseName',
sortorder: "desc",
height: 400,
viewrecords: true,
imgpath: '',
jsonReader : {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
cell: "cell",
id: "id",
userdata: "userdata",
},
});
I added the jsonReader part. I had the same problem and this seems to fix it.

Try changing the jqgrid's mtype to 'GET' and datatype to 'json':
datatype: 'json'
mtype: 'GET'
and change your GridData controller action's return to:
return Json(data, JsonRequestBehavior.AllowGet);

Related

Highcharts - How to add background in bar series? And how to print page without lose quality?

I need your help, i try use "pattern" in Highcharts to use background in bars, but the images don't fill the space that i wanna.
Bar Chart Example
I wanna know, how i do to leave the image with -90° than the way that is? And how i do to leave the image with height 100% and width 25%?
And beyond that i wanna of know, how i print the screen without lose the quality in image, because when i press "ctrl+p" i see all all blurred.
Print blurred
Follow below the current code:
<!DOCTYPE html>
<html>
<head>
<title>HighCharts - Pattern Color</title>
<meta http-equiv="Content-Type" contetn="text/html;" charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="http://code.jquery.com/ui/1.9.1/themes/base/jquery-ui.css" />
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://code.jquery.com/ui/1.9.1/jquery-ui.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://highcharts.github.io/pattern-fill/pattern-fill.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(function() {
Highcharts.chart('container', {
chart: {
type: 'bar',
backgroundColor: null
},
title: {
text: 'Como você está?'
},
xAxis: {
categories: ['']
},
yAxis: {
min: 0,
title: {
text: ''
}
},
legend: {
reversed: true
},
plotOptions: {
series: {
stacking: 'percent',
dataLabels: {
enabled: true,
format: '<b>{point.percentage:.2f}%</b>',
//point.percentage:.1f
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white'
}
}
},
series: [{
name: 'Alegre',
data: [30],
color: {
pattern: 'http://emoticons.topfriends.biz/favicon.png',
width: '30',
height: '30'
}
// color: '#B22222'
}, {
name: 'Feliz',
data: [30],
color: {
pattern: 'https://t4.ftcdn.net/jpg/01/58/30/09/240_F_158300957_MhRWEx1vDO6SPVHdGS4dqNG7nLP8rdZ4.jpg',
width: '30',
height: '30'
}
// color: '#2E8B57'
}]
});
});
</script>
<div id="container" style="min-width: 80%; height: 200px; max-width: 80%; margin: 0 auto"></div>
</body>
</html>
Since now i thanks!
1. PATTERN FILL ADJUSTMENT
Refer to this live working example: http://jsfiddle.net/kkulig/opa73k8L/
Full code:
var redrawEnabled = true,
ctr = 0;
$('#container').highcharts({
chart: {
events: {
render: function() {
if (redrawEnabled) {
redrawEnabled = false;
var chart = this,
renderer = chart.renderer;
chart.series[0].points.forEach(function(p) {
var widthRatio = p.shapeArgs.width / p.shapeArgs.height,
id = 'pattern-' + p.index + '-' + ctr;
var pattern = renderer.createElement('pattern').add(renderer.defs).attr({
width: 1,
height: widthRatio,
id: id,
patternContentUnits: 'objectBoundingBox'
});
renderer.image('http://emoticons.topfriends.biz/favicon.png', 0, 0, 1, widthRatio).attr({
}).add(pattern);
p.update({
color: 'url(#' + id + ')'
}, false);
});
ctr++;
chart.redraw();
redrawEnabled = true;
}
}
}
},
series: [{
type: 'bar',
borderWidth: 1,
borderColor: '#000000',
data: [10, 29.9, 71.5]
}]
});
In the redraw event I iterate all the points, create a separate pattern for every point based on its width/height ratio, apply pattern and redraw the chart.
On every redraw new set of patters are created which is not an elegant solution (old ones should be replaced instead). ctr variable is used to create unique name for each pattern.
redrawEnabled serves to prevent infinite recursive loop because chart.redraw() also calls the render event.
In my opinion the easiest way to have the rotated image is to simply provide the already rotated one.
API references:
https://api.highcharts.com/highcharts/chart.events.render
https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#createElement
https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#image
2. PRINTING ISSUE
It seems to be a bug reported here: https://github.com/highcharts/pattern-fill/issues/20

Google timeline graph is not working showing "Invalid data table format: must have 3 or 4 data columns" in html page

Google timeline graph is not working, i converted python datatime to google date string , then i passed my array to google charts ,google chart is not shown and showing "Invalid data table format: must have 3 or 4 data columns" in html page.
Json object : `
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
<script type="text/javascript">
google.charts.load("current", {packages:["timeline"]});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var container = document.getElementById('example3.1');
var chart = new google.visualization.Timeline(container);
// var dataTable = google.visualization.arrayToDataTable(
/*
[
['Category', 'Name', {role: 'style'}, {type: 'date'}, {type: 'date'}],
//'Date(2000, 8, 5)'
['BINGEN', '1', '#FF0000', 'Date(2014, 7, 1,12,01,01)', 'Date(2014, 7, 1,14,03,02)'],
['NRT', '1', '#228B22', 'Date(2014, 7, 1,10,10,10)', 'Date(2014, 7, 1,12,10,10)'],
['REGRESSION', '1', '#FF0000', 'Date(2014, 7, 1,09,10,12)', 'Date(2014, 7, 1,12,02,01)'],
['BINGEN', '2', '#FF0000', 'Date(2014, 7, 1,14,30,01)', 'Date(2014, 7, 1,16,03,02)'],
['NRT', '2', '#228B22', 'Date(2014, 7, 1,14,10,10)', 'Date(2014, 7, 1,16,10,10)'],
['REGRESSION', '2', '#FFFF00', 'Date(2014, 7, 1,14,10,12)', 'Date(2014, 7, 1,20,02,01)']
]);
*/
var jsonData = $.ajax({
url: "/jenkins/2017-02-10",
dataType: "json",
async: false
}).responseText;
var my_data = JSON.parse(jsonData);
my_data.splice(0, 0, ['Category', 'Name', {role: 'style'}, {type: 'date'}, {type: 'date'}]);
var dataTable = new google.visualization.DataTable(my_data);
chart.draw(dataTable);
}
</script>
<div id="example3.1" style="height: 200px;"></div>
</body>
</html>
`
Below is the html page
if you're using simple array data, as shown commented out in the question
you cannot feed that directly to --> google.visualization.DataTable
need to use static method instead --> google.visualization.arrayToDataTable
var dataTable = google.visualization.arrayToDataTable(my_data);
to feed directly to --> google.visualization.DataTable,
must be in the json format found here...
Format of the Constructor's JavaScript Literal data Parameter

ag-Grid javaScript, TypeError: rowData is undefined

ag-Grid, following the official demo of javascript but using API like real world over hard-coded data. Note: no jQuery, just use the primitive plain XMLHttpRequest() for ajax.
F12 verified API returns data in the same structure as demo, has children node inside, and gripOptions.rowData is assigned with the returned data.
Tried instantiating rowData inside of gripOptions as
rowData: [], got the same error
Or
rowData: {}, got ReferenceError: rowData is not defined.
HTML:
<script src="/scripts/agGrid/ag-grid.js"></script>
<script src="/scripts/agGrid/myAG.js"></script>
<br />JavaScript ag-Grid
<div id="myGrid" style="height: 200px;" class="ag-fresh"></div>
myAG.js:
var httpApi = new XMLHttpRequest();
var columnDefs = [
{ headerName: "Client Name", field: "ClientName", unSortIcon: true, cellRenderer: "group" },
{ headerName: "Division", field: "Division" },
{ headerName: "Others", field: "Others" }
];
var gridOptions = {
columnDefs: columnDefs,
getNodeChildDetails: getNodeChildDetails
};
function getNodeChildDetails(rowItem) {
if (rowItem.ClientName) {
return {
group: true,
// provide ag-Grid with the children of this group
children: rowItem.children,
// the key is used by the default group cellRenderer
key: rowItem.ClientName
};
} else {
return null;
}
}
// wait for the document to be loaded, otherwise
// ag-Grid will not find the div in the document.
document.addEventListener("DOMContentLoaded", function () {
$.ajax({
type: "GET",
url: "/api/myAG/Tree",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
gridOptions.rowData = data;
var eGridDiv = document.querySelector('#myGrid');
new agGrid.Grid(eGridDiv, gridOptions);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
})
});
Version:
ag-grid = v8.1.0
FireFox = 50.1.0
Error message:
F12 confirms data exists and assigned:
inside of ag-grid.js, the line it complains about but rowData has data:
See this answered post, basically an additional check is needed for the tree.
ag-Grid, try to make Tree Demo work using own data

How to export kendoui dataviz chart to (.png) or (.jpg) image format by poping up Save-As window?

I am using kendoui dataviz charts, and I need to export those charts into (.png) or (.jpg) image format.
Basically kendoui dataviz chart has a built-in method called 'svg()'.
'svg()' Returns the SVG representation of the current chart. The returned string is a self-contained SVG document.
Example
var chart = $("#chart").data("kendoChart");
var svgText = chart.svg();
Now svgText contains details of chart image..can anybody tell me how to convert these data to actual image format and pop up a Save As prompt ???
code example: I tried this, but it doesn't prompt any 'SaveAs' popup
<div id="example" class="k-content">
<div class="chart-wrapper">
<div id="chart"></div>
<center>
<div>
<input type="button" value="click" onclick="disp();" />
</div>
</center>
<div>
<canvas id="canvas"></canvas>
</div>
</div>
</div>
<script type="text/javascript">
function disp() {
var chart = $("#chart").data("kendoChart");
var svgText = chart.svg();
var c = document.getElementById('canvas');
canvg(c,svgText);
var img = c.toDataURL("image/png");
document.write('<img src="' + img + '"/>');
window.win = open(imgOrURL);
setTimeout('win.document.execCommand("SaveAs")', 100);
}
function createChart() {
$("#chart").kendoChart({
theme: $(document).data("kendoSkin") || "default",
title: {
text: "Internet Users"
},
legend: {
position: "bottom"
},
chartArea: {
background: ""
},
seriesDefaults: {
type: "bar"
},
series: [{
name: "World",
data: [15.7, 16.7, 20, 23.5, 26.6]
}, {
name: "United States",
data: [67.96, 68.93, 75, 74, 78]
}],
valueAxis: {
labels: {
format: "{0}%"
}
},
categoryAxis: {
categories: [2005, 2006, 2007, 2008, 2009]
},
tooltip: {
visible: true,
format: "{0}%"
}
});
}
$(document).ready(function () {
setTimeout(function () {
createChart();
},100);
$(document).bind("kendo:skinChange", function (e) {
createChart();
});
});
<script>
UPDATE 2
The Chart now includes various export options - PNG, SVG and a vector PDF. See the Export demo for reference.
UPDATE
The Chart now has built-in method for obtaining the exported image (base64 encoded):
var img = chart.imageDataURL();
I'm not aware of a cross-browser way to display a "Save As" dialog.
See also: API Reference
Original response follows:
Exporting the Chart image in-browser is not possible. We have prepared a demo that shows how to convert the SVG document to PNG/PDF on the server using Inkscape.
The demo application is implemented in ASP.NET MVC, but does not depend on any of its features and can be ported to other frameworks.
You can find the demo on GitHub:
https://github.com/telerik/kendo-examples-asp-net/tree/master/chart-inkscape-export
U can do like this.
For this approach u need svg.dll
U can download from this link.
http://svg.codeplex.com/releases/view/18884
Javascript:
var chart = $("#chart").data("kendoChart");
var svgString = escape(chart.svg());
$.ajax({
url: "/MyController/Sample",
data: { svg: svgString },
async: false,
type: 'Post',
success: function (data) {
window.location = "/MyController/getPdf";
}
});
Controller:
[HttpPost]
[ValidateInput(false)]
public void Sample(string svg)
{
var svgText = System.Web.HttpUtility.UrlDecode(svg);
Session["chrtData"] = svgText;
}
public void getPdf()
{
string svgText = Session["chrtData"].ToString();
var byteArray = Encoding.ASCII.GetBytes(svgText);
using (var stream = new MemoryStream(byteArray))
{
var svgDocument = Svg.SvgDocument.Open(stream);
//First Way
var bitmap = svgDocument.Draw();
MemoryStream docMemStream = new MemoryStream();
bitmap.Save("D:\\hi.png", System.Drawing.Imaging.ImageFormat.Png);
}
}

How to get select's value in jqGrid when using <select> editoptions on a column

I have a couple of columns in jqGrid with edittype="select". How can I read the option value of the value currently selected in a particular row?
e.g.: When I provide the following option, how do I get "FE" for FedEx, etc.
editoption: { value: “FE:FedEx; IN:InTime; TN:TNT” }
getRowData() for the rowId/cellname returns only the text/displayed component of the select.
If I set a "change" data event on the column, the underlying fires change events only on mouse clicks, and not keyboard selects (there's numerous references to generic selects and mouse/keyboard issues).
Bottomline, when a new value is selected, I need to know the option value at the time of the change, and also prior to posting to the server.
You have to set the formatter of the column to 'select'
Example from the wiki:
colModel : [ {name:'myname',
edittype:'select', formatter:'select',
editoptions:{value:"1:One;2:Two"}} ...
]
See more here jqgridwiki
I was having the same problem and this worked like a charm
I just solved this question by using setting JqGrid unformat option and use the following function for unformatting cell value.
function Unformat_Select(cellvalue, options, cellobject)
{
var unformatValue = '';
$.each(options.colModel.editoptions.value, function (k, value)
{
if (cellvalue == value)
{
unformatValue = k;
}
});
return unformatValue;
}
The above method will be called everytime when grid need cell data like when you call "getRowData" method. However, my function only support key-paired value edit option. You need to change your data like the following pattern.
editoption:
{
value:
{
FE:'FedEx',
IN:'InTime',
TN:'TNT'
}
}
For more information about unformat option, you can see at the following link.
JqGrid Wiki - Custom Formatter
PS. It's possible to modify my function to support client-side dropdownlist value. But I think it's impossible to apply this function for server-side dropdownlist value.
Update
In the latest jqGrid 3.8.1, I just found some bug when user cancel editing row(or programmatically call "restoreRow" method), jqGrid will create label by using key of data (instead of value of data). I create the following function to fix this issue. For use this, you must it as custom formatter function of this column. This function maps cell value to value of list by comparing key or value.
function JqGridInlineEditor_SelectFormatter(cellvalue, options, rowObject)
{
var temp = '';
$.each(options.colModel.editoptions.value, function (key, value)
{
if (cellvalue == key || cellvalue == value)
{
temp = value;
return false;
}
});
return temp;
}
So, you can send key or value as column data to be rendered by the above custom formatter.
If in case you have requirement where each row has dropdown and it has values like
FE:'FedEx',
IN:'InTime',
TN:'TNT'
Now instead of saving the data to backend on dropdown change event;you want to save data on "Save" button click at row level but want to save dropdwon selected value (TN) not display text(TNT). You can create another hidden field to set selected country code on inline editing of dropdown. Here when user exit after cell inline editing afterSaveCell method will be called and you can set it as mentioned in below code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>http://stackoverflow.com/q/9655426/315935</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/redmond/jquery-ui.css" />
<link rel="stylesheet" type="text/css" href="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-4.3.1/css/ui.jqgrid.css" />
<style type="text/css">
html, body { font-size: 75%; }
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js"></script>
<script type="text/javascript" src="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-4.3.1/js/i18n/grid.locale-en.js"></script>
<script type="text/javascript">
$.jgrid.no_legacy_api = true;
$.jgrid.useJSON = true;
</script>
<script type="text/javascript" src="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-4.3.1/js/jquery.jqGrid.src.js"></script>
<script type="text/javascript">
//<![CDATA[
/*global $ */
/*jslint devel: true, browser: true, plusplus: true, nomen: true, unparam: true */
$(document).ready(function () {
'use strict';
var listOptions = "CN:Canada; US:United States; FR:France; IN:India";
var mydata = [{
name: "Toronto",
country: "CN",
continent: "North America",
countrycode: "CN"
}, {
name: "New York City",
country: "US",
continent: "North America",
countrycode: "US"
}, {
name: "Silicon Valley",
country: "US",
continent: "North America",
countrycode: "US"
}, {
name: "Paris",
country: "FR",
continent: "Europe",
countrycode: "FR"
}, {
name: "Pune",
country: "IN",
continent: "Asia",
countrycode: "IN"
}]
$("#gvManageMapping").jqGrid({
data: mydata,
datatype: "local",
colNames: ["Name", "Country", "Continent", "countrycode"],
colModel: [{
name: 'name',
index: 'name',
editable: false,
},
{
name: 'country',
index: 'country',
editable: true, edittype: "select", formatter: 'select', editoptions: {
value: listOptions,
}, editrules: { required: true, integer: false }, formatter: "select"
},
{
name: 'continent',
index: 'continent',
editable: false,
},
{
name: 'countrycode',
index: 'countrycode',
editable: false
}],
afterSaveCell: function (rowid, cellname, value) {
var selectedCountryCode, $this;
if (cellname === 'country') {
$this = $(this);
selectedCountryCode = $this.jqGrid("getCell", rowid, 'country');
$this.jqGrid("setCell", rowid, 'countrycode', selectedCountryCode);
}
},
pager: '#pager',
'cellEdit': true,
'cellsubmit': 'clientArray',
editurl: 'clientArray'
});
});
//]]>
</script>
</head>
<body>
<table id="gvManageMapping"><tr><td /></tr></table>
<div id="pager"></div>
</body>
</html>
The documentation for getRowData states:
Do not use this method when you editing the row or cell. This will return the cell content and not the actuall value of the input element
Is the row still being edited when you call getRowData()?
Update
Agreed, jqGrid does not handle <select> very well. In my application I actually was able to get around this by not specifying an edit option (meaning, key/value were both "FedEx"); the translation to ID is then done on the server. This is not the right way to code this, but it worked well enough for my needs at the time.