Kendo grid data source update approach not working - kendo-ui

I have JSON data flowing via Pusher to a simple MVC5 website housing a Kendo Grid. The data, upon arrival, renders successfully in the grid however I'm creating and setting the data source every time. As this seems sinful, I'm trying to determine why my approach to simply updating the data source doesn't render the data.
The grid:
<div id="dashboard"></div>
<script>
$(document).ready(function () {
$("#dashboard").kendoGrid({
columns: [
{ field: "SystemName", width: "50px", title: "System" },
{ field: "Description", width: "100px", title: "Description" },
{ field: "SystemStatus", width: "30px", title: "Status" }
],
height: 600,
scrollable: true,
sortable: true,
});
var dataSource = new kendo.data.DataSource();
var grid = jQuery("#dashboard").data("kendoGrid");
grid.setDataSource(dataSource);
})
</script>
My failed attempt to read in the data without creating and binding a new data source (body of a function call which does happen):
var array = JSON.parse(data.updateGrid);
var grid = jQuery("#dashboard").data("kendoGrid");
grid.dataSource.data = array;
grid.dataSource.read(array);
grid.refresh();
I have confirmed that the data arrives from Pusher correctly yet the above approach does not update the grid.
Thanks in advance for any consideration.
jbt

Use the data() method on the dataSource to set it's data.
var array = JSON.parse(data.updateGrid);
var grid = jQuery("#dashboard").data("kendoGrid");
grid.dataSource.data(array);
You can only set the string value of data on the dataSource if the source is of XML type. Since you are using JSON, you need to call the data function and pass in the new data.
See documentation... http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#methods-data

Related

Export to PDF increase number of items per page

I have a grid control which I wish to export the content of. Upon initialisation, the pageSize attribute is set to 10 items however I want to increase the number of items per page during exportToPDF.
I have tried to modify the pageSize of the dataSource prior to carrying out the export but this seems to have no effect on the end product.
var grid = $("#grid").data("kendoGrid");
var filter = grid.dataSource.filter;
grid.dataSource.query({
filter: filter,
pageSize: 20, // has no effect on the exported PDF
page: 1,
group: [{
field: "groupField1",
dir: "asc"
}, {
field: "groupField2",
dir: "asc"
}, {
field: "groupField3",
dir: "asc"
}]
});
var progress = $.Deferred();
grid._drawPDF(progress)
.then(function (root) {
return kendo.drawing.exportPDF(root, { forcePageBreak: ".page-break", multiPage: true });
})
.done(function (dataURI) {
// ... do some manual manipulation of dataURI
kendo.saveAs({
dataURI: manipualtedDataURI
});
progress.resolve();
Is there something I am missing so I can display more items on each page of the PDF export?
EDIT
Including my grid definition with the pdfExport function suggested by the below answer (which never gets called):
var grid = $("#reportGrid").kendoGrid({
pdf: {
allPages: true,
avoidLinks: true,
repeatHeaders: true,
template: kendo.template($("#page-template").html()),
scale: 0.7,
margin: { top: "2.5cm", right: "1cm", bottom: "1.5cm", left: "1cm" },
paperSize: "A4",
landscape: true
},
// *this function is not getting called*
pdfExport: function(e) {
e.sender.dataSource.pageSize(10);
e.promise.done(function() {
e.sender.dataSource.pageSize(20);
});
},
toolbar: kendo.template($("#template").html()),
...
});
Note: A template is used to include a header / footer on each page of the PDF export.
Another note: 'Manual manipulation of dataURI' includes going out to the server to perform a merge with another PDF file, so I cannot use the default export via the grid :(
EDIT 2
I have extended the Dojo example from #R.K.Saini's answer to use the method by which I need to generate the PDF export (as per original post).
The snippet logs the URI of the grid being exported and when the pdfExport function is called. As you will see, when using the built in grid 'Export to PDF' button, the pdfExport function is triggered but when using the additional button below the grid, it is not.
You can use pdfExport event to change page size of your grid datasource before pdf export started and then when the export finish you just need to revert back the previous page size.
The call back function of this event receive grid instance as e.sender and and a promise as e.promise which can be used to set back the page size when exporting finish.
For more info check http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#events-pdfExport
$("#grid").kendoGrid({
dataSource: dataSource,
pdf: {
allPages: true
},
pdfExport: function(e) {
e.sender.dataSource.pageSize(10);
e.promise.done(function() {
e.sender.dataSource.pageSize(20);
});
},
...
//Other configguration
});
Here is a working demo http://dojo.telerik.com/UzOXO
Edit
You can also change grid page size in your custom export function just change grid page size before calling _drawPdf() function and change it back when done.
$("#btnPdfExport").kendoButton({
click: function () {
var grid = $("#grid").data("kendoGrid");
var progress = $.Deferred();
// Change grid datasource pagesize before calling _drawPDF
grid.dataSource.pageSize(20);
grid._drawPDF(progress)
.then(function (root) {
return kendo.drawing.exportPDF(root, { forcePageBreak: ".page-break", multiPage: true });
})
.done(function (dataURI) {
console.log("Exporting " + dataURI);
kendo.saveAs({
dataURI: dataURI,
fileName: "export.pdf"
});
progress.resolve();
// Change grid datasource pagesize when done
grid.dataSource.pageSize(10);
});
}
});
Check Update DOJO here http://dojo.telerik.com/UzOXO/8

How to get a client side editor when working with MVC version of Kendo UI Grid?

Well, I'm really stuck here. This example by Telerik shows how to change a field when editing to whatever you need. Exactly,
columns: [
{ field: "Category", title: "Category", width: "180px", editor: categoryDropDownEditor, template: "#=Category.CategoryName#" },
],
...where "categoryDropDownEditor" is a client side function that does the trick.
In MVC version there seems to be nothing of the kind. Is there? I keep believing that it should. I just do not need to traverse partial HTML from server each time I need to decorate an input field. And this is seemingly what "EditorTemplate", the only one available for MVC, does.
OK. In case anyone will bump into the same. I ended up with this "too elegant" a solution:
.Events(e => e.Edit("editing"))
this line in grid initialization routine (server side) calls the named dynamic method (client side):
function editing(e) {
var input = e.container.find("input[name=Regex]");
var textbox = $(document.createElement('textarea')).attr({
id: input.id,
}).width(input.width()).height(input.height()).val(input.val());
input.hide();
textbox.insertAfter(input);
textbox.focus(function () {
/*to make this flexible, I'm storing the current width & height in an attribute*/
$(this).attr('data-defaultwidth', $(this).width());
$(this).attr('data-defaultheight', $(this).height());
$(this).animate({
width: 400
}, 'slow');
$(this).animate({
height: 300
}, 'slow');
}).blur(function () {
/* lookup the original width */
var w = $(this).attr('data-defaultwidth');
var h = $(this).attr('data-defaultheight');
$(this).animate({
width: w
}, 'slow');
$(this).animate({
height: h
}, 'slow');
input.val(textbox.val());
input.trigger('change');
});
}
End tada, although it's a pure hack.

Kendo grid change indicator and cancel not working

I'm new to Kendo and the Kendo grid but I'm trying to learn how to use the master detail Kendo grid where the detail grid is supposed to support batch editing. The data is available in a local JavaScript object.
This jsFiddle demonstrates the problems I'm seeing.
Here's how the grid is being created - see the jsFiddle for the complete snippet -
$("#grid").kendoGrid({
dataSource: items,
detailInit: createDetail,
columns: [
{ field: "Item", width: "200px" },
]
});
function createDetail(e) {
$("<div/>")
.appendTo(e.detailCell)
.kendoGrid({
dataSource: {
batch:true,
transport: {
read: function (options) {
options.success(e.data.SubItems);
}
}
},
editable:true,
pageable:true,
toolbar: ["save", "cancel"],
columns: [
{ field: "SubItem", title: "Sub Item", width: 200 },
{ field: "Heading1", title: "Heading 1", width: 100 }
]
});
}
When you edit an item in the grid and click to the next cell, the details grid automatically collapses not matter where I click, even in an adjacent cell. When I open it again, I don't see the change indicator in the cell (red notch) but the new value is there.
If I were to hook up the save to an ajax call, Kendo sends the right detail item(s) that were edited.
Nothing happens when I click cancel changes.
How do I get the grid to not collapse and see the change indicators ?
How do I get canceling of changes to work correctly ?
[Update] - Further investigation reveals that if I use an older Kendo version 2011.3.1129 , this works as expected. But if I use the newer 2012.3.1114, it doesn't. Dont know if this is a bug or a change in behavior.
After much effort, I found that the cause seems to be that the master grid is rebinding automatically causing the behavior I observed. I was able to get around this by handling the dataBinding event in the master grid and within that, checking if any of the detail datasources were dirty and if so, calling preventDefault.
Here are relevant code snippets :
dataBinding: function (e) {
if (masterGrid.AreChangesPending()) {
e.preventDefault();
}
}
AreChangesPending : function () {
var pendingChanges = false;
// I gave each detail div an id so that I can get a "handle" to it
$('div[id^="detail_"]').each(function (index) {
var dsrc = $(this).data("kendoGrid").dataSource;
$.each(dsrc._data, function () {
if (this.dirty == true || this.isNew()) {
pendingChanges = true;
}
});
// For some reason, Kendo did not detect new rows in the isNew()
// call above, hence the check below
if (dsrc._data.length != dsrc._total) {
pendingChanges = true;
}
});
return pendingChanges;
}

Create highcharts chart using AJAX/JSON

I am building a website that uses the Highcharts library to display a single line series chart. I am using AJAX to retrieve historical financial data from yahoo finance using their YQL.
The ajax call is working correctly and I can view the returned data in the console for example
console.log( data.query.results.quote[0].Close );
returns the closing price value 457.84
How do I now build the single line series chart using this data?
I cannot find a simple explanation anywhere of how to create the chart using AJAX data.
Thanks
edit: I am fetching the data in AJAX and it works correctly but trying to make the chart work with JSON is where im having difficulties.
This is what my code currently looks like: http://jsfiddle.net/JbGvx/
This is the demo code off the HighStocks website: http://jsfiddle.net/xDhkz/
I think the problem is with the date formatting of the AJAX request. The date is being returned like so 2013-02-25 but the chart wants JS timestamps. Is there a way that I can extract the date from the AJAX, convert it using Date.UTC and then make the chart using the converted data?
If you are considering stock data, consider using HighStocks instead of HighCharts. It can handle many data points much faster than HighCharts is able to.
HighStocks has an example where they pull in AJAX data (1.6 million points) asynchronously here: http://www.highcharts.com/stock/demo/lazy-loading
var chartSeriesData = [];
var chartCategory = [];
$.each(response, function() {
if(this.name!="TOTAL" && this.no!="0")
{
var series_name = this.name;
var series_data = this.no;
var series = [
series_name,
parseFloat(series_data)
];
chartSeriesData.push(series);
}
});
//initialize options for highchart
var options = {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false
},
title: {
text: 'SalesOrder '
},
tooltip: {
pointFormat: '{series.name}: <b>{point.y}</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
center:['60%','60%'],
size:150
,
dataLabels: {
enabled: true,
color: '#000000',
distance: 40,
connectorColor: '#000000',
format: '<b>{point.name}</b>: {point.y} '
}
}
},
series: [{
type: 'pie',
name: 'Browser share',
data:chartSeriesData //load array created from json
}]
}
//options.series[0].setData(datavaluejson);
var chart= $('#container').highcharts(options);

jqGrid - edit data

I am quite new to jquery and jqgrid. I use ASP.NET WebForms. I am able to get some data prom server and show it in grid. I use PageMethods to get data from server. Usually my code is
function CreateGrid(){
$("#sestGrid").jqGrid({
datatype: GetData,
//toolbar: [true, "top"],
colNames: ['Name', 'Age'],
colModel: [
{ name: 'Name', index: 'Name', width: 170, align: 'left',
sortable: false, key: true },
{ name: 'Age', index: 'Age', width: 40, align: 'center',
sortable: false, editable: true },
],
ondblClickRow: function () {
var row_id = $("#sestGrid").getGridParam('selrow');
$('#sestGrid').editRow(row_id, true);
}
});
}
function GetData() {
PageMethods.GetSestevalniStevecData(GotData);
}
function GotData (data) {
$("#sestGrid").clearGridData(false);
for (var j = 0; j <= data.length; j++)
$("#sestGrid").jqGrid('addRowData', j + 1, data[j]);
}
So, now I would like to edit some data and post it to server. How can I do that using PageMethods? Should I use any other approach?
And one more thing. I checked the demos http://trirand.com/blog/jqgrid/jqgrid.html and in all edit examples you are able to edit only one row and then you have to save changes… Is it possible to edit more than one row and save all changes in one step?
Thanks all.
jqGrid is designed to be used together with ajax services. So if the user change the data of some row then the changes will be send to the server: to the URL which you configure through jqGrid parameter editurl. So the easiest way to implement row editing will be to include an ASMX web-service or a WCF service in you web site. It is not important whether you use ASP.NET WebForms, ASP.NET MVC or just pure HTML for your pages. So just choose the technology which you prefer and add the corresponding page to your site.
The ASMX or WCF should has a method with the signature like
public string MyDataEdit (string Age, string oper, string id)
(see this old answer for more information). The method should return the id of the new added item (the Name in your case) in case of Add operation.
One more small remark. You can change the definition of the ondblClickRow function from function() to function(row_id) and remove the line used getGridParam('selrow').
I used your example and changed it a bit:
ondblClickRow: function (rowid) {
if (rowid && rowid != lastsel) {
changedRows.push(rowid); //keep row id
jQuery('#jqgrid').editRow(rowid, true);
}
}
Under the save button click event:
$.each(changedRows, function () {
var row = $("#jqgrid").getRowData(this);
var Id = row['ID'];
var price = $(row['Price']).val(); //this is an input type
});
HTH someone :)

Resources