Export to PDF increase number of items per page - kendo-ui

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

Related

Kendo DropDownList Search on template modified text

I am unable to get the built-in search for Kendo DropDownList to use the templated text instead of the raw text from the dataSource. I want to strip off the leading slash from the dataSource name for display, value, and search purposes.
<script>
$("#dropdownlist").kendoDropDownList({
dataSource: [ "/Apples", "/Oranges" ],
// None of these templates appear to fix the search text.
// Kendo is using the dataSource item to search instead of the template output.
// I want to be able to search using 'a' (for Apples) or 'o' (for Oranges).
// If I use '/' then it cycles through the items which proves to me that the search is not using templated text.
template: function(t) { return t.name.slice(1); },
valueTemplate: function(t) { return t.name.slice(1); },
optionLabelTemplate : function (t) { return t.name.slice(1); },
});
</script>
Here is a non-working sample in Kendo's UI tester:
http://dojo.telerik.com/#Jeremy/UvOFo
I cannot easily alter the dataSource on the server side.
If it's not possible to change how the search works then maybe there is a way to alter the dataSource after it's been loaded into the client from the server?
I'm not sure if this will help you at all, but I was able to force it to work. The control allows for you to subscribe to the filtering event on init. From here, you can set the value of the filter before it is submitted.
<script>
$("#dropdownlist").kendoDropDownList({
dataSource: ["/Apples", "/Oranges"],
template: function(t) { return t.slice(1); },
valueTemplate: function(t) { return t.slice(1); },
optionLabelTemplate : function (t) { return t.slice(0); },
filter: "startswith",
filtering: function(e) {
e.filter.value = '/'+e.filter.value;
}
});
</script>

CKEditor widget receives data after it has been rendered

Looking at the docs you can pass startup data to a widget:
editor.execCommand( 'simplebox', {
startupData: {
align: 'left'
}
} );
However this data is pointless as there seems to be no way to affect the template output - it has already been generated before the widget's init, and also the data isn't even available at that point:
editor.widgets.add('uselesswidget', {
init: function() {
// `this.data` is empty..
// `this.dataReady` is false..
// Modifying `this.template` here does nothing..
// this.template = new CKEDITOR.template('<div>new content</div>');
// Just after init setData is called..
this.on('data', function(e) {
// `e.data` has the data but it's too late to affect the tpl..
});
},
template: '<div>there seems to be no good way of creating the widget based on the data..</div>'
});
Also adding a CKEditor tag throws a "Uncaught TypeError: Cannot read property 'align' of undefined" exception so it seems the data is also not passed to the original template:
template: '<div>Align: {align}</div>'
What is the point of having a CKEDITOR.template.output function which can accept a context, if there's no way of dynamically passing data?
The only horribly hacky solution I've found so far is to intercept the command in a beforeCommandExec and block it, then modify the template and manually execute the command again..
Any ideas to generate dynamic templates based on passed data? Thanks.
Here's how I did it.
Widget definition:
template:
'<div class="myEditable"></div>',
init: function () {
// Wait until widget fires data event
this.on('data', function(e) {
if (this.data.content) {
// Clear previous values and set initial content
this.element.setHtml('')
var newElement = CKEDITOR.dom.element.createFromHtml( this.data.content );
this.element.append(newElement,true);
this.element.setAttribute('id', this.data.id);
}
// Create nestedEditable
this.initEditable('myEditable', {
selector: '.myEditable',
allowedContent: this.data.allowedContent
})
});
}
Dynamic widget creation:
editor.execCommand('myEditable', {startupData: {
id: "1",
content: "some <em>text</em>",
allowedContent: {
'em ul li': true,
}
}});

Kendo grid data source update approach not working

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

how to select all records in the grid in order to export the data

I am trying to select all the data present in the jqgrid table in order to export in to an excel file. But the data present in the first page of the grid is only getting exported. i.e., if a total of 25 records are present in the grid and 5 records are present in the first page, then only first 5 records are getting exported.
The following code is responsible for displaying records 'only' in the first page of the grid..
var gridData = $("#list").jqGrid('getRowData');
The following code is responsible for displaying records present in all the pages in the grid..
var gridData1 =jQuery("#list").jqGrid('getGridParam','data');
how to use the above code such that I can select all the records present in the grid. also, I am trying to apply filter on the records present in the grid. In such a case, how to get the filtered number of records in order to export them..?
Thanks,
You can do it server side.
<script type="text/javascript">
$(document).ready(function () {
$('#list').jqGrid({
caption: "test",
// ...
}).navGrid(
// ...
}).jqGrid('navButtonAdd', '#pager', {
caption: "", buttonicon: "ui-icon-print", title: "export",
onClickButton: function () {
$("#list").jqGrid('excelExport', { url: 'path......' });
}
});
});
</script>
excelExport method, sends the current page number, sort field, filtering, etc to the specified url. now you have time to process these parameters and create a new output.
You may want to try below script and function:
<script type='text/javascript'>
var tableToExcel = (function () {
var uri = 'data:application/vnd.ms-excel;base64,'
, template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>'
, base64 = function (s) { return window.btoa(unescape(encodeURIComponent(s))) }
, format = function (s, c) { return s.replace(/{(\w+)}/g, function (m, p) { return c[p]; }) }
return function (table, name) {
if (!table.nodeType) table = document.getElementById(table)
var ctx = { worksheet: name || 'Worksheet', table: table.outerHTML }
window.location.href = uri + base64(format(template, ctx))
}
})();
$(document).ready(function () {
...declare & setup the jqGrid with 'big row page', e.g. ...
rowNum: 9999,
rowList: [50, 100, 200, 9999],
.........then add below navigation button after setup the grid...
$("#list").jqGrid('navButtonAdd', pgrid1, {caption:"Download",title:"Download report contents", buttonicon :'ui-icon-circle-arrow-s',
onClickButton:function(){
tableToExcel('list', 'export data')
}
});
}
</script>
Alternatively, another way to exporting can refer to related question:
How to enable jQgrid to Export data into PDF/Excel

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;
}

Resources