Good day. I am developing a Web Application and there's a part where I print the form on button click. To achieve this, I overrode the definition of my Form Panel so that I can call form.print()
anywhere in my code when I need to. Here is how I overrode my form:
Ext.define('my_app_name.override.form.Panel', {
override: 'Ext.form.Panel',
print: function(pnl) {
if (!pnl) {
pnl = this;
}
// instantiate hidden iframe
var iFrameId = "printerFrame";
var printFrame = Ext.get(iFrameId);
if (printFrame === null) {
printFrame = Ext.getBody().appendChild({
id: iFrameId,
tag: 'iframe',
cls: 'x-hidden',
style: {
display: "none"
}
});
}
var cw = printFrame.dom.contentWindow;
// instantiate application stylesheets in the hidden iframe
var stylesheets = "";
for (var i = 0; i < document.styleSheets.length; i++) {
stylesheets += Ext.String.format('<link rel="stylesheet" href="{0}" />', document.styleSheets[i].href);
}
// various style overrides
stylesheets += ''.concat(
"<style>",
".x-panel-body {overflow: visible !important;}",
// experimental - page break after embedded panels
// .x-panel {page-break-after: always; margin-top: 10px}",
"</style>"
);
// get the contents of the panel and remove hardcoded overflow properties
var markup = pnl.getEl().dom.innerHTML;
while (markup.indexOf('overflow: auto;') >= 0) {
markup = markup.replace('overflow: auto;', '');
}
var str = Ext.String.format('<html><head>{0}</head><body>{1}</body></html>',stylesheets,markup);
// output to the iframe
cw.document.open();
cw.document.write(str);
cw.document.close();
// remove style attrib that has hardcoded height property
cw.document.getElementsByTagName('DIV')[0].removeAttribute('style');
// print the iframe
cw.print();
// destroy the iframe
Ext.fly(iFrameId).destroy();
}
});
Then on a click of a button in my Web App, I do something like:
var form = Ext.getCmp('formIDHere');
form.print();
However, this code is rather inconsistent at times. There are times that I can print the form no problem and there are times that it gives the "Print Preview Error" message. I can't replicate the issue consistently and the logs aren't showing anything so I'm in the dark.
What I've noticed however, is that when I save my project (I'm using Sencha Architect), preview it (or refresh the current window where I'm previewing my Web App), stay with the web app all throughout the process (meaning I don't shift tabs or windows), hit the print button, the print preview appears and I don't have problems with it.
So far I haven't tested in other Web Browsers. Any ideas anyone? I'll be really thankful for anyone who can point out what I'm doing wrong. Thanks in advance.
Sorry I forgot to update this. Thanks to whoever upvoted my question.
The concept is simple. Since ExtJS4 is asynchronous, I placed my code in "blocks" and then I delayed my calls to those functions to ensure that they finish constructing what they need to construct before moving on to the next part.
print: function(pnl) {
if (!pnl) {
pnl = this;
}
// instantiate hidden iframe
var iFrameId = "printerFrame";
var printFrame = Ext.get(iFrameId);
if (printFrame === null) {
printFrame = Ext.getBody().appendChild({
id: iFrameId,
tag: 'iframe',
cls: 'x-hidden',
style: {
display: "none"
}
});
}
var cw = printFrame.dom.contentWindow;
var stylesheets = "";
var markup;
// instantiate application stylesheets in the hidden iframe
var printTask = new Ext.util.DelayedTask(function(){
// print the iframe
cw.print();
// destroy the iframe
Ext.fly(iFrameId).destroy();
});
var strTask = new Ext.util.DelayedTask(function(){
var str = Ext.String.format('<html><head>{0}</head><body>{1}</body></html>',stylesheets,markup);
// output to the iframe
cw.document.open();
cw.document.write(str);
cw.document.close();
// remove style attrib that has hardcoded height property
// cw.document.getElementsByTagName('DIV')[0].removeAttribute('style');
printTask.delay(500);
});
var markUpTask = new Ext.util.DelayedTask(function(){
// get the contents of the panel and remove hardcoded overflow properties
markup = pnl.getEl().dom.innerHTML;
while (markup.indexOf('overflow: auto;') >= 0) {
markup = markup.replace('overflow: auto;', '');
}
while (markup.indexOf('background: rgb(255, 192, 203) !important;') >= 0) {
markup = markup.replace('background: rgb(255, 192, 203) !important;', 'background: pink !important;');
}
strTask.delay(500);
});
var styleSheetConcatTask = new Ext.util.DelayedTask(function(){
// various style overrides
stylesheets += ''.concat(
"<style>",
".x-panel-body {overflow: visible !important;}",
// experimental - page break after embedded panels
// .x-panel {page-break-after: always; margin-top: 10px}",
"</style>"
);
markUpTask.delay(500);
});
var styleSheetCreateTask = new Ext.util.DelayedTask(function(){
for (var i = 0; i < document.styleSheets.length; i++) {
stylesheets += Ext.String.format('<link rel="stylesheet" href="{0}" />', document.styleSheets[i].href);
}
styleSheetConcatTask.delay(500);
});
styleSheetCreateTask.delay(500);
}