PDA

View Full Version : ExtJS 4: Grid Printer Plugin



loiane
7 Sep 2011, 5:36 AM
Hi,

I ported GridPrinter plugin to ExtJS 4.
This plugin was originally written by Ed Spencer.

Code: https://github.com/loiane/extjs4-ux-gridprinter
Demo: http://loianegroner.com/extjs/examples/extjs4-ux-gridprinter/
Blog post: http://loianegroner.com/2011/09/extjs-4-grid-printer-plugin

crysfel
7 Sep 2011, 9:11 AM
This is great, I was planing on porting this plugin to ext4 but you did it!

Thanks for share.

zacware
8 Sep 2011, 8:28 PM
Thank you! Really missed having this.

foxmarco
9 Sep 2011, 9:06 AM
but in case of paging?

loiane
23 Sep 2011, 3:56 AM
but in case of paging?

The plugin will only print what the grid is displaying at the time.
To print all the records, you have to change the plugin and load all the records into the store, or you can create a server side solution.

hschaefer123
29 Sep 2011, 12:41 AM
Hi Loiane,
thanks for the migration.

I like to see that the code quality of migrated extensions is getting better and better and Ext 4 has the possibility to produce same quality with less code ;-)

Currently Grid Printer does not support TemplateColumns -> XTemplate Exception.

I added support this way


Ext.each(columns, function(column) {
if (column.dataIndex == key) {
// template column support
if (column instanceof Ext.grid.column.Template) {
convertedData[key] = column.tpl.apply(item.data);
} else {
convertedData[key] = column.renderer ? column.renderer(value) : value;
}
}
}, this);

Cheers Holger

loiane
10 Oct 2011, 2:47 PM
Thanks!

I will update the plugin code with these new fixes!

parkcity
11 Oct 2011, 1:41 AM
I am using chrome and the code doesn't print automatically. In chrome I get the notification.."Print Preview failed". The code works fine when printAutomatically is set to false.

mfruizs2
14 Oct 2011, 12:20 AM
First: Thx 4 ur great support, mates!

Second: For @parkcity, to delete this error, u need to erase or commented the windows internal command to close the windows, then, it will run nice again :)

Now, my question :) I need to print all the grid, but not all the grid print on the current screen, else all data store. Then, how could I return all the storage on a "grid.panel" that is the parameter i need to ?

thx 4 ur time!

cya!

PS: sorry if i didnt explaned very well :(

hschaefer123
14 Oct 2011, 1:55 AM
A little addon to the htmlMarkup with table headers (THEAD) and table body (TBODY) tags will allow printing table head on each page (if printing large grids that are printed on different pages).

Concerning question printing large store, the grid prints the binded store. So make sure the store contains all data and you do not use filtering or paging (ex. paging plugin) or paging should be a very large value.

This solution should not be a genrall solution for printing very large data sets! In such a case you should generate print output on server side and maybe download it as PDF.

The plugin is thought as a quick and easy solution to print the visible grid part, including custom renderers, etc.

Currently all columns are printed, but it is also possible to filter hidden column, or prior print to hide some columns that contain html markup not needed to be printed in a later version.


var htmlMarkup = [
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
'<html>',
'<head>',
'<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />',
'<link href="' + this.stylesheetPath + '" rel="stylesheet" type="text/css" media="screen,print" />',
'<title>' + grid.title + '</title>',
'</head>',
'<body>',
'<table>',
'<thead>',
headings,
'</thead>',
'<tbody>',
'<tpl for=".">',
body,
'</tpl>',
'</tbody>',
'</table>',
'</body>',
'</html>'
];

mfruizs2
14 Oct 2011, 2:37 AM
Thx 4 the reply.

It's interesting ... How could i need to rewrite the code on the printer plugin to put the head on all the pages ? because with only adding <thead> and </thead> not do it.

thx again 4 ur help!

hschaefer123
23 Oct 2011, 11:35 PM
Hi mfruizs2,
i do not know if this works in all browsers as expected, but you are right.

You only need the addtional THEAD/TBODY markup to get this working in firefox.
This is standard html behavior.
I did not check this thing against all browsers because it is only additional markup (nice to have),

So if you browser did not cache the script and your table is printed on at least 2 pages
each page should have its own column description (headers) on top.

Cheers Holger

mfruizs2
25 Oct 2011, 6:54 AM
Ok thx 4 all. i'm thinking that i need to re-code the CSS to get it.

cya!

craigsimons
24 Nov 2011, 2:48 PM
Viewing source in Chrome will crash the browser. Firefox doesn't crash, but source is blank.

venkateshns
28 Nov 2011, 2:47 AM
HI All,
Can anybody tell me how to print a form panel ?

Regards,
Venkatesh

rjsquire
3 Jan 2012, 2:04 PM
Using the example from the distribution, I found that the css was not getting applied when printAutomatically is true. When it is false, the page never finishes loading. All the content is displayed, but the loading indicator of the browser is still moving.

To fix this, the stream opened to write to the document needs to be closed. One line is added to the plugin right after the data is written to the document.


win.document.write(html);
win.document.close(); // this line is new and closes the stream
if (this.printAutomatically){
win.print();
win.close();
}

Once that is in place, the printable view works perfectly whether or not printAutomatically is set.

amanp
23 Jan 2012, 12:59 AM
This plugin doesn't support for grid panels with grouped headers...

caballero
22 Feb 2012, 11:44 PM
god bless you hschaefer123


Your code snippet was a life saver.


Loraine, you mentioned that you would put his fix into the source. I highly recommend you do. I spent a good hour and a half trying to get this to work on multiple grids.


Great tool.


Thanks again.

masoud_tamizy
23 Feb 2012, 1:34 AM
very good plugin :)

user ext
24 Feb 2012, 8:22 AM
This plugin doesn't support for grid panels with grouped headers... This variant for grouped headers ( column group or nested headers) and grid grouping.
print: function (grid)
{

var columns = grid.headerCt.getVisibleGridColumns(false);
//drop first empty column (when grid groupped)
if (columns[0].dataIndex == null && columns[0].items.length == 0) columns.shift();
//build a useable array of store data for the XTemplate
var data = [];
grid.store.data.each(function (item)
{
var convertedData = [];
//apply renderers from column model
for (var key in item.data)
{
var value = item.data[key];
Ext.each(columns, function (column)
{
if (column.dataIndex == key)
{
var colIndex = column.getIndex();
convertedData[key] = column.renderer ? column.renderer.call(grid, value, null, item, null, colIndex) : value;
}
}, this);
}
data.push(convertedData);
});

//create nested headers as html (not used headerTpl)
var nr = 0, rows = [[]];
var fn = function (item, index, all)
{
if (item.dataIndex == null)
{
var cols = item.items.items;
if (cols.length > 0 && !item.hidden)
{
rows[nr].push('<th colspan="' + cols.length + '"><div align="center">' + item.text + '</div></th>');
nr++; if (nr == rows.length){ rows[nr] = []; }
Ext.each(cols, fn);
nr--;
}
}
else
{
if (!item.hidden) rows[nr].push('<th{0}>' + item.text + '</th>');
}
}
Ext.each(grid.columns, fn);
Ext.each(rows, function (item, index, all)
{
item.unshift('<tr>'); item.push('</tr>');
all[index] = Ext.String.format(item.join(''), ' rowspan="' + (all.length - index) + '"');
});
var headings = rows.join('');
var body = Ext.create('Ext.XTemplate', this.bodyTpl).apply(columns);

var htmlMarkup =
[
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
'<html>',
'<head>',
'<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />',
'<link href="' + this.stylesheetPath + '" rel="stylesheet" type="text/css" media="screen,print" />',
'<title>' + 'table: ' + grid.store.storeId + '</title>',
'</head>',
'<body>',
'<table>',
headings,
'<tpl for=".">',
body,
'</tpl>',
'</table>',
'</body>',
'</html>'
];

var html = Ext.create('Ext.XTemplate', htmlMarkup).apply(data);

//open up a new printing window, write to it, print it and close
var win = window.open('', 'printgrid');
win.document.write(html);
win.document.close();

if (this.printAutomatically)
{
win.print();
win.close();
}
},

vicvolk
29 Mar 2012, 9:15 AM
"This variant for grouped headers ( column group or nested headers) and grid grouping".

Unfortunately, it does not work with three and more level headers.

philance
1 Apr 2012, 2:54 PM
First of all, thanks a lot for great plugin.

Btw, I implement grid with remote store and paging. At any time, there are only pageSize records, and hence when print, it only print those pageSize records. How can I modify your plugin to make it print the whole remote store.

Thanks a lot in advance.

navvn
8 May 2012, 12:28 AM
Any solution to make a xtype rownumberer working? Right now it outputs only {}

talha06
17 May 2012, 10:18 PM
Hi everyone,
Thanks a lot Loiane and Ed for this great extension. =D> I'm getting the error that I added below while using this with ExtJS 4.1, I'll be happy if someone can help me.
Thanks in advance.
With regards,
T


missing ) in parenthetical
if ((v=fm.0(values['margin']))!==undefined) out.push(v+'')

austin1030
20 May 2012, 8:08 AM
I get this error

Uncaught SyntaxError: Unexpected number

Any idea?

predator
23 May 2012, 6:27 PM
Hi everyone,
Thanks a lot Loiane and Ed for this great extension. =D> I'm getting the error that I added below while using this with ExtJS 4.1, I'll be happy if someone can help me.
Thanks in advance.
With regards,
T


missing ) in parenthetical
if ((v=fm.0(values['margin']))!==undefined) out.push(v+'')

I think i have the same error.

missing ) in parenthetical
http://project2.dev/libs/ext4/ext-all.js
Line 22

byu_risk3
14 Jun 2012, 1:37 PM
This plug in doesn't seem to work with action columns. In Printer.js, some of the algorithms under the print() function that deal with the columns throw an error when it gets to the action column I think.

talha06
15 Jun 2012, 5:51 AM
This plug in doesn't seem to work with action columns. In Printer.js, some of the algorithms under the print() function that deal with the columns throw an error when it gets to the action column I think.
I tried that before, it still gives error..

byu_risk3
15 Jun 2012, 9:31 AM
I tried that before, it still gives error..

I'm not sure what you are referring to when you say you 'tried that before'...

I was able to get the printer plugin to work with action columns by hacking the code a little bit. I also changed the code so that the grid will only display the columns visible to the user.

Here is my modification for Printer.js



print: function(grid) {
//We generate an XTemplate here by using 2 intermediary XTemplates - one to create the header,
//the other to create the body (see the escaped {} below)
var columns = [];

//account for grouped columns
Ext.each( grid.view.headerCt.getVisibleGridColumns() , function(c) { // byu_risk3 modification - only print visible columns that user sees
// Ext.each( grid.columns , function(c) { // Original code
if( c.xtype != "actioncolumn" ){ // byu_risk3 modification - prevent action columns from being included with other columns
if(c.items.length > 0) {
columns = columns.concat(c.items.items);
} else {
columns.push(c);
}
}
});
// ...etc


Hope this helps someone who gets errors with action columns. :)

talha06
15 Jun 2012, 10:58 AM
@byu_risk3
I mean even if I don't have an 'actioncolumn', it stils gives same error '
Uncaught SyntaxError: Unexpected number'.

flex62ryz
18 Jul 2012, 4:36 AM
For browsers based on WebKit engine when print window opened the title of window has value "Untitled". Fix it for safari you can swap this code:

var win=window.open('','printgrid');
on this:

var win=window.open('about:blank','printgrid');

For Chrome this solution fixes problem not fully

flex62ryz
18 Jul 2012, 5:31 AM
In column values of print grid instead of empty values displays string with "null" text. I fix it by replace code:
line 108

var body =Ext.create('Ext.XTemplate',this.bodyTpl).apply(columns);
on this

var body = Ext.htmlDecode(Ext.create('Ext.XTemplate',this.bodyTpl).apply(columns));

and replace this:
line 248

'<td>\{{dataIndex}\}</td>'
on this

'<td>&lt;tpl if="{dataIndex}"&gt;\{{dataIndex}\}&lt;/tpl&gt;</td>'

hschaefer123
30 Jul 2012, 1:15 AM
I am currently migrating my Ext 3.x portal solution to Ext 4.1.x.

Based on Loaines work and my former addons i figured out some issues and fixed them for my needs!

1) wrong use of renderer
i replaced "column.renderer.call" by
column.renderer(value, meta, item, row, col, grid.store, grid.view)
If you still will use column.renderer.call, first param (scope) needs to be column instead of this.

The issue is on using locales different from english and the columns renderer needs corresponding scope. If not some column renderer (datecolumn) will not format dates overwriten in locale based files!

2) wrong asociation of convertedData
array was indexed by dataIndex, but this restriction allows only single use of dataIndex for columns, means you can't use dataindex inside templatecolumn, because value will be overwritten (for example tpl columns with icons, all column using the same dataindex will be shown icon value). Last column wins!
For this reason i index columns by column.id to allow multiple use of corresponding values.

3) adding support for column align (left|center|right)
Added basic formatting support. Currently only column alignment that is used by numbercolmns (align: right).

4) new feature print preview window
During migration i found out that i must not upgrade my iframe panel, because default ux iframe panel fullfills my needs. At this point i thought why not to use iframe panel for printing instead of open new window (it will be quite more comfortable) and so the new print preview window found his way into gridprinter (inspired by loaines print buttons).

37596

Here is the source!
I left the changes inside as comments to see what i have changed.
Also added requires for iframe panel.

Update: updated version and example can be found at
Source: https://github.com/hschaefer123/uops-ext
(https://github.com/hschaefer123/uops-ext)
Update2: online demo available
Demo: http://jsfiddle.net/hschaefer123/NHfsN/
(currently print stylesheet does not work on jsfiddle, but feature itself is ok!)



/**
* @class Ext.ux.grid.Printer
* @author Ed Spencer (edward@domine.co.uk)
* Helper class to easily print the contents of a grid. Will open a new window with a table where the first row
* contains the headings from your column model, and with a row for each item in your grid's store. When formatted
* with appropriate CSS it should look very similar to a default grid. If renderers are specified in your column
* model, they will be used in creating the table. Override headerTpl and bodyTpl to change how the markup is generated
*
* Usage:
*
* 1 - Add Ext.Require Before the Grid code
* Ext.require([
* 'Ext.ux.grid.GridPrinter',
* ]);
*
* 2 - Declare the Grid
* var grid = Ext.create('Ext.grid.Panel', {
* columns: //some column model,
* store : //some store
* });
*
* 3 - Print!
* Ext.ux.grid.Printer.mainTitle = 'Your Title here'; //optional
* Ext.ux.grid.Printer.print(grid);
*
* Original url: http://edspencer.net/2009/07/printing-grids-with-ext-js.html
*
* Modified by Loiane Groner (me@loiane.com) - September 2011 - Ported to Ext JS 4
* http://loianegroner.com (English)
* http://loiane.com (Portuguese)
*
* Modified by Paulo Goncalves - March 2012
*
* Modified by Beto Lima - March 2012
*
* Modified by Beto Lima - April 2012
*
* Modified by Paulo Goncalves - May 2012
*
* Modified by Nielsen Teixeira - 2012-05-02
*
* Modified by Joshua Bradley - 2012-06-01
*
* Modified by Holger Schäfer - 2012-07-30
*
* FORUM: http://www.sencha.com/forum/showthread.php?146348-ExtJS-4-Grid-Printer-Plugin
* GIT: https://github.com/loiane/extjs4-ux-gridprinter
*/
Ext.define("Ext.ux.grid.Printer", {
requires: [
'Ext.XTemplate',
'Ext.ux.IFrame'
],
statics: {
/**
* Prints the passed grid. Reflects on the grid's column model to build a table, and fills it using the store
* @param {Ext.grid.Panel} grid The grid to print
*/
print: function(grid, targetEl) {
if (!targetEl) targetEl = Ext.getBody();

//We generate an XTemplate here by using 2 intermediary XTemplates - one to create the header,
//the other to create the body (see the escaped {} below)
var columns = [];
//account for grouped columns
Ext.each(grid.columns, function(c) {
if (c.items.length > 0) {
columns = columns.concat(c.items.items);
} else {
columns.push(c);
}
});

//build a useable array of store data for the XTemplate
var data = [];
var emptyText = this.text;
grid.store.data.each(function(item, row) {
var convertedData = {};
//apply renderers from column model
for (var key in item.data) {
var value = item.data[key];

Ext.each(columns, function(column, col) {
if (column && column.dataIndex == key) {
/*
* TODO: add the meta to template
*/
var meta = {item: '', tdAttr: '', tdCls: '', style: ''};
value = column.renderer
//? column.renderer.call(column, value, meta, item, row, col, grid.store, grid.view)
? column.renderer(value, meta, item, row, col, grid.store, grid.view)
: value;

// add style info
// TODO: find out how to use metahandling via template (above handling via renderer does not work)
var align = column.align; // [left|center|right]
var style = '';
if (align != 'left') {
style += 'text-align:' + align + ';';
value = '<div style="' + style + '">' + value + '</div>';
}
convertedData[column.id] = (Ext.isEmpty(value))
? emptyText : value;
}
}, this);
}
data.push(convertedData);
});

//remove columns that do not contains dataIndex or dataIndex is empty. for example: columns filter or columns button
var clearColumns = [];
Ext.each(columns, function(column) {
if (column && !Ext.isEmpty(column.dataIndex) && !column.hidden) {
clearColumns.push(column);
}
});
columns = clearColumns;

//get Styles file relative location, if not supplied
if (this.stylesheetPath === null) {
var scriptPath = Ext.Loader.getPath('Ext.ux.grid.Printer'); // library/extjs/src/ux/grid/Printer.js
this.stylesheetPath = scriptPath.substring(0, scriptPath.indexOf('Printer.js')) + 'gridPrinterCss/print.css';
}

//use the headerTpl and bodyTpl markups to create the main XTemplate below
var headings = Ext.create('Ext.XTemplate', this.headerTpl).apply(columns);
var body = Ext.create('Ext.XTemplate', this.bodyTpl).apply(columns);
var pluginsBody = '',
pluginsBodyMarkup = [];

//add relevant plugins
Ext.each(grid.plugins, function(p) {
if (p.ptype == 'rowexpander') {
pluginsBody += p.rowBodyTpl.join('');
}
});

if (pluginsBody != '') {
pluginsBodyMarkup = [
'<tr class="{[xindex % 2 === 0 ? "even" : "odd"]}"><td colspan="' + columns.length + '">',
pluginsBody,
'</td></tr>',
];
}

//Here because inline styles using CSS, the browser did not show the correct formatting of the data the first time that loaded
var htmlMarkup = [
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
'<html class="' + Ext.baseCSSPrefix + 'ux-grid-printer">',
'<head>',
'<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />',
'<link href="' + this.stylesheetPath + '" rel="stylesheet" type="text/css" />',
'<title>' + grid.title + '</title>',
'</head>',
'<body class="' + Ext.baseCSSPrefix + 'ux-grid-printer-body">',
/*
'<div class="' + Ext.baseCSSPrefix + 'ux-grid-printer-noprint ' + Ext.baseCSSPrefix + 'ux-grid-printer-links">',
'<a class="' + Ext.baseCSSPrefix + 'ux-grid-printer-linkprint" href="javascript:void(0);" onclick="window.print();">' + this.printLinkText + '</a>',
'<a class="' + Ext.baseCSSPrefix + 'ux-grid-printer-linkclose" href="javascript:void(0);" onclick="window.close();">' + this.closeLinkText + '</a>',
'</div>',
*/
'<h1>' + this.mainTitle + '</h1>',
'<table>',
'<thead>',
'<tr>',
headings,
'</tr>',
'</thead>',
'<tbody>',
'<tpl for=".">',
'<tr class="{[xindex % 2 === 0 ? "even" : "odd"]}">',
body,
'</tr>',
pluginsBodyMarkup.join(''),
'</tpl>',
'</tbody>',
'</table>',
'</body>',
'</html>'
];
var html = Ext.create('Ext.XTemplate', htmlMarkup).apply(data);
// produce inline src content from html
// var src = 'data:text/html;charset=utf-8,' + escape(html);

var printWindow = Ext.createWidget('window', {
requireIcons: ['cross', 'printer'],
title: this.printPreviewText + ': ' + grid.title,
iconCls: 'icon-printer',
width: 640,
height: 480,
layout: 'fit',
animateTarget: targetEl,
resizable: false,
maximizable: true,
items: [{
xtype: 'uxiframe',
itemId: 'iframe'
}],
dockedItems: [
{
xtype: 'toolbar',
dock: 'bottom',
ui: 'footer',
layout: {
pack: 'end',
type: 'hbox'
},
items: [
{
xtype: 'button',
text: this.printLinkText,
iconCls: 'icon-printer',
handler: function(btn, e) {
iframe.getWin().print();
},
scope: this
},
{
xtype: 'button',
text: this.closeLinkText,
iconCls: 'icon-cross',
handler: function(btn, e) {
this.up('window').close();
}
}
]
}
]
});
var iframe = printWindow.down('#iframe');
printWindow.show(targetEl, function() {
var doc = iframe.getDoc();
doc.open();
doc.write(html);
doc.close();
}, this);

/*
//open up a new printing window, write to it, print it and close
var win = window.open('', 'printgrid');
// fix safari
//var win=window.open('about:blank','printgrid');

//document must be open and closed
win.document.open();
win.document.write(html);
win.document.close();
*/

//An attempt to correct the print command to the IE browser
if (this.printAutomatically){
if (Ext.isIE){
window.print();
} else {
win.print();
}
}

//Another way to set the closing of the main
if (this.closeAutomaticallyAfterPrint){
if(Ext.isIE){
window.close();
} else {
win.close();
}
}
},

/**
* @property stylesheetPath
* @type String
* The path at which the print stylesheet can be found (defaults to 'ux/grid/gridPrinterCss/print.css')
*/
stylesheetPath: null,

/**
* @property printAutomatically
* @type Boolean
* True to open the print dialog automatically and close the window after printing. False to simply open the print version
* of the grid (defaults to false)
*/
printAutomatically: false,

/**
* @property closeAutomaticallyAfterPrint
* @type Boolean
* True to close the window automatically after printing.
* (defaults to false)
*/
closeAutomaticallyAfterPrint: false,


/**
* @cfg {String} text
* The header text to be used as innerHTML (html tags are accepted) to display in the Grid.
* **Note**: to have a clickable header with no text displayed you can use the default of ` ` aka `&nbsp;`.
*/
text: ' ',

/**
* @property mainTitle
* @type String
* Title to be used on top of the table
* (defaults to empty)
*/
mainTitle: '',

/**
* Text show as window title
* @type String
*/
printPreviewText: 'Printpreview',

/**
* Text show on print link
* @type String
*/
printLinkText: 'Print',

/**
* Text show on close link
* @type String
*/
closeLinkText: 'Close',

/**
* @property headerTpl
* @type {Object/Array} values
* The markup used to create the headings row. By default this just uses <th> elements, override to provide your own
*/
headerTpl: [
'<tpl for=".">',
'<th>{text}</th>',
'</tpl>',
],

/**
* @property bodyTpl
* @type {Object/Array} values
* The XTemplate used to create each row. This is used inside the 'print' function to build another XTemplate, to which the data
* are then applied (see the escaped dataIndex attribute here - this ends up as "{dataIndex}")
*/
bodyTpl: [
'<tpl for=".">',
//'<td>\{{dataIndex}\}</td>',
'<td>\{{id}\}</td>',
'</tpl>',
]
}
});

dumidu
7 Aug 2012, 11:05 PM
Great plugin

happy to know how to add row numbers to the printed grid

caballero
22 Aug 2012, 1:49 PM
Here is the source!
I left the changes inside as comments to see what i have changed.
Also added requires for iframe panel.

Update: updated version and example can be found at
https://github.com/hschaefer123/uops-ext



Hey hschaefer123 (http://www.sencha.com/forum/member.php?39068-hschaefer123),
Big thanks for what you've done here.
Providing the code with example html in your git repository is a beautiful thing.
Love the improvements.

caballero
28 Aug 2012, 12:23 PM
I am currently migrating my Ext 3.x portal solution to Ext 4.1.x.

4) new feature print preview window
During migration i found out that i must not upgrade my iframe panel, because default ux iframe panel fullfills my needs. At this point i thought why not to use iframe panel for printing instead of open new window (it will be quite more comfortable) and so the new print preview window found his way into gridprinter (inspired by loaines print buttons).

37596

Here is the source!
I left the changes inside as comments to see what i have changed.
Also added requires for iframe panel.


@hschaefer123 (http://www.sencha.com/forum/member.php?39068-hschaefer123)
It was reported to me that the new print preview fails in IE. (IE8 & IE9)
I've verified that the supplied example fails in the same manner.
What happens is the entire page as shown in the image above gets printed, not just the frame as it does in Safari and Firefox.
I've looked through the IE config and can see nothing that would change this behavior.

I will keep poking around, but would appreciate some guidance if you have some thoughts.

caballero
28 Aug 2012, 4:58 PM
@hschaefer123 (http://www.sencha.com/forum/member.php?39068-hschaefer123)
It was reported to me that the new print preview fails in IE. (IE8 & IE9)
I've verified that the supplied example fails in the same manner.
What happens is the entire page as shown in the image above gets printed, not just the frame as it does in Safari and Firefox.
I've looked through the IE config and can see nothing that would change this behavior.

I will keep poking around, but would appreciate some guidance if you have some thoughts.

OK, I think I have a simple solution.

insert his line:
iframe.getWin().focus();

before this line:
iframe.getWin().print();

My tests show this solve my IE issues.

dolaemoney
28 Aug 2012, 5:12 PM
Have not used this yet
Simply thank for author's effort:)

hschaefer123
29 Aug 2012, 1:09 AM
Hi Guys,
just solving this issue by myself to see, that caballero has fixed it before the same way.

I have updated the repository with the new fix used for all browsers because the same solution also work on chrome and firefox.

I also added jsfiddle demo of grid print to see it in action (currently i could not get css stylesheet running hosted on githib for wrong mime header, but functionally it works!) .

For Demo link see original post above.

Cheers Holger

mvorpagel
11 Sep 2012, 7:49 AM
Hi Loiane,
It doesn't look like source code is available on github anymore? Has it been officially added to ExtJS release, and maybe I'm just missing it?

Thanks!

loiane
11 Sep 2012, 8:28 AM
Hi Loiane,
It doesn't look like source code is available on github anymore? Has it been officially added to ExtJS release, and maybe I'm just missing it?

Thanks!

Hi, the code is still on github.

https://github.com/loiane/extjs4-ux-gridprinter

jonasby
18 Sep 2012, 5:00 AM
I noticed your example page uses 4.0.2 which doesn't have Ext.String.createVarName

You might want to use 4.1.1

Great plugin, thanks for keeping it updated!

loiane
24 Sep 2012, 10:53 AM
As requested, added support to Grid Row Numbered plugin.

https://github.com/loiane/extjs4-ux-gridprinter

Will continue working to improve the plugin!

blackpig
26 Sep 2012, 3:23 AM
Hi,
I've tried to use your plugin in my project and works fine (thanks), but i needed also other feature than printing only list. I'm musing plugins like groupping, summaries, etc. Sometimes client need to print what he can see on the screen - ex. collapsed groups with summaries etc... I found a simple solution for this problem, by cutting table that is scrolled in the grid, using extjs-all.css and optional own css... I've added my method to your class and here is a code:

printGroups:function (grid){
var html = jQuery('#'+grid.id+' .x-grid-table:first').html();
html =
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'+
'<html>'+
'<head>'+
'<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />'+
'<link href="./libraries/ExtJS-4.0.7/resources/css/ext-all.css" rel="stylesheet" type="text/css" />'+
'<link href="' + this.stylesheetPathGroups + '" rel="stylesheet" type="text/css" />'+
'<title>' + grid.title + '</title>'+
'</head>'+
'<body ><table>'+
html+
'</table></body>'+
'</html>';
var win = window.open('', 'printgridGroups');
win.document.open();
win.document.write(html);
win.document.close();
if (this.printAutomatically){
win.print();
}
},
Using jQuery here, but may be replaced with ExtJS.
Example image:

38938

You can also get column headers if needed and insert in generated template


var headers = jQuery('#'+grid.id+' .x-grid-header-ct').html();

loiane
26 Sep 2012, 10:00 AM
Thanks for the contribution blackpig!

You you want to you can make a pull request into the repository and add your credits for this code! This way everyone else will be able to use your code as well! :)

Felipe-BR
4 Oct 2012, 6:21 AM
Olá a todos! Hey everyone!

I found a bug when the columns name are numbers. Ie.:
Encontrei um bug quando o nome da coluna são números. Por exemplo:

39139

Printing is not rendered. Can you help me?
A impressão não é renderizada. Vocês podem me ajudar?


"metaData": {
"root": "empresas",
"fields": [{
"type": "string",
"name": "ano2008",
"mapping": "indicadores.ano2008.quantidadeProcesso",
"defaultValue": "undefined"
}, {
"type": "string",
"name": "ano2009",
"mapping": "indicadores.ano2009.quantidadeProcesso",
"defaultValue": "undefined"
}, {
"type": "string",
"name": "ano2010",
"mapping": "indicadores.ano2010.quantidadeProcesso",
"defaultValue": "undefined"
}, {
"type": "string",
"name": "ano2011",
"mapping": "indicadores.ano2011.quantidadeProcesso",
"defaultValue": "undefined"
}, {
"type": "string",
"name": "ano2012",
"mapping": "indicadores.ano2012.quantidadeProcesso",
"defaultValue": "undefined"
}, {
"type": "int",
"name": "soma"
}],
"colunas": [{
"width": 80,
"renderer": Ext.util.Format.numberRenderer('0,000'),
"align": "right",
"cls": "coluna-grid-center",
"header": "2008",
"sortable": true,
"id": "id2008",
"dataIndex": "ano2008"
}, {
"width": 80,
"renderer": Ext.util.Format.numberRenderer('0,000'),
"align": "right",
"cls": "coluna-grid-center",
"header": "2009",
"sortable": true,
"id": "id2009",
"dataIndex": "ano2009"
}, {
"width": 80,
"renderer": Ext.util.Format.numberRenderer('0,000'),
"align": "right",
"cls": "coluna-grid-center",
"header": "2010",
"sortable": true,
"id": "id2010",
"dataIndex": "ano2010"
}, {
"width": 80,
"renderer": Ext.util.Format.numberRenderer('0,000'),
"align": "right",
"cls": "coluna-grid-center",
"header": "2011",
"sortable": true,
"id": "id2011",
"dataIndex": "ano2011"
}, {
"width": 80,
"renderer": Ext.util.Format.numberRenderer('0,000'),
"align": "right",
"cls": "coluna-grid-center",
"header": "2012",
"sortable": true,
"id": "id2012",
"dataIndex": "ano2012"
}, {
"width": 74,
"renderer": Ext.util.Format.numberRenderer('0,000'),
"align": "right",
"cls": "coluna-grid-center",
"header": "Soma",
"sortable": true,
"id": "idsoma",
"dataIndex": "soma"
}]
}

iplanit
8 Oct 2012, 2:03 AM
I put the plugin into a Grid in my Sencha Architect project and I get the following error:



Uncaught TypeError: Cannot read property 'columns' of undefined


The grid has headers, but otherwise is a regular Grid.



print: function(grid) {
//We generate an XTemplate here by using 2 intermediary XTemplates - one to create the header,
//the other to create the body (see the escaped {} below)
var columns = [];
//account for grouped columns
Ext.each(grid.columns, function(c) { <-- error
if(c.items.length > 0) {
columns = columns.concat(c.items.items);
} else {
columns.push(c);
}
});

iplanit
8 Oct 2012, 2:07 AM
It is working, I was using a wrong reference (Ext.getCmp).

Fixing it makes the printing table renders.

Thanks.

loiane
8 Oct 2012, 1:12 PM
Olá a todos! Hey everyone!

I found a bug when the columns name are numbers. Ie.:
Encontrei um bug quando o nome da coluna são números. Por exemplo:



Thanks for reporting the bug. Will try to reproduce and fix it.

loiane
8 Oct 2012, 2:16 PM
Added Sencha Architect example - in case anyone wants to use it with SA2:

https://github.com/loiane/extjs4-ux-gridprinter

iplanit
9 Oct 2012, 12:14 AM
Thanks

Added Sencha Architect example - in case anyone wants to use it with SA2:

https://github.com/loiane/extjs4-ux-gridprinter

Felipe-BR
15 Oct 2012, 5:37 AM
Loiane! Thanks!

drindal
15 Oct 2012, 6:49 AM
Hi,
how can I print a template column?

my grid column code is:

{
xtype:'templatecolumn',
tpl:'{NETPR} {WAERS}',
dataIndex: 'NETPR',
text: 'Netto'
},

i have tried to change the code as descriped earlier in this thread

} else if (column && column.xtype === 'templatecolumn') {
convertedData[column.dataIndex] = column.tpl ? column.tpl.apply(item.data) : value;
}

but it is not working.. it's only showing an empty Netto Column

I hope someone can help me.
Thanks.

Felipe-BR
15 Oct 2012, 12:53 PM
Loiane! About that bug, i found the error and i fix it.


var dataPrinter = [];
grid.store.data.each(function(item, row) {
var convertedData = {};
// apply renderers from column model
for (var key in item.data) {
var value = item.data[key];
Ext.each(columns, function(column, col) {
if (column.dataIndex == key) {
/*
* TODO: add the meta to template
*/
var meta = {
item : '',
tdAttr : '',
style : ''
};
value = column.renderer
? column.renderer.call(grid, value,
meta, item, row, col,
grid.store, grid.view)
: value;
varName = Ext.String.createVarName(column.dataIndex);
convertedData[varName] = value;
}
}, this);
}
dataPrinter.push(convertedData);
});



bodyTpl : ['<tpl for=".">',
'<td>\{{[Ext.String.createVarName(values.dataIndex)]}\}</td>',
'</tpl>']
}

grpbhb
16 Oct 2012, 10:21 AM
With RowExpander of Extjs 4.1.2 doesn't work,


Ext.each(grid.plugins, function(p) {
if (p.ptype == 'rowexpander') {
pluginsBody += p.rowBodyTpl.join(''); //In 4.1.2 rowBodyTpl is a XTemplate object
}
});


1- How obtain the compiled template with the data of each record?
2- I want to show only the expanded rows, not all rows.
Thanks!

loiane
17 Oct 2012, 9:45 AM
Loiane! About that bug, i found the error and i fix it.


Thanks Felipe, already committed the fix on github.

loiane
17 Oct 2012, 4:47 PM
Hi,
how can I print a template column?

my grid column code is:

{
xtype:'templatecolumn',
tpl:'{NETPR} {WAERS}',
dataIndex: 'NETPR',
text: 'Netto'
},

i have tried to change the code as descriped earlier in this thread

} else if (column && column.xtype === 'templatecolumn') {
convertedData[column.dataIndex] = column.tpl ? column.tpl.apply(item.data) : value;
}

but it is not working.. it's only showing an empty Netto Column

I hope someone can help me.
Thanks.

Fixed.
You can get the new version from github and use.
Template columns are now supported by the plugin.

loiane
17 Oct 2012, 4:51 PM
With RowExpander of Extjs 4.1.2 doesn't work,


Ext.each(grid.plugins, function(p) {
if (p.ptype == 'rowexpander') {
pluginsBody += p.rowBodyTpl.join(''); //In 4.1.2 rowBodyTpl is a XTemplate object
}
});


1- How obtain the compiled template with the data of each record?
2- I want to show only the expanded rows, not all rows.
Thanks!

Sorry. I don't have access to 4.1.2 yet. I only use open source version - educational purposes.

grpbhb
18 Oct 2012, 3:37 AM
Ok, but the problem exists!.
"pluginsBody += p.rowBodyTpl.join('');" only appends tpl, How obtain the compiled template with the data of each record?
I want to show only the expanded rows.
Thanks!

CE_REAL
19 Oct 2012, 7:03 AM
Hey I'm using the grid printer plugin and it works great. But now I want to display the header every 30 or so rows. I'm not really that advanced with ExtJS yet so I hope someone can help me breaking up the data to add more than one header.

Thanks in advance.

Edit:

I found a solution for my problem. I added thead and tbody to my output HTML:



'<table>',
'<thead>',
headings,
'</thead>',
'<tbody>',
'<tpl for=".">',
body,
'</tpl>',
'</tbody>',
'</table>',


And then added thead styling to my stylesheet:


thead { display: table-header-group; }

Which then results in displaying the header on every page that is printed.

drindal
22 Oct 2012, 3:10 AM
Fixed.
You can get the new version from github and use.
Template columns are now supported by the plugin.

thank you! works now.

CE_REAL
22 Oct 2012, 7:18 AM
I've got a new challenge, I see the Grid Printer working when a gird is created. But I'm using the http://dev.sencha.com/deploy/ext-4.0.0/examples/writer/writer.html example, which creates no grid but only defines it and creates it using the following:



var main = Ext.create('Ext.container.Container', {
renderTo: Ext.Element.get('invoice-summary'),
layout: 'fit',
autoHeight: true,
items: [{
itemId: 'grid',
xtype: 'writergrid',
flex: 1,
store: store
}]
});


So when I try using the gridprinter it sends an empty grid, which shows up in Firebug as h() which has no store to access by using grid.store. So I get errors and have no data to show in the printview.

loiane
22 Oct 2012, 12:30 PM
I've got a new challenge, I see the Grid Printer working when a gird is created. But I'm using the http://dev.sencha.com/deploy/ext-4.0.0/examples/writer/writer.html example, which creates no grid but only defines it and creates it using the following:



var main = Ext.create('Ext.container.Container', {
renderTo: Ext.Element.get('invoice-summary'),
layout: 'fit',
autoHeight: true,
items: [{
itemId: 'grid',
xtype: 'writergrid',
flex: 1,
store: store
}]
});


So when I try using the gridprinter it sends an empty grid, which shows up in Firebug as h() which has no store to access by using grid.store. So I get errors and have no data to show in the printview.

You need to pass an instance of a GridPanel to the plugin.
In your case, you can get the grid instance using the following code - this will be your grid variable:

Ext.ComponentQuery.query('writergrid[itemId=grid]')[0]

CE_REAL
23 Oct 2012, 11:46 PM
You need to pass an instance of a GridPanel to the plugin.
In your case, you can get the grid instance using the following code - this will be your grid variable:

Ext.ComponentQuery.query('writergrid[itemId=grid]')[0]

I used your solution and I got it to work with the toolbar printbutton. Now I'm being a bit demanding with my usage of the gridprinter.

I'll explain my whole situation a bit better:

First of all I've got one page with two containers:



var total = Ext.create('Ext.container.Container', {
renderTo: Ext.Element.get('invoice-summary-total'),
layout: 'fit',
autoHeight: true,
items: [{
itemId: 'grid',
xtype: 'writergrid',
flex: 1,
store: total_store
}]
});


var main = Ext.create('Ext.container.Container', {
renderTo: Ext.Element.get('invoice-summary'),
layout: 'fit',
autoHeight: true,
items: [{
itemId: 'grid',
xtype: 'writergrid',
flex: 1,
store: store
}]
});


Both are using the same defined grid:


var grid = Ext.define('Writer.Grid', {
extend: 'Ext.grid.Panel',
alias: 'widget.writergrid',


requires: [
'Ext.grid.plugin.CellEditing',
'Ext.form.field.Text',
'Ext.toolbar.TextItem',
'Ext.ux.grid.Printer'
],


initComponent: function(){


this.editing = Ext.create('Ext.grid.plugin.RowEditing', {
clicksToMoveEditor: 1,
autoCancel: false
});


Ext.apply(this, {
title: 'Invoice summary' + ' [<?php echo $customer_information['id'] .' ' .$customer_information['name'] ?>]',
iconCls: 'icon-grid',
frame: true,
plugins: [this.editing],
columns: [{
text: '<?php echo __('Invoice number') ?>',
width: 80,
sortable: true,
dataIndex: 'number',
renderer: function(value, metaData, record, rowIndex, colIndex, store) {
var linkReturn = '';
var customerId = '<?php echo $customer_information['id'] ?>';
if (!isNaN(record.data.number) && record.data.number != '') {
linkReturn = '<a href="' + url + "/agent/invoicePaymentSummary/" + '<?php echo $customer_information['id'] ?>'+ "/" + record.data.number +'">'+ record.data.number +'</a>';
} else {
linkReturn = record.data.number;
}
return linkReturn;
}
}, {
header: '<?php echo __('Date') ?>',
width: 70,
sortable: true,
dataIndex: 'date',
renderer: Ext.util.Format.dateRenderer('d-m-Y'),
}, {
header: '<?php echo __('Due date') ?>',
width: 70,
sortable: true,
dataIndex: 'due_date',
renderer: Ext.util.Format.dateRenderer('d-m-Y'),
renderer: function(value, metaData, record, rowIndex, colIndex, store) {
var returnValue = Ext.Date.format(value, "d-m-Y");
var dueDate = value;
var today = new Date();
if(dueDate < today && record.data.overdue_days > 0) {
returnValue = '<p class="red">'+ returnValue +'</p>';
}
return returnValue;
}
}, {
header: '<?php echo __('Invoice amount') ?>',
width: 90,
sortable: true,
dataIndex: 'invoice_amount',
align: 'right',
renderer: money
}, {
header: '<?php echo __('Paid') ?>',
width: 90,
sortable: true,
dataIndex: 'paid',
align: 'right',
renderer: money
}, {
header: '<?php echo __('Remaining') ?>',
width: 90,
sortable: true,
dataIndex: 'remaining',
align: 'right',
renderer: money
}, {
header: '<?php echo __('Currency') ?>',
width: 60,
sortable: true,
dataIndex: 'currency'
}, {
header: '<?php echo __('Draft') ?>',
width: 40,
sortable: true,
dataIndex: 'draft',
align: 'right',
renderer: redClass
}, {
header: '<?php echo __('Overdue days') ?>',
width: 80,
sortable: true,
dataIndex:"overdue_days",
align: 'right',
renderer: redOverdueDaysClass
}, {
xtype: 'numbercolumn',
header: '<?php echo __('Pay-week') ?>',
width: 80,
sortable: true,
dataIndex:"pay_week",
format: '0',
field: {
xtype: 'numberfield',
allowBlank: false,
minValue: period,
regex: /^[0-9]{4}([0][1-9]|[1-4][0-9]|[5][0-2])$/i,
maskRe: /^[0-9]{4}([0][1-9]|[1-4][0-9]|[5][0-2])$/i,
regexText: 'Format YYYYWW (Min. YYYY01 - Max. YYYY52)'
},
align: 'right',
vtype: 'payweek',
renderer: redPayWeekField
}, {
header: '<?php echo __('Comment') ?>',
width: 220,
sortable: true,
dataIndex:"comment",
field: {
type: 'textfield',
maxLength: 30,
emptyText: ''
},
renderer: redCommentField
}, {
header: '<?php echo __('Send address') ?>',
width: 200,
sortable: true,
dataIndex:"send_address"
}, {
header: '<?php echo __('PDF') ?>',
width: 40,
sortable: true,
dataIndex:"pdf",
renderer: function(value, metaData, record, rowIndex, colIndex, store) {
var pdfReturn = '';
var customerId = '<?php echo $customer_information['id'] ?>';
if (!isNaN(record.data.number) && record.data.number != '')
pdfReturn = '<a href="' + url + '/agent/invoiceSummary/viewInvoice/'+ record.data.number +'/'+ customerId +'" target="_blank">'+ '<img src="/images/icons/pdf_icon.gif"></a>';
return pdfReturn;
}
}],
tbar: [{
text: 'Print',
iconCls: 'icon-print',
handler : function(){
Ext.ux.grid.Printer.printAutomatically = true;
Ext.ux.grid.Printer.print(Ext.ComponentQuery.query('writergrid[itemId=grid]')[1]);
}
}]
});
this.callParent();

onSync: function(){
this.store.sync();
}
});


Now I'd like to print the first grid and print the second grid with both their own print button in the toolbar.

I'm thinking of maybe creating two different toolbars and using them in the container, but I don't really know how to add them to the container.

And the second thing I like, is using my own print button outside of the grid like:


<div id="print"><button id="printPage" onclick="Ext.ux.GridPrinter.print(invoiceSummaryGrid)">Print</button></div>


But I can't get my grid object to send to the Ext.ux.GridPrinter.print function. I get the following error:



TypeError: grid.store is undefined
grid.store.data.each(function(item, row)

I hope you can help me with this problem.

Radius-Service
19 Nov 2012, 3:30 AM
Printing GridPanels with GroupingView and GroupSummary plugin

http://www.rahulsingla.com/blog/2010/10/extjs-printing-gridpanels-with-groupingview-and-groupsummary-plugin

But working with Ext 3 only

rafaelrp
12 Jul 2013, 5:01 AM
This plugin works with 4.2?

Thanks!

orrence
16 Aug 2013, 7:56 AM
Printing GridPanels with GroupingView and GroupSummary plugin

http://www.rahulsingla.com/blog/2010/10/extjs-printing-gridpanels-with-groupingview-and-groupsummary-plugin

But working with Ext 3 only


See my merged pull request regarding this matter on github.com.

Cheers,
orrence.

TexasSteve99
5 Sep 2013, 9:57 AM
Hi,

I ran into an issue under Ext 4.2.1. Some of my data models have more fields than are currently configured in the grid columns. I had to make the following changes in Printer.js:

bodyTpl changes:


var bodyTpl = [
'<tpl for=".">',
'<tr class="group-header">',
'<td colspan="{[this.colSpan]}">',
html, // This is the group header!
'</td>',
'</tr>',
'<tpl for="children">',
'<tr>',
'<tpl for="this.columns">',
'{% if (values.dataIndex==="id") continue; %}',
'<td>',
'{[ parent.get(values.dataIndex) ]}',
'</td>',
'</tpl>',
'</tr>',
'</tpl>',
'</tpl>',
{
// XTemplate configuration:
columns : columns,
colSpan : columns.length - 1,
// XTemplate member functions:
childCount : function(c) {
return c.length;
}
}
];



I also changed Printer.js to use the columnManager.getColumns() instead of interogating grid.columns directly.:



var columns = grid.columnManager.getColumns();
// //account for grouped columns
// Ext.each(grid.columns, function(c) {
// if(c.items.length > 0) {
// columns = columns.concat(c.items.items);
// } else {
// columns.push(c);
// }
// });


This had the advantage of getting columns in the correct order in case the user had moved one or more columns.

Thanks,

Steve Ervin

orrence
9 Sep 2013, 3:16 AM
Hi Ervin!
Have you tried if your changes are compatible with versions 4.1.x, too?
If the answer is "yes" then I would recommend to make a pull request on the project page on github.
Thanks,
orrence.

TexasSteve99
10 Sep 2013, 11:09 AM
I have not. Where I work, we are migrating directly from 3.x -> 4.2.1. I will pull 4.1 and try them. I expect the bodyTpl to work but not the columnManager.

I will let you know.

Steve

TexasSteve99
19 Sep 2013, 10:19 AM
I have submitted a pull request for my grouping changes. I also added support for summary and groupingsummary features. They have been tested under 4.1.3 and 4.2.1.

Steve

orenmeidan
30 Sep 2013, 11:34 PM
Hi,

Thanks for the great plugin.

In my renderer function I use information from the meta.record. since it's not existing in the meta definition, I got an error.

I fixed it by changing:
var meta = {item: '', tdAttr: '', style: ''};
to
var meta = {item: '', tdAttr: '', style: '',record:item};

You might want to consider changing it.

Delphine
1 Oct 2013, 4:16 AM
I use this plugin. All is ok but I can't have my meta personnalized.

In my gris, I have :

column.renderer = function(value, meta) {
var tabVal = value.split(',');
if (tabVal.length > 1) {
var valTmp = tabVal[1].split('|');
// On met un style uniquement pour l'intérieur de la grille
if (valTmp.length > 1) {
meta.tdCls = 'td-grille-kiela';
if (valTmp[1] != '') {
// On colore le fond des cellules en fonction de ce qui est posé
meta.style = "background-color: #" + valTmp[1] + ";";
if (valTmp[2] == 'K')
meta.style += "color: #C0C0C0;";


// Demi journée
if (valTmp[3] == 1) {
meta.tdCls = 'td-grille-kiela-demijour';
}


// Commentaire de la saisie
if (valTmp[4] != '' && valTmp[4] != 'grille') {
meta.tdAttr = 'data-qtip="' + Ext.String.htmlEncode(valTmp[4]) + '"';
meta.style += "background-image:url(/app/ressources/images/fam/comment_petit.png);";
meta.style += "background-repeat:no-repeat;";
}
}
}
} else {
var valTmp = value.split('|');
if (value.indexOf('|') > 0) // On ne met l'italic que sur l'intérieur du tableau, pas le nom
meta.style = "font-style: italic; color: #C0C0C0;";
}
return valTmp[0];
};

If I look meta (with console.log(meta) ), I have this :

Object {item: "", tdAttr: "", style: "background-color: #6EDCAB;", tdCls: "td-grille-kiela"}
But in the opened windows, the columns have no meta.
How can I apply this meta ?

Thanks in advance !

TexasSteve99
1 Oct 2013, 6:04 AM
Sorry about that. Record is not in the documentation. I will do some snooping and add the missing fields. I will let you know when the fix is available.

Steve

TexasSteve99
1 Oct 2013, 6:22 AM
The Grid Printer has not ever supported using the Meta in the output. I was considering updating it to do that but it will need several changes to do so. The change I posted adds the following features:

1) Uses Ext.Grid.ColumnManager in Ext 4.2 to support Grid reconfigure().
2) Align grid items according to the column's align property.
3) Supports summary and groupingsummary features.
4) Calls the Summary renderer to get properly formatted values.

Thanks,

Steve


I use this plugin. All is ok but I can't have my meta personnalized.

In my gris, I have :

column.renderer = function(value, meta) {
var tabVal = value.split(',');
if (tabVal.length > 1) {
var valTmp = tabVal[1].split('|');
// On met un style uniquement pour l'intérieur de la grille
if (valTmp.length > 1) {
meta.tdCls = 'td-grille-kiela';
if (valTmp[1] != '') {
// On colore le fond des cellules en fonction de ce qui est posé
meta.style = "background-color: #" + valTmp[1] + ";";
if (valTmp[2] == 'K')
meta.style += "color: #C0C0C0;";


// Demi journée
if (valTmp[3] == 1) {
meta.tdCls = 'td-grille-kiela-demijour';
}


// Commentaire de la saisie
if (valTmp[4] != '' && valTmp[4] != 'grille') {
meta.tdAttr = 'data-qtip="' + Ext.String.htmlEncode(valTmp[4]) + '"';
meta.style += "background-image:url(/app/ressources/images/fam/comment_petit.png);";
meta.style += "background-repeat:no-repeat;";
}
}
}
} else {
var valTmp = value.split('|');
if (value.indexOf('|') > 0) // On ne met l'italic que sur l'intérieur du tableau, pas le nom
meta.style = "font-style: italic; color: #C0C0C0;";
}
return valTmp[0];
};

If I look meta (with console.log(meta) ), I have this :

Object {item: "", tdAttr: "", style: "background-color: #6EDCAB;", tdCls: "td-grille-kiela"}
But in the opened windows, the columns have no meta.
How can I apply this meta ?

Thanks in advance !

Dmoney
10 Oct 2013, 5:09 AM
Does anyone have this working with summary grids. The plugin works great for me with standard grids but with my summary grids all I get are the headings.

TexasSteve99
19 Oct 2013, 7:30 PM
Does anyone have this working with summary grids. The plugin works great for me with standard grids but with my summary grids all I get are the headings.

I recently posted code on GitHub to add support for Summary and Grouping Summary Grid Features. You can download it by going to the following URL: https://github.com/loiane/extjs4-ux-gridprinter and pressing the download button.

Within the next couple weeks, I hope to posting code to support the following:

Complete Metadata object.
Support for server generated summaries.
Printing Tree grids.

Thanks,

Steve

smstid
21 Oct 2013, 6:27 AM
Hi
Is there a way to extend your nice plugin with rowbody

I have been using Eds original plugin before that I modified to print the row body, but have now switch to using yours and has been playing with the code without success for printing the row body.

Regards Max

TexasSteve99
21 Oct 2013, 8:27 AM
Loiane Groner, the original author of the Grid Printer plugin, added code for RowExpander. I have never used that or RowBody. You would be best to reply to one of her posts for help.

Steve


Hi
Is there a way to extend your nice plugin with rowbody

I have been using Eds original plugin before that I modified to print the row body, but have now switch to using yours and has been playing with the code without success for printing the row body.

Regards Max

radtad
24 Oct 2013, 9:21 AM
I recently posted code on GitHub to add support for Summary and Grouping Summary Grid Features. You can download it by going to the following URL: https://github.com/loiane/extjs4-ux-gridprinter and pressing the download button.

Within the next couple weeks, I hope to posting code to support the following:

Complete Metadata object.
Support for server generated summaries.
Printing Tree grids.

Thanks,

Steve

I was going to fix a couple of the following in regards to grid grouping:

- colSpan is off by 1 (not sure if columns.length - 1 was the appropriate value)
- groupName is not showing up

TexasSteve99
24 Oct 2013, 10:23 AM
I just submitted a pull request to Loaine. Once its accepted, go for it!

I will be posting a message about the changes after its accepted.

Steve


I was going to fix a couple of the following in regards to grid grouping:

- colSpan is off by 1 (not sure if columns.length - 1 was the appropriate value)
- groupName is not showing up

TexasSteve99
24 Oct 2013, 10:35 AM
If your groupHeaderTpl has methods, the grid printer will not see those. You will need to fix the generatedBody() method to support it.


The columns -1 colspan value is from a previous contributor.

Thanks,

Steve

radtad
24 Oct 2013, 11:27 AM
If your groupHeaderTpl has methods, the grid printer will not see those. You will need to fix the generatedBody() method to support it.


The columns -1 colspan value is from a previous contributor.

Thanks,

Steve

That's the section I was modifying :) . Just have to make sure I check for the groupHeaderTpl properly. As of right now, the feature.groupHeaderTpl.html default is '{groupName}: {name}' and doesn't return properly anyway. Nowhere is groupName set.

TexasSteve99
24 Oct 2013, 12:08 PM
I'm looking into that right now. The only values the groupHeaderTpl sees in generateBody() is name and children. I'm working on an applyGroupTpl method to fix it so it will print any groupHeaderTpl.

Steve

TexasSteve99
24 Oct 2013, 1:02 PM
I've applied a fix for the columns -1 and groupHeaderTpl. It should be included in my pull request when Loiane approves it. If you want to try it out now, you can pull it from https://github.com/TexasSteve99/extjs4-ux-gridprinter/archive/master.zip.

Steve


That's the section I was modifying :) . Just have to make sure I check for the groupHeaderTpl properly. As of right now, the feature.groupHeaderTpl.html default is '{groupName}: {name}' and doesn't return properly anyway. Nowhere is groupName set.

TexasSteve99
25 Oct 2013, 5:15 AM
Good Morning Everyone,

I have updated the Grid Printer on github (https://github.com/loiane/extjs4-ux-gridprinter/archive/master.zip) with the following updates:


Fixed the groupHeaderTpl handling to support all attributes except rows.
Full XTemplate support for template columns and RowExpander.
Styling via metadata object. The following attributes are supported:

align
tdCls
innerCls
style
tdAttr
tdCls
unselectableAttr


Server generated summaries and groupingsummaries (remoteRoot).
Added a rowexpander grid to example.html.

For styling output with CSS classes, you must either:

Copy your classes into the top of the print.css file or
Supply a custom css file by setting a Ext.ux.grid.Printer.stylesheetPath prior to printing. I recommend you append the contents of print.css to this file.

Server generated summaries (remoteRoot) for the summary feature is currently broken in ExtJS 4.2.1. The following override will fix it.



Ext.grid.feature.Summary.override({
createSummaryRecord: function(view) {
var columns = view.headerCt.getVisibleGridColumns(),
info = {
records: view.store.getRange()
},
colCount = columns.length, i, column,
summaryRecord = this.summaryRecord || (this.summaryRecord = new view.store.model(null, view.id + '-summary-record'));

// Set the summary field values
summaryRecord.beginEdit();

if (this.remoteRoot) {
if (view.store.proxy.reader.rawData) {
if (Ext.isArray(view.store.proxy.reader.rawData[this.remoteRoot]))
summaryRecord.set(view.store.proxy.reader.rawData[this.remoteRoot][0]);
else
summaryRecord.set(view.store.proxy.reader.rawData[this.remoteRoot]);
}
} else {
for (i = 0; i < colCount; i++) {
column = columns[i];

// In summary records, if there's no dataIndex, then the value in regular rows must come from a renderer.
// We set the data value in using the column ID.
if (!column.dataIndex) {
column.dataIndex = column.id;
}

summaryRecord.set(column.dataIndex, this.getSummary(view.store, column.summaryType, column.dataIndex, info));
}
}

summaryRecord.endEdit(true);
// It's not dirty
summaryRecord.commit(true);
summaryRecord.isSummary = true;

return summaryRecord;
}
});


You can download the new version from https://github.com/loiane/extjs4-ux-gridprinter/archive/master.zip

Let me know if you run into any issues.

This will be my last update for a while. I have an urgent project that needs my attention.

Thanks,

Steve Ervin

radtad
28 Oct 2013, 12:49 PM
Good Morning Everyone,

You can download the new version from https://github.com/loiane/extjs4-ux-gridprinter/archive/master.zip

Let me know if you run into any issues.

This will be my last update for a while. I have an urgent project that needs my attention.

Thanks,

Steve Ervin

So far works great!

radtad
28 Oct 2013, 3:07 PM
Looks like it breaks on xtype: 'actioncolumn'.



Error: Cannot read property 'disabled' of undefined


I think some logic to skip this column needs to be added since there is no reason to print it that I can see. Changes in red below fixes the problem.



// remove columns that do not contain dataIndex
// or dataIndex is empty.
// for example: columns filter or columns button
var clearColumns = [];
Ext.each(
columns,
function (column) {
if ( column ) {
if ( !Ext.isEmpty(column.dataIndex) &&
!column.hidden &&
!isGrouped &&
column.xtype !== 'actioncolumn')
{
clearColumns.push(column);
} else if ( column.xtype === 'rownumberer'){
if (!column.text) column.text = 'Row';
clearColumns.push(column);
} else if ( column.xtype === 'templatecolumn'){
clearColumns.push(column);
} else if ( isGrouped &&
column.dataIndex !== groupField &&
column.xtype !== 'actioncolumn')
{
clearColumns.push(column);
}
}
}
);
columns = clearColumns;

mazhar.shaikh
31 Oct 2013, 5:05 PM
Hi,

I am using the Grid plugin and it works just fine.

There's a slight problem, I am using
grid.reconfigure in my controller and modifying the columns that appear in the grid.
But on clicking the Print button, the grid still prints all the columns that I placed on the view.

Is there a way, I could print only the columns thats on the grid?

Thanks

TexasSteve99
1 Nov 2013, 7:26 AM
Hi,

I am using the Grid plugin and it works just fine.

There's a slight problem, I am using
grid.reconfigure in my controller and modifying the columns that appear in the grid.
But on clicking the Print button, the grid still prints all the columns that I placed on the view.

Is there a way, I could print only the columns thats on the grid?

Thanks

I got into making updates to Grid Printer because it wasn't supporting reconfigure under 4.2.1. It properly handles reconfigure in my code now. Could you let me know which version your using?

Thanks,

Steve

TexasSteve99
1 Nov 2013, 7:28 AM
Looks like it breaks on xtype: 'actioncolumn'.



Error: Cannot read property 'disabled' of undefined


I think some logic to skip this column needs to be added since there is no reason to print it that I can see. Changes in red below fixes the problem.



// remove columns that do not contain dataIndex
// or dataIndex is empty.
// for example: columns filter or columns button
var clearColumns = [];
Ext.each(
columns,
function (column) {
if ( column ) {
if ( !Ext.isEmpty(column.dataIndex) &&
!column.hidden &&
!isGrouped &&
column.xtype !== 'actioncolumn')
{
clearColumns.push(column);
} else if ( column.xtype === 'rownumberer'){
if (!column.text) column.text = 'Row';
clearColumns.push(column);
} else if ( column.xtype === 'templatecolumn'){
clearColumns.push(column);
} else if ( isGrouped &&
column.dataIndex !== groupField &&
column.xtype !== 'actioncolumn')
{
clearColumns.push(column);
}
}
}
);
columns = clearColumns;


Thanks for contributing! I have entered your fix and submitted a Pull request to Loaine. The fix should be on GitHub within 24 hours.

Steve

smstid
1 Nov 2013, 7:48 AM
Hi thanks for the nice updated version

Is there a way to extend your nice plugin with rowbody

I have been using Eds original plugin before that I modified to print the row body, but have now switch to using yours and has been playing with the code without success for printing the row body.

Regards Max

TexasSteve99
1 Nov 2013, 10:37 AM
Hi thanks for the nice updated version

Is there a way to extend your nice plugin with rowbody

I have been using Eds original plugin before that I modified to print the row body, but have now switch to using yours and has been playing with the code without success for printing the row body.

Regards Max

I will get that working when I start working on the tree grid support. I will probably start working on it late next week.

Steve

smstid
1 Nov 2013, 2:02 PM
Fantastic, big thanks
If there is anything I can do to help you out I am happy to do that

Best Regards Max

filippo.ferrari
4 Nov 2013, 1:53 AM
I'm tring to integrate gridprinter plugin in my project. I get an error: 'record is undefined' on line 72766 of ext-all-debug where ext call method getGroups:


getGroups: function(requestGroupString) {var records = this.data.items,
length = records.length, // <-- error line
groups = [],
pointers = {},
record,
groupStr,
group,
i;
for (i = 0; i < length; i++) {
record = records[i];
groupStr = this.getGroupString(record);
group = pointers[groupStr];
if (group === undefined) {
group = {
name: groupStr,
children: []
};
groups.push(group);
pointers[groupStr] = group;
}
group.children.push(record);
}
return requestGroupString ? pointers[requestGroupString] : groups;
}

I'm using Ext 4.2.1.883

radtad
4 Nov 2013, 1:42 PM
I'm tring to integrate gridprinter plugin in my project. I get an error: 'record is undefined' on line 72766 of ext-all-debug where ext call method getGroups:

I'm using Ext 4.2.1.883

Posting ExtJS code isn't helping anyone debug your code. You will need to post your code in order for anyone to help you.

diegotainha
18 Nov 2013, 4:40 AM
Olá Loiane, estou com um problema na minha impressão. A grid é impressa duas vezes em uma mesma página de impressão, uma grid em seguida da outra. Já ocorreu algo assim? Sabe o motivo?

Matt Bittner
17 Jun 2014, 7:03 AM
Any ideas, off the top of your heads, why I would receive a "getFields" is not a function error from within ux.grid.Printer, at line 543? I checked the regModel and it appears to be the same as the example.

Here's part of the code:


Ext.regModel( 'reportModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'plan'},
{name: 'anniversary'},
{name: 'rec_id'}
]
});

var reporStore = Ext.create( 'Ext.data.JsonStore', {
autoLoad: true,
model: 'reportModel',
proxy: {
type: 'ajax',
url: 'anniversary.sql',
reader: {
idProperty: 'rec_id',
root: 'results',
type: 'json'
}
}
});

var reportGrid = Ext.create( 'Ext.ux.LiveSearchGridPanel', {
columns: [],
hidden: false,
hideCollapseTool: true,
id: 'reportGrid',
afterrender: function( self, store_record, html_element, node_index, event ){
this.getTopToolbar().add( {xtype: 'tbfill'} );
this.getTopToolbar().add({
text: 'Print',
iconCls: 'icon-print',
handler: function(){
Ext.ux.grid.Printer.printAutomatically = false;
Ext.ux.grid.Printer.print ( Ext.getCmp( 'reportGrid' ) );
}
});
},
store: reportStore
});

TexasSteve99
18 Jun 2014, 11:34 AM
This is probably caused because the Grid Printer gets an undefined when calling getModel(). Since Ext.regModel is deprecated since 4.0.0, try changing it to Ext.define. If that doesn't work, let us know what version of ExtJS your using.

Steve

Matt Bittner
19 Jun 2014, 5:22 AM
Changed Ext.regModel to Ext.define and still receiving the same error. I'm currently on 4.0.7 but about to upgrade to 4.2.1 hopefully in the very near future.

austin1030
27 Aug 2014, 9:24 PM
Hi

I have updated Printer.js with the latest one with hope GroupSummary is working. But, for some reason, it does not work. I wonder why. BTW, I'm using Ext 4.2.x.

Is there a tip or step am I missing?

Austin

TexasSteve99
28 Aug 2014, 7:36 AM
I re-downloaded the version of sourceforge recently. It appears that printing summaries is broken. Its also not printing my tree grids properly. I will fix it but its going to take some time. In the meantime, try this version that I use in my enterprise apps.

Thanks,

Steve Ervin

austin1030
28 Aug 2014, 7:58 AM
Thanks TexasSteve99

I believe below code is what causing...end of function, you are returning "undefined".


getFeature : function( grid, featureFType) {
var view = grid.getView();
var features = view.features;
if (features)
for (var i = 0; i <features.length; i++)
{
if (featureFType == 'grouping')
if (features[i].ftype == 'grouping' || features[i].ftype == 'groupingsummary')
return features[i];
if (featureFType == 'groupingsummary')
if (features[i].ftype == 'groupingsummary')
return features[i];
if (featureFType == 'summary')
if (features[i].ftype == 'summary')
return features[i];
}
return undefined; //WHY????
},



EDIT: on the other hand, I may mistaken above code for bug...it may not....then, I don't know why.

EDIT 2: Looking into above code, Ext 4.2.x does not have ftype in feature.

austin1030
28 Aug 2014, 8:09 AM
TexasSteve99

Just let you know that I downloaded your file but no luck.

austin1030
28 Aug 2014, 9:09 AM
I found out that if I just do this...


return features[0];

Rest of parts is working.

Austin

BillySao
1 Sep 2014, 2:16 PM
Hi,
Why I can not see the data grouped when do I configure it this way in the gridpanel?



features: [
{
ftype: 'grouping',
groupHeaderTpl: [
'{[values.rows[0].data["name"]]}'
]
}
]


With the above code I would like to know if there is any way that I can display the data grouped as this is not seen. Thank you very much.

TexasSteve99
2 Sep 2014, 10:00 AM
All,

I have fixed the getFeature() method. I have also fixed the plugin to work on ExtJS 5.0.1. It was not working on ExtJS 5 previously because the output of Ext.data.store.getGroups() has changed. Previously it emitted an array of group objects. Under ExtJS 5, it emits an Ext.util.GroupCollection object. Ext.util.GroupCollection is a private class. The documentation has not been updated to reflect that it no longer emits an array. I have opened a ticket with Sencha on the misleading documentation. The new code has been posted to https://github.com/loiane/extjs4-ux-gridprinter.

Enjoy,

Steve Ervin

TexasSteve99
2 Sep 2014, 10:12 AM
Hi,
Why I can not see the data grouped when do I configure it this way in the gridpanel?



features: [
{
ftype: 'grouping',
groupHeaderTpl: [
'{[values.rows[0].data["name"]]}'
]
}
]


With the above code I would like to know if there is any way that I can display the data grouped as this is not seen. Thank you very much.

Download the new Printer.js I just posted to github.com and change rows to children. Rows is deprecated and not supported by the Grid Printer Plugin. If that doesn't work, try values.children[0].get("name").

Steve Ervin

BillySao
2 Sep 2014, 2:17 PM
Download the new Printer.js I just posted to github.com and change rows to children. Rows is deprecated and not supported by the Grid Printer Plugin. If that doesn't work, try values.children[0].get("name").

Steve Ervin

Thank you very much, works perfectly, excellent support.

austin1030
3 Sep 2014, 10:33 AM
I have fixed the getFeature() method. I have also fixed the plugin to work on ExtJS 5.0.1. It was not working on ExtJS 5 previously because the output of Ext.data.store.getGroups() has changed. Previously it emitted an array of group objects. Under ExtJS 5, it emits an Ext.util.GroupCollection object. Ext.util.GroupCollection is a private class. The documentation has not been updated to reflect that it no longer emits an array. I have opened a ticket with Sencha on the misleading documentation. The new code has been posted to https://github.com/loiane/extjs4-ux-gridprinter.

Thank you so much!

austin1030
3 Sep 2014, 10:58 AM
I found out that if I just do this...


return features[0];

Rest of parts is working.

Austin

I downloaded the latest version and no luck. I still need to change the getFeature function as before (as above).

mazhar.shaikh
7 Sep 2014, 5:43 PM
Hi,

I am reconfiguring my grid on runtime and pushing appropriate columns on. All columns display fine but BOOLEAN column does not display anything. Appears blank. The way I am pushing it on the grid is a below:

item = {
xtype: 'booleancolumn',
dataIndex: 'isApproved',
text: '<b>Approved</b>',
tooltip: 'Approved (Yes/No)',
falseText: 'No',
trueText: 'Yes',
stateId: 'grid1IsApproved',
stateful: true,
editor: {
xtype: 'checkboxfield'
}
};
columns.push(item);


Am I missing something? Or is it a bug in the plugin?
Thanks

smileyatic
11 Sep 2014, 12:48 PM
Hi, I'm using this plugin on a ext 5.0.1+ app.
I've got a simple app at this point.

The problem I have, is if I have any field that has a renderer, it
prints the header row, and any data on the first record until
it gets to the columns with the renderer, then I get this exception:

XTemplate evaluation exception: Cannot read property 'Column' of undefined


some interesting other observations, are if I group any of the fields,
it will print with the data properly, even though there is the renderer.

it doesn't matter what field has the renderer, but it will stop when it hits
that first column that has the renderer.

the code for example -
columns:[
{
header:'Score ID',
text: 'id',
dataIndex:'id', flex: 1,
renderer: function(value, meta, rec) {
console.log(value);
console.log(rec);
console.log(rec.phantom);
return rec.phantom ? null : value;
}
},

Any thoughts?

I'm using the latest version from
https://github.com/loiane/extjs4-ux-gridprinter

(https://github.com/loiane/extjs4-ux-gridprinter)

smileyatic
15 Sep 2014, 7:29 AM
I was able to track down the problem (but no solution except not to make the call )
In the case there is no grouping, but columns that have renderers, this gets called
and failes.

if (column instanceof Ext.tree.Column) {


in the code



if (column.xtype == 'templatecolumn')



{



value = column.tpl ? column.tpl.apply(rcd.data) : value;



}



else if (column.renderer) {



if (column instanceof Ext.tree.Column) {



value = column.renderer.call(column, value, meta, rcd, -1, col - 1, this.grid.store, this.grid.view);



} else {



value = column.renderer.call(this.grid, value, meta, rcd, -1, col - 1, this.grid.store, this.grid.view);



}



}






Hi, I'm using this plugin on a ext 5.0.1+ app.
I've got a simple app at this point.

The problem I have, is if I have any field that has a renderer, it
prints the header row, and any data on the first record until
it gets to the columns with the renderer, then I get this exception:

XTemplate evaluation exception: Cannot read property 'Column' of undefined


some interesting other observations, are if I group any of the fields,
it will print with the data properly, even though there is the renderer.

it doesn't matter what field has the renderer, but it will stop when it hits
that first column that has the renderer.

the code for example -
columns:[
{
header:'Score ID',
text: 'id',
dataIndex:'id', flex: 1,
renderer: function(value, meta, rec) {
console.log(value);
console.log(rec);
console.log(rec.phantom);
return rec.phantom ? null : value;
}
},

Any thoughts?

I'm using the latest version from
https://github.com/loiane/extjs4-ux-gridprinter

(https://github.com/loiane/extjs4-ux-gridprinter)

TexasSteve99
16 Sep 2014, 6:58 AM
I've run the examples on ExtJS 5.0.1 without any issues. What I need is working example to test against as my renderers (and the examples renderers) are called without issue. In the example.html, I did have to change

renderer: 'usMoney'

to

renderer: Ext.util.Format.usMoney

I have been having some issues merging changes back into Loiane's repository. I've attached the version of the Printer.js with my latest changes. Try that. If it still doesn't work, I'll need an example to test against.

Steve Ervin

mazhar.shaikh
29 Oct 2014, 5:52 PM
Steve,

Your changes are working. I have tried using the attached printer.js on Extjs 5 application and before it was throwing a NULL exception on
grid.store.getGroups(). I think your changes in that part are legit and working.

Thanks
Maz