Print function

Page: 1

Author Post
Member
Registered: Nov 2008
Posts: 28
Sir:

First, the print function works as described, i.e., the contents of the floatbox window are successfully printed.

However, I am displaying a list of names and addresses in two columns (read from a database and displayed on an asp page). Since this list may be long I set the floatbox to a specific width & height but allowed it to scroll. Works great so far.

When I choose to print, only the names and addresses visible in the floatbox window are printed ... not the entire table of data.

Is there any way that the print will/can print the entire table even if it is over multiple pages?

Thanks in advance for any help you may offer.

Fred
Administrator
Registered: Aug 2008
Posts: 3382
I'm not sure why you are getting that behaviour. I added the print button to the google news link on my demo page. It's got scrollable content and seems to print the whole thing just fine. Perhaps if I can see your page in action I can be more helpful.
Member
Registered: Nov 2008
Posts: 28
While, I guess I got the described behavior because I didn't look at the demo close enough .... when I used height:max everything appeared to work just fine.

I apologise for my lax reading ... but that you again for your prompt response.

Fred
Administrator
Registered: Aug 2008
Posts: 3382
No, that doesn't make sense. Print is not dependent on the floatbox height in any way. And setting height to max is no different than assigning a particular pixel value - it just pulls that pixel value by measuring the viewable screen area.

It sounds like it's working ok for you now, and I'm glad for that. But when I get a chance I'll play around some more and see if I can reproduce your original problem. So far, I haven't been able to.

The google news link on my test demo page at http://test.randomous.com/tools/floatbox/demo.php now has a set height and scrolled content, and it prints ok.
« Last edit by admin on Sun Dec 21, 2008 5:21 am. »
SJP
Guest
Hi Admin,

I am having a similar problem.

On your test page using Firefox, Google news prints only what is visible. In the courthouse example, when I click print a new window pops up for printing.

With IE the courthouse works the same a FF.
The Google example causes a new window to popup and it quickly disappears.
Administrator
Registered: Aug 2008
Posts: 3382
Thanks for reporting this.

I'm now just back (and jet-lagged) from two months of travel and so again have better facilities for testing and debugging than I did on the road.

I've reproduced and can confirm the behaviour you report. And I understand what's causing it. Currently, when iframed content is printed, the iframe is rendered in the new browser instance as a page that contains nothing but that single iframe. The page is printed with that iframe displayed only to its set dimensions. The proper way for floatbox to print iframe content is to print the iframe source page itself.

This will be fixed in the next version, probably to be released in the second half of February (but possibly not until March). I may be able to post a patch to the current version here in the next few days to immediately solve your problem if you need it.
SJP
Guest
Thanks Admin.

If you would like to post the patch that would be fine but only if it will not inconvenience you. I am currently using a new window to display some text and I can continue to do that.

If it helps any, I can get the Google example to print correctly in IE by right clicking and selecting print. With FF right clicking and selecting ?This Frame? and ?Print Frame? makes it print correctly.
Administrator
Registered: Aug 2008
Posts: 3382
Right-clicking is not always a good substitute. For iframes, it prints the whole base page in Opera and for some reason, print frame is greyed out in Chrome. But where the print function is really needed is to print div content such as floatboxed ajax or an inline div.

It would be great if you could test the following changes for me. It should print everything fine now with one exception. You can't print iframe content that comes from a different domain. This is because browsers block cross-domain scripting and error out if it is attempted. If you want to test iframe printing with the new routine on my demo page, use the "Nested (Stacked) Floatbox Content" example as it is a same-domain iframe.

There are three changes to make to the v3.24 floatbox.js file.
1. Add the bolded line between the two unbolded lines (line 249):
};
this.base = location.protocol + '//' + location.host;
var match = /\bautoStart=(.+?)(?:&|$)/i.exec(location.search);

2. Change (line 1270 or 1271) from
if (item.revOptions.showPrint) {
to
if (item.revOptions.showPrint && !(item.type === 'iframe' && /https?:\/\/\w/i.test(item.href) && item.href.indexOf(this.base) !== 0)) {

3. Replace the entire printContents function (line 2354 or 2355) with:
printContents: function(el, style) {
if (el && el.offsetWidth) { // existing element passed
var options = 'width=' + el.offsetWidth + ', height=' + el.offsetHeight;
} else { // use floatbox content if no element specified
el = fb.lastChild.fbContent;
var pos = fb.lastChild.pos.fbMainDiv,
options = 'width=' + pos.width + ', height=' + pos.height;
}
// create a new browser instance
var isIframe = el.tagName.toLowerCase() === 'iframe',
win = window.open((isIframe ? el.src : ''), '', options + ', scrollbars=' + (isIframe ? 1 : 0)),
doc = win && win.document;
if (!doc) { // was it blocked?
alert('Popup windows are being blocked by your browser.\nUnable to print.');
return false;
}
// write content if we're not printing an iframe's src
if (!isIframe) {
// optional passed style can be a css file path or a string of style definitions
if (/\.css$/i.test(style)) {
style = '<link rel="stylesheet" type="text/css" href="' + style + '" />';
} else {
style = '<style type="text/css"> html,body{border:0;margin:0;padding:0;}' + (style || '') + '</style>';
}
// put content into a div so we can read it with innerHTML for browsers that don't support outerHTML
var div = document.createElement('div');
div.appendChild(el.cloneNode(true));
doc.open('text/html');
doc.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"' +
' "http://www.w3.org/TR/html4/loose.dtd"><html><head>' +
style + '</head><body><div>' + div.innerHTML + '</div></body></html>');
doc.close();
}
// timeout to give the new window a chance to render
win.setTimeout(function() { win.print(); win.close(); }, 500);
return true;
}, // end printContents


Let me know if you encounter any problems.
...Cheers
SJP
Guest
"Nested (Stacked) Floatbox Content" in FF prints but it takes 3 pages. 1st page prints up to ?Be sure to play with the Options Form.? Page 2 prints up to ?Image map example? and table above it has gray background instead of white. Page 3 shows last table. Background is gray instead of white. Blue line is above the table, copyright is below table. With IE same as before a new window to popup and it quickly disappears.

The courthouse example is still the same. A new window pops up for printing in both browsers.

Google news example is missing print link in both browsers.

I made the changes on my script. The link is to a local html file that contain just text. The print link is missing in IE and FF.
Administrator
Registered: Aug 2008
Posts: 3382
Thanks for the testing assistance.
Quote
"Nested (Stacked) Floatbox Content" in FF prints but it takes 3 pages. 1st page prints up to ?Be sure to play with the Options Form.? Page 2 prints up to ?Image map example? and table above it has gray background instead of white. Page 3 shows last table. Background is gray instead of white. Blue line is above the table, copyright is below table.

That's standard browser print behaviour. Browser's will layout that page differently on account of the differing width between the browser window and the paper size. Browser's also make their own choices about what to print in terms of backgrounds That sample page was never intended to be a print sample. To get proper print layout, you would want to apply some print-specific css styles to the page.

Quote
With IE same as before a new window to popup and it quickly disappears.

This turns out to be a timing issue. If the popup page is not fully rendered before the print command is executed, IE just ignore the print command and goes straight to the close command after it. I've tried to scriptomagically detect when the page is ready, but can't find a way to do this. Trying to tap in to window.onload or body.onload has been unsuccessful. So instead, for iframe content I've increased the delay to 2.5 seconds. This works in all my tests, but no doubt there will be the occasional instance when the page is not ready in this amount of time. Imperfect for sure, but the best I can do, at least for now.

Quote
Google news example is missing print link in both browsers.

Good. That's intended. You can't print that page from script because of cross-domain script blocking, so there's no point displaying a print link that cannot work.

Quote
I made the changes on my script. The link is to a local html file that contain just text. The print link is missing in IE and FF.

As per the above comment, the local html is being detected as a cross-site source (different protocol or different server name) and so printing cannot be scripted.

I would recommend loading your local html file as ajax content rather than iframe content. That is, strip the doctype, html, head and body declarations out and use type:ajax in the rev options. It will probably be a little more responsive, and the print function will not encounter the problems associated with printing iframe content.
SJP
Guest
Quote
So instead, for iframe content I've increased the delay to 2.5 seconds.
The courthouse example is working now. Do I need to change something in the script for 2.5 seconds?
Quote
strip the doctype, html, head and body declarations out and use type:ajax in the rev options.
I tried that. A plain text file loads but html file throws errors. Expects <br> where </font> is. Has difficulty reading tables.
Administrator
Registered: Aug 2008
Posts: 3382
Sounds like you've got some badly structured html either on your base page or in the ajax source. Loading a floatbox through ajax will neither fix nor break the html.

I've got a better print function. I think it's complete and stable, but I still have a little more testing to do with it. I've succeeded in hooking window.onload so there's no more timing issues, and it's now pulling in css styles from the original doc (which doesn't mean things will always look the same as the original doc - print layout is often different than screen layout).

Each of the 3 changes/patches described in my post on Friday needs to be updated.

#1 becomes:
this.base = (location.protocol + '//' + location.host).toLowerCase();

#2 - The entire if... block that follows the if statement previously patched should be replaced with:
	if (item.revOptions.showPrint && !(item.type === 'iframe' && /https?:\/\/\w/i.test(item.href) && item.href.toLowerCase().indexOf(this.base) !== 0)) {
var css = item.revOptions.printCSS || '';
str = '<a href="' + this.encodeHTML(item.href) +
'" onclick="fb.printContents(\'' + css + '\'); if (window.event) event.returnValue = false; return false;"><b>' +
(item.revOptions.printText || this.strings.printText) + '</b></a>';
if (this.setInnerHTML(this.fbPrintLink, str)) infoPanel.display = infoDiv.display = printLink.display = '';
}


#3 - The new replacement printContents function follows, and you also need to add the companion getOuterHTML function just below it.

printContents: function(style) {
var el = fb.lastChild.fbContent,
styles = '<style type="text/css">html,body{border:0;margin:0;padding:0;}</style>',
pos = fb.lastChild.pos.fbMainDiv,
pwin = window.open('', '', 'width=' + pos.width + ',height=' + pos.height),
pdoc = pwin && pwin.document;
if (!pdoc) {
alert('Popup windows are being blocked by your browser.\nUnable to print.');
return false;
}
if (el.tagName.toLowerCase() === 'iframe') {
var idoc = el.contentDocument || el.contentWindow;
idoc = idoc.document || idoc;
var ibod = idoc.body || idoc.getElementsByTagName('body')[0],
html = '<div style="' + (ibod.getAttribute('style') || '') + '">' + ibod.innerHTML + '</div>';
for (var tag in {link:'', style:''} ) {
var els = idoc.getElementsByTagName(tag);
for (var i = 0, len = els.length; i < len; i++) {
styles += this.getOuterHTML(els[i]);
}
}
} else {
var html = '<div>' + this.getOuterHTML(el) + '</div>';
}
if (/\.css$/i.test(style)) {
styles += '<link rel="stylesheet" type="text/css" href="' + style + '" />';
} else if (style) {
styles += '<style type="text/css">' + (style || '') + '</style>';
}
pdoc.open('text/html');
pdoc.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">' +
'<html><head>' + styles + '<script type="text/javascript">' +
'window.onload = function() { setTimeout(function() { document.body.focus(); print(); close(); }, 200) };' +
'</script></head><body>' + html + '</body></html>');
pdoc.close();
},
getOuterHTML: function(el) {
if (el.outerHTML) return el.outerHTML;
var div = document.createElement('div');
div.appendChild(el.cloneNode(true));
return div.innerHTML;
},


I've got print enabled on the courthouse, the contact form, and the Nested Floatbox Content on the test demo page - http://test.randomous.com/tools/floatbox/demo.php

If you find any grief with this new routine, please let me know. And thanks again for your help in sorting it out.
SJP
Guest
Quote
And thanks again for your help in sorting it out.

Thank you, I am glad to help with the best lightbox on the Internet.

I have not found any problems on your test page other than the previously mentioned 3 pages to print ?Nested (Stacked) Floatbox Content? example.

I made the script changes and print function in iframe is now working perfectly with an all text html file on the same server. However, images do not print. That seems strange since images in your ?Nested (Stacked) Floatbox Content? example do print.

Page: 1