JQGRID - Prevent adding empty row after execution of afterSubmit - jqgrid

I have a grid where I put a custom button in the navgrid for inserting totally different data in another table so I used editGridRow("new",…) where in the php url I just post data to a different table. Actually I am stuck with the issue if I submit the form, even if I settled reloadAfterSubmit:false, it add a new empty row in the grid…
You can see the piece of code here:
jQuery("#"+child_table_id).navButtonAdd("#"+pager_id,
{
caption:"Insert",buttonicon:"ui-icon-arrow-1-se",
onClickButton:function(){
var rows = jQuery("#"+child_table_id).getRowData();
if ( rows.length != 0 ) {
jQuery("#"+child_table_id).editGridRow("new",{height:140,width:420,url:"http://.../edit_datatable.php?table_name=mytable&fact=insert&q=1&flag=yes&ref_id="+id_row,
reloadAfterSubmit:false,
recreateForm:true,
closeOnEscape:true,
closeAfterAdd:true,
addCaption:'Insert',
savekey: [true,13],
bSubmit:'Save',
afterSubmit:function(response, postdata){ alert('inserting to a total different table...'); return {0:true} }
});
}
},
position:"last",
title:"Insert new step...",
cursor:"pointer"
});
I tried even to add:
onClickButton:function(){ $("#"+child_table_id).setGridParam({ datatype: 'local' }); }
afterSubmit:function(response, postdata){ return {0:true} },
onclickSubmit : function(params, posdata) {return {0:true} },
afterComplete:function(response, postdata, formid) { $("#"+child_table_id).setGridParam({ datatype: 'json' }); }
but it added anyway a row in the grid…
So how I can prevent jqGrid to add a new empty grid and refreshing the grid?…

You wrote about "inserting totally different data in another table", but you add button to the navigator bar of the grid "#"+child_table_id and your code inside of onClickButton callback adds new row to the same grid:
jQuery("#"+child_table_id).navButtonAdd("#"+pager_id, { ...
onClickButton:function(){
...
jQuery("#"+child_table_id).editGridRow("new", ...
}
});
If you really want to add new row to another grid you should use id of another in the editGridRow (like jQuery("#"+another_table_id).editGridRow("new",...).

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

jqGrid: add loadonce as parameter to the AJAX-request

I have a PHP-script to handle the AJAX-Requests of many different jqGrid's.
I generate the "ORDER BY" statement with the 'sidx' and 'sord' parameters and the "LIMIT" statement with the 'page' and 'rows' parameters.
Similar to the PHP-example here.
The problem is, that in the PHP-script I can not determine if the loadonce-parameter of the current jqGrid is set or not.
But only if it is not set, I have to filter the returned data (LIMIT by page and rows).
How can I force jqGrid to send an additional parameter?
I dont want to change all my Grids. Is there a global way of doing it?
------ EDIT ------
With the help from this answers (here and here) i got this now.
$.extend($.jgrid.defaults, {
postData: {
loadingType: function() {
var isLoadonce = $("#list1").jqGrid('getGridParam', 'loadonce');
console.log('isLoadonce: ' + isLoadonce);
return isLoadonce ? 'loadAll' : 'loadChunk';
},
},
});
This works, if the Grid has the ID "list1". How can I reference the current Grid without ID?
------ EDIT 2 ------
This seems to work. It looks to me a bit like a hack. Is there a better way?
$.extend($.jgrid.defaults, {
serializeGridData: function(postData) {
var isLoadonce = $(this).jqGrid('getGridParam', 'loadonce');
var newPostData = $.extend(postData, {
loadingType: isLoadonce ? 'loadAll' : 'loadChunk'
});
return $.param(newPostData);
},
});
To pass in an extra parameter you can add:
postData: { ExtraDataName: ExtraDataValue },
then whenever jqGrid goes to get data it will pass that name pair to your controller.
With serializeGridData, jqGrid provides an event to modify the data sent with the Request. The event is called in the context of the current Grid, so we can access the current Grid with this.
By exdending $.jgrid.defaults we can make all Grids sending their loadonce parameter as additional requestparameter without changing any Grid.
$.extend($.jgrid.defaults, {
serializeGridData: function(postData) {
var isLoadonce = $(this).jqGrid('getGridParam', 'loadonce');
var newPostData = $.extend(postData, {
loadingType: isLoadonce ? 'loadAll' : 'loadChunk'
});
return $.param(newPostData);
},
});

dilemna with jqgrid and ajaxfileupload

I am using jqgrid and ajaxFileUpload.js script in order to pass parameters and files to a php script. The structure of the code is like this:
...
url:url_1.php,
beforeSubmit: function (postdata,formid)
{
$.ajaxFileUpload (
{
url: url_2.php,
...
success:
error:
}),
return[true,""];
},
afterSubmit: function(reponse,postdata)
{
...
return [true,'',''];
}
I have a dilemna:
According to the jqgrid behaviour, url_2.php is called, then url_1.php.
url_2.php handles the data (parameters + file), url_1.php handles nothing.
url_2.php could return an error or message (e.g "already exist") but, the errors are displayed in the form by the aftersubmit event, and this event receives error from url_1.php !!!
I suppose that I am obliged to put the ajaxfileupload in the beforesubmit event !!!
Any ideas to solve this dilemna ?
You can use jquery form plugin and jqGrid dataProxy method instead.
useDataProxy: true,
dataProxy : function (opts, act) {
opts.iframe = true;
var $form = $('#FrmGrid_' + $grid.jqGrid('getGridParam', 'id'));
//Prevent non-file inputs double serialization
var ele = $form.find('INPUT,TEXTAREA,SELECT').not(':file');
ele.each(function () {
$(this).data('name', $(this).attr('name'));
$(this).removeAttr('name');
});
//Send only previously generated data + files
$form.ajaxSubmit(opts);
//Set names back after form being submitted
setTimeout(function () {
ele.each(function () {
$(this).attr('name', $(this).data('name'));
});
}, 200);
};
For example http://jqgrid-php.net file fileUpload class uses this. This is described in How to force dataProxy call in form editing if editurl is set in jqgrid also.

Resources